Java Hook简洁实用教程

一般来说,hook的应用场景就是修改或拦截某些系统类的方法及替换属性

直接上代码!

有一个接口IAction

public interface IAction {
    void eat(String food);
}

People类中有一个"name"属性,并实现了接口IAction

public class People implements IAction {
    private String name = "小明";

    @Override
    public void eat(String food) {
        System.out.println(name + "吃" + food);
    }
}

动态代理类,实现InvocationHandler接口,构造函数传入被代理的对象

public class DynamicProxyHandler implements InvocationHandler {
    private Object proxied;// 被代理的对象

    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 执行代理对象原来的方法之前,加入任何自己想要的动作
        System.out.println(" ==== 代理方法接收的参数是:"+args[0]);
        args[0] = "苹果";
        System.out.println(" ==== 改为:"+args[0]);
        // 执行代理对象原来的方法
        return method.invoke(proxied,args);
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println("-----正常操作-----");
        normal();

        System.out.println("\n-----hook代理-----");
        hookInterface();

        System.out.println("\n-----hook属性-----");
        hookAttr();
    }

    /**
     * 正常操作
     */
    public static void normal() {
        People people = new People();
        people.eat("梨子");
    }

    /**
     * hook方法
     */

    public static void hookInterface() {
        People people = new People();

        IAction iAction = (IAction) Proxy.newProxyInstance(
                IAction.class.getClassLoader(),
                new Class[]{IAction.class},
                new DynamicProxyHandler(people));

        iAction.eat("梨子"); // 虽然传递的是"梨子",但hook过程被修改了
    }

    /**
     * hook属性
     */
    public static void hookAttr(){
        try {
            System.out.println(" ==== hook属性,狸猫换太子,小明变小强");

            People people = new People();

            Field field = People.class.getDeclaredField("name");
            field.setAccessible(true);
            field.set(people, "小强");

            people.eat("梨子");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行Test输出:

-----正常操作-----
小明吃梨子

-----hook代理-----
 ==== 代理方法接收的参数是:梨子
 ==== 改为:苹果
小明吃苹果

-----hook属性-----
 ==== hook属性,狸猫换太子,小明变小强
小强吃梨子

Java Hook简洁实用教程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章