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

浅析Java序列化和反序列化

来源:本站整理 作者:佚名 时间:2019-01-15 TAG: 我要投稿
        );
    }
    return suid.longValue();
}
先顺带提一嘴,AccessController.doPrivileged()会忽略JRE配置的安全策略的检查,以特权的身份去执行PrivilegedAction接口中的run(),可以防止JDK底层在进行序列化和反序列化时可能出现的一些权限问题。这些内容与本文主题无关,不多作详细解释,感兴趣的同学可以去看看Java的Security包和其中的java.policy、java.security文件内容。
重点来了,计算SUID时,会先创建一个DataOutputStream对象,所有二进制数据写入其包装的ByteArrayOutputStream中:
写入类名 (UTF8)
dout.writeUTF(cl.getName());
写入类访问权限标识
int classMods = cl.getModifiers() &
    (Modifier.PUBLIC | Modifier.FINAL |
        Modifier.INTERFACE | Modifier.ABSTRACT);
Method[] methods = cl.getDeclaredMethods();
if ((classMods & Modifier.INTERFACE) != 0) {
    classMods = (methods.length > 0) ?
        (classMods | Modifier.ABSTRACT) :
        (classMods & ~Modifier.ABSTRACT);
}
dout.writeInt(classMods);
如果不是数组类型,写入实现接口的接口名,按接口名排序
if (!cl.isArray()) {
    Class[] interfaces = cl.getInterfaces();
    String[] ifaceNames = new String[interfaces.length];
    for (int i = 0; i  interfaces.length; i++) {
        ifaceNames[i] = interfaces[i].getName();
    }
    Arrays.sort(ifaceNames);
    for (int i = 0; i  ifaceNames.length; i++) {
        dout.writeUTF(ifaceNames[i]);
    }
}
写入非私有静态或瞬态字段信息数据,包括字段名、字段访问权限标识和字段签名,按字段名排序
Field[] fields = cl.getDeclaredFields();
MemberSignature[] fieldSigs = new MemberSignature[fields.length];
for (int i = 0; i  fields.length; i++) {
    fieldSigs[i] = new MemberSignature(fields[i]);
}
Arrays.sort(fieldSigs, new ComparatorMemberSignature>() {
    public int compare(MemberSignature ms1, MemberSignature ms2) {
        return ms1.name.compareTo(ms2.name);
    }
});
for (int i = 0; i  fieldSigs.length; i++) {
    MemberSignature sig = fieldSigs[i];
    int mods = sig.member.getModifiers() &
        (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
            Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
            Modifier.TRANSIENT);
    if (((mods & Modifier.PRIVATE) == 0) ||
        ((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0))
    {
        dout.writeUTF(sig.name);
        dout.writeInt(mods);
        dout.writeUTF(sig.signature);
    }
}
如果存在类初始化器 (不是类实例化的构造方法,感兴趣的同学可以去看看JVM规范中的相关内容) ,写入固定的初始化器信息数据
if (hasStaticInitializer(cl)) {
    dout.writeUTF("");
    dout.writeInt(Modifier.STATIC);
    dout.writeUTF("()V");
}
写入非私有构造方法信息数据,包括方法名 (固定为) 、方法访问权限标识和方法签名 (分隔符/会替换成.的包名形式) ,按方法签名排序
Constructor[] cons = cl.getDeclaredConstructors();
MemberSignature[] consSigs = new MemberSignature[cons.length];
for (int i = 0; i  cons.length; i++) {
    consSigs[i] = new MemberSignature(cons[i]);
}
Arrays.sort(consSigs, new ComparatorMemberSignature>() {
    public int compare(MemberSignature ms1, MemberSignature ms2) {
        return ms1.signature.compareTo(ms2.signature);
    }
});
for (int i = 0; i  consSigs.length; i++) {
    MemberSignature sig = consSigs[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("");

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

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