Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attach to already running JVM

Is there a way to attach to an already running JVM?

For example, in JNI you can use JNI_CreateJavaVM to create a VM and run a jar and inspect all its classes..

However, if the jar is already running, I cannot find a way to attach to its JVM and communicate with its classes or get its env pointer..

Another problem is that if the jar loads my native library (.dll) and I want to create a JVM inside the .dll, I cannot.. Nor can I attach the jar's current JVM either without the jar calling my function..

Example on the Java side:

class Foo
{
    static {loadLibrary("Foo")}
}

on the C++ side:

void Foo()
{
    //CreateJVM
    //Attach to the current process..
    //Call function from the jar that loaded me.
}

This cannot be done without the jar calling Foo first.

Any ideas? Is there no way to get the current JVM or to attach to it or an external jvm instance?

like image 775
Brandon Avatar asked Mar 16 '14 19:03

Brandon


2 Answers

Yes you can.

1) Inject a DLL in the process hosting the JVM (eg, java.exe, or javaw.exe, or iexplore.exe). A common injection technique is to use SetWindowsHookEx

2) In the DLL, get the module handle of the jvm.dll using GetModuleHandle

3) Get the address of the JNI_GetCreatedJavaVMs function, using GetProcAddress

4) Call the function and, if successfull, attach your thread to the first JVM found, using the AttachCurrentThread function pointer from the JavaVM struture.

5) Done.

Usefull link: The Invocation API

like image 76
manuell Avatar answered Oct 19 '22 23:10

manuell


No you cannot. JNI allow for exactly two models:

  • Your non-Java program creates the JVM.
  • You Java program invokes a native method.

If you need to communicate in other cases, you will need to use some other mechanism. Web services are one straightforward approach.

like image 45
bmargulies Avatar answered Oct 20 '22 00:10

bmargulies