欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

浅析Java序列化和反序列化

来源:本站整理 作者:佚名 时间:2019-01-15 TAG: 我要投稿
        dout.writeInt(mods);
        dout.writeUTF(sig.signature.replace('/', '.'));
    }
}
写入非私有方法,包括方法名、方法访问权限标识和方法签名,按方法名和方法签名排序
MemberSignature[] methSigs = new MemberSignature[methods.length];
for (int i = 0; i  methods.length; i++) {
    methSigs[i] = new MemberSignature(methods[i]);
}
Arrays.sort(methSigs, new ComparatorMemberSignature>() {
    public int compare(MemberSignature ms1, MemberSignature ms2) {
        int comp = ms1.name.compareTo(ms2.name);
        if (comp == 0) {
            comp = ms1.signature.compareTo(ms2.signature);
        }
        return comp;
    }
});
for (int i = 0; i  methSigs.length; i++) {
    MemberSignature sig = methSigs[i];
    int mods = sig.member.getModifiers() &
        (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
            Modifier.STATIC | Modifier.FINAL |
            Modifier.SYNCHRONIZED | Modifier.NATIVE |
            Modifier.ABSTRACT | Modifier.STRICT);
    if ((mods & Modifier.PRIVATE) == 0) {
        dout.writeUTF(sig.name);
        dout.writeInt(mods);
        dout.writeUTF(sig.signature.replace('/', '.'));
    }
}
以上就是SUID中包含的类的所有信息,得到的二进制串如下:
00 11 53 65 72 69 61 6c  69 7a 61 74 69 6f 6e 44    ..Serial izationD
65 6d 6f 00 00 00 01 00  14 6a 61 76 61 2e 69 6f    emo..... .java.io
2e 53 65 72 69 61 6c 69  7a 61 62 6c 65 00 08 69    .Seriali zable..i
6e 74 46 69 65 6c 64 00  00 00 02 00 01 49 00 0b    ntField. .....I..
73 74 72 69 6e 67 46 69  65 6c 64 00 00 00 02 00    stringFi eld.....
12 4c 6a 61 76 61 2f 6c  61 6e 67 2f 53 74 72 69    .Ljava/l ang/Stri
6e 67 3b 00 06 3c 69 6e  69 74 3e 00 00 00 01 00    ng;..in it>.....
16 28 4c 6a 61 76 61 2e  6c 61 6e 67 2e 53 74 72    .(Ljava. lang.Str
69 6e 67 3b 49 29 56 00  04 6d 61 69 6e 00 00 00    ing;I)V. .main...
09 00 16 28 5b 4c 6a 61  76 61 2e 6c 61 6e 67 2e    ...([Lja va.lang.
53 74 72 69 6e 67 3b 29  56                         String;)V
最后,将二进制数据通过SHA1算法得到摘要,取前8位按BigEndian的字节顺序转换成长整型:
long hash = 0;
for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
    hash = (hash  8) | (hashBytes[i] & 0xFF);
}
返回的hash就是最终的SUID了。
由此可知,当父类或非原始数据类型字段的类内部发生变更时,并不会影响当前类的SUID值,再结合之前的内容我们还可以引申出两个结论:
若当前类自定义了readObject(),在反序列化时会正常执行readObject()中所有ObjectInputStream.defaultReadObject() (如果调用了的话) 之前的逻辑;否则在处理到变更对象时,仍会抛出InvalidClassException
由于序列化会对类的字段进行排序,并在反序列化时按顺序遍历处理,所以反序列化会正常处理字段名比变更对象类型字段『小』的其他字段
关于writeReplace()和readResolve()
在前面的执行流程分析中,为了突出主要逻辑,我们主观的忽略了一些内容,其中就包括了序列化的invokeWriteReplace()和反序列化的invokeReadResolve()。
现在就来看看它们分别有什么作用:
writeReplace()
返回一个对象,该对象为实际被序列化的对象,在原对象序列化之前被调用,替换原对象成为待序列化对象
readResolve()
返回一个对象,该对象为实际反序列化的结果对象,在原对象反序列化之后被调用,不影响原对象的反序列化过程,仅替换结果
再从具体示例来体会一下:
public class SerializationReplacementClass implements Serializable {
    protected String replacementField;
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
    }
    private Object readResolve() {
        return new SerializationReplacementClass("resolve");
    }
    private SerializationReplacementClass(String s) {

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载