Search code examples
c++dlljava-native-interfacedll-injection

Injecting DLL with JNI crashing existing JVM


when I'm trying to inject DLL with JNI code, my existing JVM (minecraft) crashing. I got this error when trying to use JNI function. When I removed this call, JVM doesn't crash.

Crash code (from attached Visual Studio Debugger):

Unhandled exception at 0x00000000352B10CB in javaw.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

My DLL code:

#include "pch.h"
#include "jni.h"
#include <iostream>

JavaVM* jvm;
JNIEnv* env;
HANDLE jvmHandle;
FARPROC func_JNI_GetCreatedJavaVMs;
JavaVMInitArgs vm_args;

void init() {
    AllocConsole();
    freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
    std::cout << "This works" << std::endl;

    typedef jint(JNICALL* GetCreatedJavaVMs)(JavaVM**, jsize, jsize*);
    GetCreatedJavaVMs jni_GetCreatedJavaVMs;
    jni_GetCreatedJavaVMs = (GetCreatedJavaVMs)GetProcAddress(GetModuleHandle(
        TEXT("jvm.dll")), "JNI_GetCreatedJavaVMs");

    std::cout << "CreatedJavaVMs: "<<jni_GetCreatedJavaVMs << std::endl;

    std::cout << "JVM load succeeded: Version ";
    jint ver = env->GetVersion(); //Removing this removes crashes too.
    std::cout << ((ver >> 16) & 0x0f) << "." << (ver & 0x0f) << std::endl;




    //if (getEnvStat == JNI_EDETACHED)
    //{
    //     vm->AttachCurrentThread((void**)&env, NULL);
    // }

    /*if (env != nullptr)
    {
        //start
    }


    if (env->ExceptionCheck())
    {
        env->ExceptionDescribe();
    }

    vm->DetachCurrentThread();*/

}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    init();
    return TRUE;
}

Solution

  • You don't initialize env anywhere. You get the pointer to JNI_GetCreatedJavaVMs, but don't ever invoke it. There are several steps from that to a working JNIEnv...