
用 2017 工具链编译, 创建线程这一步就卡住不运行了:
换 2019 编译,线程运行正常,钩子成功注册:
C++代码:
#include <Windows.h> #include <stdio.h> #include <thread> extern "C" { __declspec(dllexport) BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpReserved) // reserved { // Perform actions based on the reason for calling. switch (fdwReason) { case DLL_PROCESS_ATTACH: { // Initialize once for each new process. // Return FALSE to fail DLL load. printf("附加到进程\n"); std::thread th([]{ HHOOK hook = SetWindowsHookExW(WH_KEYBOARD_LL, (HOOKPROC)[](int code, WPARAM wParam, LPARAM lParam)->LRESULT{ KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam; // Do the wParam and lParam parameters contain information about a keyboard message. if (code == HC_ACTION) { // Messsage data is ready for pickup if (wParam == WM_SYSKEYDOWN || wParam == WM_KEYDOWN) { if (p->vkCode == VK_LWIN) { printf("拦截 KeyDown 事件\n"); return TRUE; } } } // hook procedure must pass the message *Always* return CallNextHookEx(NULL, code, wParam, lParam); }, NULL, 0); printf("hook = %p\n", hook); MSG msg = {0}; while (1) { GetMessage(&msg, NULL, 0, 0); TranslateMessage(&msg); DispatchMessage(&msg); } }); th.detach(); break; } case DLL_THREAD_ATTACH: // Do thread-specific initialization. printf("附加到线程\n"); break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. printf("从线程分离\n"); break; case DLL_PROCESS_DETACH: // Perform any necessary cleanup. printf("从进程分离\n"); break; } return TRUE; // Successful DLL_PROCESS_ATTACH. } } 1 x1596357 2022-03-11 15:54:02 +08:00 DllMain 里创建线程本来就是不允许的。https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices |
4 ysc3839 2022-03-11 16:44:11 +08:00 感觉是 X-Y Problem https://coolshell.cn/articles/10804.html 看上去你是注入 DLL 之后再设置一个 low level keyboard hook 为什么要这么做?直接在另一个进程中跑不行吗? |
5 yulon 2022-03-11 16:48:47 +08:00 首先 DllMain 里不推荐创建线程,如果真要创建线程请用 CreateThread ,用 std::thread 和 _beginthread 都有可能死锁,因为要初始化语言标准库。 |