java - VM 启动后启动 Instrumentation Agent

标签 java instrumentation agent

我希望有人能解释一下这个项目,因为我可能会弄错:

我正在阅读有关 Java Agent Instrumentation 的文章,它说代理可以在 VM 启动后启动。因此,如果我想动态替换某些类(而不会使应用程序崩溃),这就是我要使用 agent-main 的目的吗?或者我需要在这里做更多的事情吗?

我知道人们可能会问“您是在谈论 JRebel 吗”- 并不是真的,因为我想做一些简单的事情,而 JRebel 太过分了。

仪器文档 - Java docs for Instrumentation

我理解所有的检测覆盖,但我有点困惑如何在应用程序启动后使用 -agent 参数挂接此代理。

最佳答案

首先,您的代理类需要指定一个 agentmain 方法,例如:

public class MyAgent {
    public static void agentmain(final String args, final Instrumentation inst) {
        try {
            System.out.println("Agent loaded.");
        } catch (Exception e) {
            // Catch and handle every exception as they would
            // otherwise be ignored in an agentmain method
            e.printStackTrace();
        }
    }
}

例如,编译它并将其打包到一个jar 文件中。如果您选择 jar 变体,则它必须在其 manifest 文件 (MANIFEST.MF)。它指向实现 agentmain 方法的类。它可能看起来像:

Manifest-Version: 1.0
Agent-Class: package1.package2.MyAgent

例如,如果它位于那些包中。


之后,您可以通过 VirtualMachine#loadAgent 方法 ( documentation ) 加载代理。请注意,这些类使用的机制是 Java 的Attach 库 的一部分。他们决定,因为大多数用户不需要它,所以不直接将它添加到系统路径中,但您可以直接添加它。它位于

pathToYourJDKInstallation\jre\bin\attach.dll

它需要位于系统属性 java.library.path 指向的地方。例如,您可以将它复制到您的 .../Windows/System32 文件夹或调整属性或类似的东西。


例如,如果您想在另一个当前运行的 jar 中注入(inject)一个 agent-jar,您可以使用如下方法:

public void injectJarIntoJar(final String processIdOfTargetJar,
        final String pathToAgentJar, final String[] argumentsToPass) {
    try {
        final VirtualMachine vm = VirtualMachine.attach(processIdOfTargetJar);
        vm.loadAgent(pathToAgentJar, argumentsToPass.toString());
        vm.detach();
    } catch (AttachNotSupportedException | AgentLoadException
            | AgentInitializationException | IOException e) {
        System.err.println("Unable to inject jar into target jar.");
    }
}

使用相同的技术,您可以将 dll 库(如果它们通过 native 代理接口(interface)实现相应的代理方法)注入(inject) jar。


实际上,如果这对您有帮助,我前段时间已经为这类东西编写了一些小型库。参见 Mem-Eater-Bug ,对应的类是Injector.java整个项目有一个小Wiki .

它有一个示例,展示了如何使用该技术来操纵以 Java 应用程序编写的 SpaceInvaders 游戏。

关于java - VM 启动后启动 Instrumentation Agent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45701826/

相关文章:

java - 如何在不使用-D语法的情况下将属性传递给JVM?

java - 按条件用 JSON 定义组或元素填充 ArrayList<ArrayList<Object>>(尝试在 Android 中为可扩展列表创建数据)

internet-explorer - 如何让 Web 浏览器将所有事件(包括请求、响应、cookie 事件)记录到我可以检查的日志文件中?

java - OpenAM 代理的配置

java - 特工 : Why is the majority of agent work done in java?

java - 增量浮点均值算法的选择(java)

java - 在java的for循环中++i真的比i++快吗?

android - 将触摸发送到 ActivityInstrumentationTestCase2 测试时如何修复 INJECT_EVENTS 权限异常

.net - 如何找到泛型参数的 TypeSpec

java - 不可解析的父 POM : Could not find artifact