Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Inject java agent in to running jvm

Basically, I am trying to write something that lists every class loaded by the JVM. What I wrote works, but it only works for the jvm it is running on. I crafted a java agent to dynamically inject into another JVM, but then realized I don't actually know how to inject it. How do I actually send this agent into another JVM? Is it possible?

like image 902
Stoud Avatar asked Aug 15 '16 03:08

Stoud


2 Answers

Dynamic agents need to declare an agentmain(String, Instrumentation) method which is executed upon attachment within the target VM. You can use the tools.jar dependency which is (until Java 9) only included in a JDK but not a JRE. You can however bundle your agent program with a JDK and attach to JVMs from there.

The biggest pitfall is that the API differs for different VMs; you can however use a library like byte-buddy-agent which contains different implementations for different VMs. An attachment can be done using:

ByteBuddyAgent.attach("my.jar", "my-pid");

This attaches the agent contained in my.jar onto the Java process with id my-id.

like image 191
Rafael Winterhalter Avatar answered Sep 28 '22 18:09

Rafael Winterhalter


Agents can be injected with HotSpot Attach API.
Run the following snippet with $JAVA_HOME/lib/tools.jar on the class path.

    VirtualMachine vm = VirtualMachine.attach(PID);
    try {
        vm.loadAgent(agentJar);
    } finally {
        vm.detach();
    }

Alternatively you may do this with my command-line jattach utility:

$ jattach PID load instrument false /path/to/agent.jar

Note that in order to support dynamic attach, your Java agent should have agentmain method and Agent-Class property in MANIFEST.MF.

like image 39
apangin Avatar answered Sep 28 '22 18:09

apangin