使用 JNI 注入 DLL 会导致现有的 JVM 崩溃

Injecting DLL with JNI crashing existing JVM

当我试图用 JNI 代码注入 DLL 时,我现有的 JVM (minecraft) 崩溃了。尝试使用 JNI 函数时出现此错误。当我删除此调用时,JVM 不会崩溃。

崩溃代码(来自附加的 Visual Studio 调试器):

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

我的 DLL 代码:

#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;
}

您没有在任何地方初始化 env。您获得指向 JNI_GetCreatedJavaVMs 的指针,但永远不要调用它。从那到工作 JNIEnv 有几个步骤...