关于java hook的一点点思考

今天有同事问我怎么hook别人写好的方法,比如先自己打印参数,然后在执行它本身的方法。  这个方法并且已经以jar包的形式存在。 我当时的第一反应是使用反射或者代理。

先看看这个需求, 本质上是hook原方法,然后等待调用(从行为上被动)

先分析反射是否可行:

仔细思考就会发现反射无法实现这种, 反射可以获取任何属性和主动调用方法, 反射调用某某解密方法有用。(从行为上主动)

反射方式适合用在破解数据领域

 

在看看代理是否可行, 直接看demo吧:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ReflectionHookDemo {

    // 定义接口(假设目标类实现了此接口)
    public interface TargetInterface {
        void targetMethod(String arg);
    }

    // 原始实现类(第三方JAR中的类)
    public static class TargetClass implements TargetInterface {
        public void targetMethod(String arg) {
            System.out.println("原始方法执行,参数: " + arg);
        }
    }

    public static void main(String[] args) {
        // 1. 创建原始对象
        TargetInterface original = new TargetClass();

        // 2. 创建代理对象
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
            TargetInterface.class.getClassLoader(),
            new Class[]{TargetInterface.class},
            new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // 前置逻辑:打印参数
                    System.out.println("方法调用前,参数: " + Arrays.toString(args));

                    // 调用原始方法
                    Object result = method.invoke(original, args);

                    // 后置逻辑(可选)
                    System.out.println("方法调用后");

                    return result;
                }
            }
        );

        // 3. 通过代理对象调用方法
        proxy.targetMethod("Hello");
    }
}

从这个逻辑中, 确实是hook了方法,但是进行了逻辑转移。 把原来hook方法的需求, 变成了怎么hook对象。   在自己的项目中弄了一个proxy对象, 但是第三方jar包并会不会使用proxy对象。

所以也是非常鸡肋。 (从行为上也是属于主动)

 

到这里难道要放弃了吗???

问一下deepseek吧

看到了一个新词: AspectJ, 面向切面编程

@Aspect
public class HookAspect {
    @Around("execution(* com.example.TargetClass.targetMethod(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before method");
        Object result = joinPoint.proceed(); // 执行原方法
        System.out.println("After method");
        return result;
    }
}

这个demo实际也是没什么软用, 因为实际测试我发现它只对源码有用, 对于第三方库jar包, 没有源码。

下面2个点是deepkseek的总结:

    1. 编译时编织(Compile-Time Weaving)
      在编译阶段将切面逻辑织入目标类,适用于源码可修改的场景。但若目标类是第三方 JAR(无源码),需通过 编译后编织(Post-Compile Weaving) 直接修改其字节码

    2. 加载时编织(Load-Time Weaving, LTW)
      在类加载时动态修改字节码,无需源码或重新编译,适合第三方 JAR。需通过 -javaagent 参数引入 aspectjweaver.jar 并配置 aop.xml

所以想要hook第三方jar包的方法只能使用编译后编织或者加载时编织.  

回头看看具体实践看看

 

另外我发现一个百分百可以hook的方式:https://github.com/rdbo/jnihook

 

posted @ 2025-04-23 11:06  浪浪辛  阅读(49)  评论(0)    收藏  举报