关于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的总结:
-
编译时编织(Compile-Time Weaving)
在编译阶段将切面逻辑织入目标类,适用于源码可修改的场景。但若目标类是第三方 JAR(无源码),需通过 编译后编织(Post-Compile Weaving) 直接修改其字节码。 -
加载时编织(Load-Time Weaving, LTW)
在类加载时动态修改字节码,无需源码或重新编译,适合第三方 JAR。需通过-javaagent参数引入aspectjweaver.jar并配置aop.xml
所以想要hook第三方jar包的方法只能使用编译后编织或者加载时编织.
回头看看具体实践看看
另外我发现一个百分百可以hook的方式:https://github.com/rdbo/jnihook

浙公网安备 33010602011771号