CreateRemoteThread DLL注入成功但未弹出MessageBox问题排查
问题根因
你的代码存在3个核心错误,会直接导致DLL加载失败或者弹窗无法显示:
- DLL路径写入时缺失字符串终止符
你调用VirtualAllocEx申请远程内存、WriteProcessMemory写入DLL路径时,传入的长度参数都是strlen(buffer)。注意C语言中strlen计算的是字符串有效字符长度,不包含末尾必须的\0结束符。LoadLibraryA读取路径参数时会一直向后遍历内存直到碰到\0才会停止,缺失结束符会导致它读到后续内存里的随机垃圾值,根本找不到你指定的C:\drivers\inject.dll文件,DLL加载直接失败。
修复方式:将两处长度参数改为strlen(buffer) + 1,多申请1字节内存,写入时把结束符一同写入目标进程。 - 未校验远程线程执行结果,且未等待加载完成
CreateRemoteThread返回成功仅代表系统已经创建了远程线程对象,不代表线程已经启动执行,更不代表LoadLibraryA已经跑完了DLL加载流程。你现在的代码创建完线程立刻打印成功提示,既不等待线程执行结束,也不获取线程返回值判断加载是否成功(LoadLibraryA执行成功会返回DLL模块基址,失败返回NULL,可通过错误码定位具体失败原因),本质是盲注,根本不知道实际加载结果。
修复方式:创建远程线程后调用WaitForSingleObject(threadID, INFINITE)等待线程执行完毕,再调用GetExitCodeThread获取返回值校验加载结果,所有操作完成后再关闭线程、进程句柄。 - 在DllMain中直接调用MessageBox违反Windows加载规范,就算DLL加载成功也弹不出框
DllMain执行期间系统会持有全局加载器锁(Loader Lock),此时仅能调用kernel32.dll中极少数被明确标记为安全的函数,User32.dll提供的GUI函数(包括MessageBox)此时处于不可安全调用的状态,直接调用大概率触发死锁、函数调用失败,甚至导致目标进程崩溃。
修复方式:DllMain的DLL_PROCESS_ATTACH分支中不要直接执行业务逻辑,仅调用CreateThread创建独立工作线程,把弹窗、业务逻辑全部放到新线程中执行,DllMain本身直接返回即可。
另外还有几个会导致问题的细节:
- 代码存在笔误:打印LoadLibraryA地址获取失败时把
printf拼成了prinf,内存分配失败提示把Cannot拼成了Cannote,会导致出错时看不到正确日志。 - 注入器和目标进程位数必须一致:32位注入器只能注入32位进程,64位注入器只能注入64位进程,否则你在本地获取的
LoadLibraryA地址和目标进程内的函数地址不匹配,远程线程执行时会直接崩溃。 - 注入器需要以管理员权限运行,且确保目标进程有权限读取
C:\drivers\inject.dll文件,否则会因为权限不足加载失败。 - 硬编码的PID 1056必须是注入时目标进程的实时PID,进程每次重启PID都会变化,PID不匹配会导致操作的是其他进程,自然不会有预期效果。
内容的提问来源于stack exchange,提问作者I_4m_Z3r0
相关产品推荐
相关产品推荐

