使用 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 有几个步骤...
当我试图用 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 有几个步骤...