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簡潔實用教程

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