实现一个javaagent需要几步?

最近在学习IAST技术,IAST的核心其实就是插桩,在java语言下,用到的技术就是javaagent,由于之前没有接触过javaaent,正好整理一下。在介绍javaagent之前,我想有必要向大家介绍一下JVMTI,因为javaagent是基于这个技术实现的JVMTIJVMTI(JVM Tool Interface)是 Java 虚拟机所提供的 native 编程接口,JVMTI可以用来开发并监控JVM,可以查看JVM的内部状态,并控制JVM应用程序的执行。JVMTI只是一套接口,我们.
摘要由CSDN通过智能技术生成

 最近在学习IAST技术,IAST的核心其实就是插桩,在java语言下,用到的技术就是javaagent,由于之前没有接触过javaaent,正好整理一下。

在介绍javaagent之前,我想有必要向大家介绍一下JVMTI,因为javaagent是基于这个技术实现的

JVMTI

JVMTI(JVM Tool Interface)是 Java 虚拟机所提供的 native 编程接口,JVMTI可以用来开发并监控JVM,可以查看JVM的内部状态,并控制JVM应用程序的执行。

JVMTI只是一套接口,我们要开发JVM工具就需要写一个Agent程序来使用这些接口。Agent程序其实就是一个C/C++语言编写的动态链接库。

注:这里提到的agent程序和javaagent不是同一概念

我们通过JVMTI开发好agent程序后,把程序编译成动态链接库,之后可以在jvm启动时指定加载运行该agent。

-agentlib:<agent-lib-name>=<options>

之后JVM启动后该agent程序就会开始工作。

而接下来要提到的Instrumention机制,也是通过实现了一个JVMTI的agent来完成的,这个agent的实现代码在libinstrument.so里(在BSD系统中叫做libinstrument.dylib),由于libinstrument.so是java内置的,所以不需要我们手动通过 -agentlib 参数指定就可以使用它。

这个动态链接库可以在{JAVA_HOME}/jre/lib 下找到ÿ

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
宿主应用不能直接调用Java Agent中的静态方法,因为Java Agent是在独立的Java虚拟机中运行的,与宿主应用是独立的进程。Java Agent和宿主应用之间是通过Java Instrumentation API进行通信的。 在Java Agent中,可以通过premain方法获取到Instrumentation实例,并保存在静态变量中。然后,在宿主应用中,可以通过调用Java Agent提供的公共接口来获取Java Agent中的静态变量或执行Java Agent中的方法。 以下是一个示例: Java Agent中的公共接口: ``` public class MyAgent { private static Instrumentation instrumentation; public static void premain(String args, Instrumentation inst) { instrumentation = inst; } public static Object getObjectThreadLocal(Thread thread, ThreadLocal threadLocal) { return instrumentation.getObjectThreadLocal(thread, threadLocal); } // 其他公共方法 } ``` 宿主应用中的代码: ``` import java.lang.instrument.Instrumentation; public class MyApp { public static void main(String[] args) { // 加载Java Agent String agentJarPath = "/path/to/agent.jar"; String agentArgs = "arg1,arg2"; Instrumentation instrumentation = loadAgent(agentJarPath, agentArgs); // 调用Java Agent中的公共接口 Thread targetThread = // 获取目标线程 ThreadLocal threadLocal = // 获取目标线程中的ThreadLocal对象 Object threadLocalValue = MyAgent.getObjectThreadLocal(targetThread, threadLocal); // 其他业务逻辑 } private static Instrumentation loadAgent(String agentJarPath, String agentArgs) { try { // 通过VirtualMachine.loadAgent方法加载Java Agent VirtualMachine vm = VirtualMachine.attach("pid"); vm.loadAgent(agentJarPath, agentArgs); return MyAgent.getInstrumentation(); } catch (Exception e) { e.printStackTrace(); return null; } } } ``` 在这个示例中,宿主应用通过VirtualMachine.loadAgent方法加载Java Agent,并调用Java Agent提供的公共接口MyAgent.getObjectThreadLocal来获取ThreadLocal变量。需要注意的是,加载Java Agent需要使用VirtualMachine.attach方法,该方法需要传递Java虚拟机的进程ID(pid)。可以通过jps命令来获取Java虚拟机的进程ID。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值