注入DLL后DllMain未被调用的问题求助
问题分析:添加ImGui/MinHook后DLLMain不执行的排查方向
问题描述
原本可与JNI交互的DLL注入后运行正常,添加ImGui和MinHook实现GUI功能后,DllMain完全不再被调用,仅修改了项目配置中新增库的目录,Visual Studio调试时所有断点均无效,怀疑项目中的*.lib文件是否导致该问题。
提供的代码
主DLL代码
#include <cstdio> #include <Windows.h> #include <WinUser.h> //#include "Core/Patching.h" #include "Cheat.h" #include "Java.h" void MainThread(HMODULE module) { createEnv(); if (getEnv() != nullptr) { //Patching::ApplyPatches(); while (true) { if (GetAsyncKeyState(VK_END)) break; //runModules(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } printf("DETACHED!!!\n"); FreeLibraryAndExitThread(module, 0); } extern "C" bool __stdcall DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { static FILE* p_file{ nullptr }; static std::thread main_thread; if (reason == DLL_PROCESS_ATTACH) { CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MainThread, NULL, NULL, NULL); } else if (reason == DLL_PROCESS_DETACH) { } return true; }
Java.h实现代码
#include "Java.h" JNIEnv* env; void createEnv() { if (env == nullptr) { JavaVM* p_jvm{ nullptr }; jint result = JNI_GetCreatedJavaVMs(&p_jvm, 1, nullptr); JNIEnv* p_env{ nullptr }; // JNI interface pointer p_jvm->AttachCurrentThread((void**)&env, nullptr); if (env == nullptr) printf("Creating JavaEnv failed\n"); } printf("Successfully created JavaEnv\n"); }
排查与解答
一、*.lib库确实可能是问题根源
- 静态初始化冲突:ImGui或MinHook的静态库可能在DLL加载阶段(DllMain执行前)就有全局对象构造、
__init_seg段代码执行等逻辑,如果这些逻辑出现异常(比如非法内存访问、死锁,或者调用了DllMain中禁止的API),系统会直接终止DLL加载流程,DllMain根本没机会运行。 - 编译配置不匹配:如果ImGui/MinHook的库使用的CRT版本(MT/MD)、架构(x86/x64)、字符集和你的项目不一致,会导致DLL加载时CRT初始化失败,系统拒绝加载DLL。
- 链接顺序问题:新增库的链接顺序不合理,可能导致符号解析错误,间接引发加载失败。比如MinHook依赖的系统库没被正确链接,加载时找不到依赖。
二、其他可能的原因
- DLL未成功注入:调试断点无效可能是DLL根本没被加载到目标进程。用Process Explorer查看目标进程的模块列表,确认你的DLL是否存在。
- 违反DllMain安全规范:虽然你的DllMain逻辑简单,但新增库的全局初始化如果触发了创建线程、调用
LoadLibrary等操作,会违反DllMain的安全规则(禁止可能引发重入的操作),导致系统终止加载。 - 调试器附加问题:VS调试器可能没正确附加到目标进程,或者DLL加载时机早于调试器附加,导致断点无法命中。可以尝试手动附加后再注入DLL。
三、具体排查步骤
- 隔离测试:先移除ImGui和MinHook的所有代码(仅保留库链接),看DllMain是否恢复执行。如果恢复,再逐个添加库排查是哪一个导致的问题。
- 核对库配置:确保ImGui/MinHook的库和你的项目编译配置完全一致:
- CRT版本(多线程MT/多线程DLL MD,Debug/Release)
- 平台架构(x86/x64)
- 字符集(多字节/Unicode)
- 换用动态库:如果用的是静态库,尝试换成对应的动态库(DLL版本),减少静态初始化阶段的冲突。
- 用调试工具追踪加载流程:用x64dbg附加到目标进程,设置断点在
LdrLoadDll,跟踪DLL加载过程,查看是否有加载错误(比如返回STATUS_DLL_INIT_FAILED)。 - 改用调试日志:把代码中的
printf换成OutputDebugStringA,用DebugView工具查看输出,确认DllMain是否被调用,或者加载阶段是否有错误信息。
内容的提问来源于stack exchange,提问作者Nikita
相关产品推荐
相关产品推荐

