AnnotationInvocationHandler的深度分析

cc链于jdk原生反序列化中常用AnnotationInvocationHandler做最后的包装,其优点如下。

一、其readobject中有setvalue方法当cc1使用TransformedMap包裹时,setvalue后会调用TransformedMap中的checksetvalue方法进而调用valueTransformer.transform(value)达到命令执行。

image.png

![image.png](/imgs/AnnotationInvocationHandler的深度分析/image 1.png)

![image.png](/imgs/AnnotationInvocationHandler的深度分析/image 2.png)

二、AnnotationInvocationHandler是一个代理类,其invoke方法中存在equalsImplget方法。使用AnnotationInvocationHandler包裹自身代理类后(如代理lazymap的map接口)则执行setvalue时必然会走到invoke方法中调用到get的危险方法如(lazymap.get)。7u21时会调用到equalsImpl。

![image.png](/imgs/AnnotationInvocationHandler的深度分析/image 3.png)

![image.png](/imgs/AnnotationInvocationHandler的深度分析/image 4.png)

![image.png](/imgs/AnnotationInvocationHandler的深度分析/image 5.png)

针对于动态代理在反序列化中的思考

动态代理需要的东西:

一个要被代理的接口

一个被代理的实体类(其实现了某个接口)

一个实现了InvocationHandler代理类

最后使用Proxy.newProxyInstance实现动态代理

代理类代理的是接口,所以其构造方法一般是接受的是一个接口。

当追踪到反序列链条最终存在危险方法a.b时(如lazymap.get),要代理ab方法时该方法必须是从一个接口如c实现而来,进而则可寻找满足如下条件的代理类。该代理类的构造方法接受a实现的接口c且invoke中调用了方法b

如下图所示:

image.png