SetWindowsHookEx返回0x7E错误:进程键盘钩子挂载问题排查
排查GetLastError返回0x7E(模块未找到)的思路
首先,0x7E对应的是ERROR_MOD_NOT_FOUND,虽然你觉得模块查找逻辑没问题,但实际场景里有几个容易踩的坑,咱们一步步捋:
1. 先确认DLL路径的绝对正确性
你注入时传递给目标进程的DLL路径,必须是绝对路径,不能用相对路径。因为目标进程的工作目录大概率和你的注入程序不一样——比如你在C:\tools里运行注入器,但目标进程可能在C:\Program Files\XXX下,它会在自己的工作目录找DLL,自然找不到。
解决办法:用GetModuleFileNameA/W获取你自己程序的路径,然后拼接出DLL的绝对路径,或者直接写死绝对路径测试(比如C:\your_dll_path\hook.dll)。
2. 检查32位/64位进程不匹配的问题
这个是高频坑:如果你的注入器是32位程序,想注入64位目标进程,或者反过来,LoadLibraryW在目标进程里会直接失败返回NULL,GetLastError就是0x7E。
怎么验证?
- 用
IsWow64Process检查目标进程的位数,和你的注入器位数对比。 - 确保DLL的位数和目标进程一致——32位DLL只能注入32位进程,64位同理。
3. 模块查找逻辑的细节漏洞
你说模块查找逻辑正确,但有没有考虑这些情况?
- 目标进程是否有权限访问你存放DLL的目录?比如DLL放在需要管理员权限的目录,而目标进程是普通权限运行,会导致访问失败,间接触发0x7E。
- 有没有拼写错误?比如DLL文件名写错(比如
Hook.dll写成Hookk.dll),或者路径里有中文但用了ANSI版API(比如LoadLibraryA而不是LoadLibraryW),导致路径解析乱码。
4. 结合你给出的代码补充建议
你现在的代码是通过EnumWindows找目标进程的窗口,这一步没问题,但后续注入时要注意:
- 如果用
CreateRemoteThread注入,传递的参数(DLL路径)要先在目标进程里分配内存(VirtualAllocEx),然后用WriteProcessMemory写入绝对路径,再调用LoadLibraryW。千万不能直接把本地进程的字符串指针传给远程线程,目标进程访问不了你的进程内存,也会导致加载失败。
举个正确的注入片段示例:
// 假设已经拿到目标进程句柄hProcess WCHAR szDllPath[MAX_PATH]; GetModuleFileNameW(NULL, szDllPath, MAX_PATH); PathRemoveFileSpecW(szDllPath); PathAppendW(szDllPath, L"your_hook.dll"); // 在目标进程分配内存 LPVOID pRemotePath = VirtualAllocEx(hProcess, NULL, MAX_PATH * sizeof(WCHAR), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (pRemotePath == NULL) { /* 处理错误 */ } // 写入DLL路径 if (!WriteProcessMemory(hProcess, pRemotePath, szDllPath, MAX_PATH * sizeof(WCHAR), NULL)) { /* 处理错误 */ } // 创建远程线程加载DLL HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"), pRemotePath, 0, NULL);
先从上面这几个点排查,大概率能找到问题所在。
内容的提问来源于stack exchange,提问作者andrew r
相关产品推荐
相关产品推荐

