Java内功--动态代理

  • A+
所属分类:安全开发

     动态代理在代码审计中很重要, 很多地方都会用到 。如果想做代码审计 必须要掌握 必须要掌握


动态代理

    代理类在程序运行时创建的代理方式被代理成为动态代理。我们上面静态代理的例子中,代理类(studentProxy)是自己定义好的,在程序运行之前就已经编译完成。然而动态代理,代理类并不是在Java代码中定义的,而是在运行时根据我们在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具体的目标对象

Java内功--动态代理

2.Method method要执行的方法名, 也就是在Test.java里面调用的方法名

Java内功--动态代理

也就是在Test.java里面调用的方法名

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();      }}



执行结果

Java内功--动态代理


重点说三遍

动态代理的牛逼之处

1.静态代理只能代理执行指定的接口,比较有局限性,

2.动态代理解决了只能代理指定接口的限制.可以代理任何接口

动态代理的牛逼之处

1.静态代理只能代理执行指定的接口,比较有局限性,

2.动态代理解决了只能代理指定接口的限制.可以代理任何接口

动态代理的牛逼之处

1.静态代理只能代理执行指定的接口,比较有局限性,

2.动态代理解决了只能代理指定接口的限制.可以代理任何接口


内功修练完...下一期开始进一步分析漏洞


本文始发于微信公众号(安全帮Live):Java内功--动态代理

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: