【发布时间】:2021-05-01 11:47:22
【问题描述】:
我编写了一个小 DLL,它被注入到游戏中以应用运行时修复。我决定添加一些键盘监听器:
while (1)
if (AsyncKeyState(...)) (...)
但是,这会占用 CPU 资源,并引入一些明显的卡顿。所以我决定使用 MSDN 通过SetWindowsHookExA 和KeyboardProc 回调建议的回调方法。起初,我通过SetWindowsHookExA(WH_Keyboard, KeyboardProc, NULL, 0) 运行该方法,但收到错误代码ERROR_HOOK_NEEDS_HMOD (0x594)。所以我把我的代码改成了这样:
bool APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpRes)
{
HHOOK hook_ = nullptr;
switch (reason)
{
case DLL_PROCESS_ATTACH:
if (!(hook_ = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hModule, 0)))
{
char x[100];
sprintf(x, "Failed To Hook Keyboard FN: 0x%X", GetLastError());
MessageBox(NULL, x, "Error", MB_ICONERROR);
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
UnhookWindowsHookEx(hook_);
break;
}
return true;
}
这不再给出错误,我的挂钩键盘功能运行良好。然而,一个非常意想不到的副作用是所有正在运行的应用程序的所有键盘捕获都被忽略了。 我注意到 MSDN 的这句话,所以我将它添加到我的代码中:
如果code大于等于0,并且hook过程没有处理该消息,强烈建议调用CallNextHookEx并返回它返回的值;否则,其他安装了 WH_KEYBOARD 挂钩的应用程序将不会收到挂钩通知,因此可能会出现错误行为。如果钩子过程处理了消息,它可能会返回一个非零值,以防止系统将消息传递给钩子链的其余部分或目标窗口过程。
这解决了键盘问题,但现在还有另一个问题,即我无法删除我创建的 DLL。当我尝试删除它时,它显示“dll 正在 Explorer.exe 中运行”。当我杀死explorer.exe 时,它说“dll 正在 SteamHelper.exe 中运行”。当我杀死 steamhelper.exe 时,它说“dll 正在 Chrome.exe 中运行”。这表明我已经以某种方式迷上了每个正在运行的应用程序?
我无法解决此问题,也找不到任何帮助。非常感谢任何见解!
【问题讨论】:
-
我不明白这个问题。您已经要求系统将您的 DLL 注入到每个进程中,并且现在对 DLL 被注入到每个进程中感到惊讶?解决方法是不要将您的 DLL 注入每个进程,但您似乎已经决定这是必需的。
标签: c++ windows dll msdn setwindowshookex