前言
今天看到一篇文章,写关于JAVA Agent相关的资料,里面提到了 Java Agent 的两种实现方法:
-
实现 premain 方法,在 JVM 启动前加载
-
实现 agentmain 方法,在 JVM 启动后 attach 加载
因为最近流行破解 CobaltStrike 不再直接使用反编译打包源码了,而是使用JAVA Agent进行提前字节码修改。并且文章中也提到了 javassist 工具,我之前也用过javassist工具进行破解过Charles,因此抱着学习和复习的态度来复现下本文提到的技术点。
JAVA Agent两种方法复现
Java Agent 简单说就是一种可以修改 jar 字节码的技术,我们来复现下上述提到的两种方法。
premain
通过实现 premain方法 ,并在启动jar时添加 -javaagent:agent.jar 即可进行字节码修改。首先我们创建一个正常输出、测试用的 JAVA 程序, hello.jar :
package com.test; public class Hello { public static void main(String[] args) { hello(); } public static void hello(){ for (int i = 0; i < 1000; i++) { System.out.println("hello"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
生成jar包:
Build -> Build Artifacts -> Build
正常运行jar包得到如下输出:
java -jar hello.jar
接下来编写一个实现premain方法的JAVA程序:
package com.test; import java.lang.instrument.Instrumentation; public class premainagent { public static void premain(String args, Instrumentation inst) throws Exception{ for (int i = 0; i < 10; i++) { System.out.println("hello I`m premain agent!!!"); } } }
并在 MANIFEST.MF 添加一行:
Premain-Class: com.test.premainagent
生成jar包并加载执行:
java -javaagent:premainagent.jar -jar hello.jar
可以看到,成功的在 hello.jar 本身结果输出前输出了 premain 方法的内容:
前面也提到现在破解 CobaltStrike 流行用 JAVA Agent 技术,我们看下破解工具的源码,能发现确实用的也是 premain 方法进行的破解: