Java序列化:readObjects()超出readObject()?

Fox*_*BOA 6 java obfuscation serialization objectinputstream deserialization

ObjectInputStream.readFields()仅在private void readObject(ObjectInputStream)方法内有资格.

public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException {
  SerialCallbackContext ctx = curContext;
  if (ctx == null) {
    throw new NotActiveException("not in call to readObject");
  }
...
Run Code Online (Sandbox Code Playgroud)

当我无法使用默认序列化来读取对象(即ObjectInputStream.defaultReadObject())并且不希望readObject()在我的所有类中实现方法时,我处于这种情况.在理想情况下,我希望有一个 ownDefaultReadObject()方法可以从序列化字段构建新对象(例如通过反射).

有任何想法吗?

如果有人想知道更多.我的一些类中的字段名称被重命名(例如通过混淆器)到a,b,c等.这些类使用默认的Java序列化使用重命名的字段进行序列化.我需要将它们反序列化为原始类(我知道每个类的字段名称对; a => fieldName,b => age,c => gender等).

Tom*_*ine 1

要重命名对象流中的字段,您需要重写的方法是ObjectInputStream.readClassDescriptor返回ObjectStreamClass.

实例ObjectStreamClass通过接口的大量不同子集来履行两种不同角色之一。为避免疑义,不应复制此设计选择。

  • 描述当前 JVM 实例中运行的可序列化类的字段。通过查找这些实例ObjectStreamClass.lookup
  • 描述特定序列化流中表示的可序列化类的字段。这些实例由 的实现返回ObjectInputStream.readClassDescriptor

在您的覆盖调用中super.readClassDescriptor。这将从流中读取数据。如果是您感兴趣的类,请将流中的值替换为具有新字段名称的值。

如何创建自己的ObjectStreamClass?将您感兴趣的类的虚拟实例写入ObjectOutputStream. 您可以将其作为构建的一部分来执行,只需保留二进制数据。用另一个重写的ObjectInputStream方法来读取readClassDescriptor以存储描述符。

ObjectInputStream.defaultReadObject/readFields在外部(或类似)之外没有任何意义readObject,因为它们依赖于当前的反序列化对象而不是参数。还有其他限制可以防止其他代码调用defaultReadObject重写必须保持不变、复制验证、安全检查或类似的字段。