8

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?

Brandon
  • 22,723
  • 11
  • 93
  • 186
  • Is this for windows or linux or some other OS? Which C debugger/IDE are you using? – cup Mar 16 '14 at 19:45
  • I might be missing smth, but can't you just open up debug port and attach to it? In the debugger hit pause VM and expect everything? – WeMakeSoftware Mar 16 '14 at 19:47
  • I'm using Codeblocks and I'm on Windows. I'm not sure what you mean by open up the debugger and hit pause.. – Brandon Mar 16 '14 at 20:13
  • @CantChooseUsernames Let me know if you managed to use my answer. It works fine. – manuell Mar 17 '14 at 18:29

2 Answers2

16

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

manuell
  • 7,528
  • 5
  • 31
  • 58
  • Yes! This works :D I didn't use `SetWindowsHook`. Instead I just used the `CreateThread` and `LoadLibrary` combination for injecting. Nevertheless, it works =) I am happy! – Brandon Mar 17 '14 at 18:35
  • @CantChooseUsernames Happy coding! (and beware the JNI memory leaks :-) – manuell Mar 17 '14 at 19:47
  • @CantChooseUsernames Side note: with `SetWindowsHookEx`, you can choose to attach to the "GUI" thread. It may matter. – manuell Mar 17 '14 at 19:50
1

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.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • 2
    You can inject a dynamic link library in a running java process, and attach to the JVM. See my answer. Works fine on Windows. – manuell Mar 17 '14 at 17:15
  • Works on linux as well, [just a little different of course](https://stackoverflow.com/a/14986308/21851535) – uglibubla May 19 '23 at 13:48