【问题标题】:How to set/get a value from another JVM如何从另一个 JVM 设置/获取值
【发布时间】:2017-04-17 08:01:24
【问题描述】:

我有一个类Normal,代码如下:

public class Normal {

    private static String myStr = "Not working...";
    private static boolean running = true;

    public static void main(String[] args) {
        while(running) {
            System.out.println(myStr);
        }
    }

}

我在另一个项目中有另一个名为Injector 的类。它的目的是改变Normal的值,即使它们不在同一个JVM中:

public class Injector {

    public static void main(String[] args) {
    String PID = //Gets PID, which works fine

    VirtualMachine vm = VirtualMachine.attach(PID);

    /*
    Set/Get field values for classes in vm?
    */

    }
}

我想要做的是将Normal 类中的值myStrrunning 分别更改为"Working!"false,而不更改Normal 中的代码(仅在Injector 中)。

提前致谢

【问题讨论】:

标签: java jvm code-injection


【解决方案1】:

您需要两个 JAR:

  1. 一个是Java Agent,它使用反射来改变字段值。 Java Agent 的主类应该有agentmain 入口点。

    public static void agentmain(String args, Instrumentation instr) throws Exception {
        Class normalClass = Class.forName("Normal");
        Field myStrField = normalClass.getDeclaredField("myStr");
        myStrField.setAccessible(true);
        myStrField.set(null, "Working!");
    }
    

    您必须添加 MANIFEST.MFAgent-Class 属性并将代理打包到 jar 文件中。

  1. 第二个是使用 Dynamic Attach 将代理 jar 注入正在运行的 VM 的实用程序。让pid 成为目标Java 进程ID。

    import com.sun.tools.attach.VirtualMachine;
    ...
    
        VirtualMachine vm = VirtualMachine.attach(pid);
        try {
            vm.loadAgent(agentJarPath, "");
        } finally {
            vm.detach();
        }
    

    the article 有更多详细信息。

【讨论】:

    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    相关资源
    最近更新 更多