动态代理在代码审计中很重要, 很多地方都会用到 。如果想做代码审计 必须要掌握 必须要掌握
动态代理
代理类在程序运行时创建的代理方式被代理成为动态代理。我们上面静态代理的例子中,代理类(studentProxy)是自己定义好的,在程序运行之前就已经编译完成。然而动态代理,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。
核心代码:
InvocationHandler 定义代理对象调用那些方法,以及参数,和实现了那些接口
Proxy.newProxyInstance 创建代理类对象
测试代码:
接口Mappr1.class
package moves;
public interface Mappr1 {
public void jdbc0(String c);
public void jdbc1(String c);
}
class UserMappr implements Mappr1{
public void jdbc0(String c)
{ System.out.println("--Secbang--user--执行核心业务代码-"+c+"---");}
public void jdbc1(String c) {
{ System.out.println("--Secbang111--user--执行核心业务代码-"+c+"---");}
}
}
class AdminMappr implements Mappr1{
public void jdbc0(String c)
{ System.out.println("--Secbang--admin--执行核心业务代码-"+c+"---"); }
public void jdbc1(String c) {
{ System.out.println("--Secbang1111--user--执行核心业务代码-"+c+"---");}
}
}
接口 Mp.class
package moves;
public interface Mp {
public void say();
}
class Mappr2 implements Mp{
public void say()
{ System.out.println("--Secbang--Mappr2--执行核心业务代码----");}
}
代理类InvoctionHandle.java 需要实现InvocationHandler接口,并重写Invoke方法
package moves;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InvoctionHandle implements InvocationHandler {
//接受目标对象目标对象 OBject
private Object target;
//构造器
public InvoctionHandle(Object target) {
this.target = target;
}
/*
* Invoke方法用于增强处理
* Object arg0 动态生成的代理类实例,生成后保存在内存里面
* Method method 当前目标对象正在执行的方法
* arg2 当前目标对象正在执行的方法中的参数信息
*/
public Object invoke(Object arg0, Method method, Object[] arg2)
throws Throwable {
System.out.println("---获取链接----");
method.invoke(target, arg2);
System.out.println("---关闭链接----");
return null;
} }
动态代理的牛逼之处
1.静态代理只能代理执行指定的接口,比较有局限性,
2.动态代理解决了只能代理指定接口的限制.可以代理任何接口
静态代理只能代理Mappr1接口
public StaticProxy(Mappr1 um) {
this.um = um;
}
动态代理可以代理任意的接口 Object包含所有接口类型
public InvoctionHandle(Object target) {
this.target = target;
}
Proxy.newProxyInstance作用 需要指定三个参数
Proxy.newProxyInstance 方法动态生成代理类以及代理对象。然后放到内存里
这个方法三个参数的的作用
1.usmx.getClass().getClassLoader() 类加载器
2.usmx.getClass().getInterfaces() 返回目标对象实现了那些接口
3.mi为具体的InvocationHandle目标对象
Invoke方法
这个方法三个参数的的作用
1.Object arg0具体的目标对象
2.Method method要执行的方法名, 也就是在Test.java里面调用的方法名
也就是在Test.java里面调用的方法名
3.arg2 当前目标对象正在执行的方法中的参数信息
测试执行 : (静态代理只能代理实现了特定接口类)
测试使用动态代理“代理”实现了不同的接口类 AdminMappr类 Mappr2类
package moves;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
AdminMappr usm =new AdminMappr();//目标对象
//根据实例对象返回object对象,最后把obiect 重新new 返回InvocationHandler对象
InvocationHandler hd=new InvoctionHandle(usm); //真正干活的
Mappr1 umi = (Mappr1)Proxy.newProxyInstance(usm.getClass().getClassLoader(),usm.getClass().getInterfaces(),hd);
umi.jdbc1("hacker"); //此时调用class InvoctionHandle的invoke方法
Mappr2 usmx =new Mappr2(); //为实际干活的
InvocationHandler mi=new InvoctionHandle(usmx);
Mp mp=(Mp)Proxy.newProxyInstance(usmx.getClass().getClassLoader(),usmx.getClass().getInterfaces(),mi);
mp.say();
}
}
执行结果
重点说三遍
动态代理的牛逼之处
1.静态代理只能代理执行指定的接口,比较有局限性,
2.动态代理解决了只能代理指定接口的限制.可以代理任何接口
动态代理的牛逼之处
1.静态代理只能代理执行指定的接口,比较有局限性,
2.动态代理解决了只能代理指定接口的限制.可以代理任何接口
动态代理的牛逼之处
1.静态代理只能代理执行指定的接口,比较有局限性,
2.动态代理解决了只能代理指定接口的限制.可以代理任何接口
内功修练完...下一期开始进一步分析漏洞
本文始发于微信公众号(安全帮Live):Java内功--动态代理
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论