如何从另一个JVM设置/获取值

时间:2017-04-17 08:01:25

标签: java jvm code-injection

我有一个类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?
    */

    }
}

我想要做的是将类myStr中的值runningNormal分别更改为"Working!"false而不更改{中的代码{1}}(仅限于Normal)。

提前致谢

1 个答案:

答案 0 :(得分:0)

你需要两个JAR:

  1. 一个是Java Agent,它使用Reflection来更改字段值。 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.MF Agent-Class属性并将代理打包到jar文件中。

    1. 第二个是使用动态附加将代理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中的更多细节。