问题
I want to be able to replace and add some classes to an already running JVM. I read that I need to use CreateRemoteThread
, but I don't completely get it. I read this post on how to do it (Software RnD), but I can't figure out what it does and why. Besides that, it only introduces new classes, but doesn't change existing ones. How can I do it with C++?
回答1:
You don't even need CreateRemoteThread
- there is an official way to connect to remote JVM and replace loaded classes by using Attach API.
You need a Java Agent that calls Instrumentation.redefineClasses.
public static void agentmain(String args, Instrumentation instr) throws Exception { Class oldClass = Class.forName("org.pkg.MyClass"); Path newFile = Paths.get("/path/to/MyClass.class"); byte[] newData = Files.readAllBytes(newFile); instr.redefineClasses(new ClassDefinition(oldClass, newData)); }
You'll have to add
MANIFEST.MF
withAgent-Class
attribute and pack the agent into a jar file.
Then use Dynamic Attach to inject the agent jar into the running VM (with process ID =
pid
).import com.sun.tools.attach.VirtualMachine; ... VirtualMachine vm = VirtualMachine.attach(pid); try { vm.loadAgent(agentJarPath, options); } finally { vm.detach(); }
A bit more details in the article.
If you insist on using C/C++ instead of Java API, you may look at my jattach utility.
来源:https://stackoverflow.com/questions/43157989/inject-jar-and-replace-classes-in-running-jvm