挂接WH_CALLWNDPROC后未获取窗口过程消息

Not getting Window Procedure messages after hooking WH_CALLWNDPROC

本文关键字:获取 窗口 过程 消息 WH CALLWNDPROC 挂接      更新时间:2023-10-16

我尝试过使用全局钩子,但钩子过程只接收到我的程序线程的窗口过程消息,而针对特定的应用程序(线程)则根本没有消息。

我正确地将DLL中的一个函数用于非本地钩子。这是我的应用程序代码。

#include <Windows.h>
#include <stdio.h>
HINSTANCE hinst;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int main() {
    HWND notepad = FindWindow(NULL, L"Untitled - Notepad");
    if (!notepad)
        return 0;
    hinst = GetModuleHandle(NULL);
    // create a window class:
    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hinst;
    wc.lpszClassName = L"hooking";
    // register class with operating system:
    RegisterClass(&wc);
    // create and show window:
    HWND hwnd = CreateWindow(L"hooking", L"hooking", WS_OVERLAPPEDWINDOW, 0, 0, 500, 400, NULL, NULL, hinst, NULL);
    if (hwnd == NULL) {
        return 0;
    }
    ShowWindow(hwnd, SW_SHOW);
    DWORD threadID = GetWindowThreadProcessId(notepad, NULL);
    HINSTANCE hinstDLL = LoadLibrary(TEXT("..\Debug\ProcHookDLL.dll"));
    void (*AttachHookProc)(DWORD);
    AttachHookProc = (void (*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook"); 
    AttachHookProc(threadID);
    // handle messages:
    MSG msg = {};
    while(GetMessage(&msg, hwnd, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    printf("Done execution... press any key to exit");
    char garbage = getchar();
    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_DESTROY) {
        PostQuitMessage(0);
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

这是DLL的代码。我没有收到任何信息是什么原因?

#include <Windows.h>
#include <stdio.h>
// TODO: create a mutex so this can only be loaded once
HMODULE thisModule;
HHOOK hook;
LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    thisModule = hModule;
    // Very restricted set of things that can be done in DllMain, refer to documentation
    // before adding anything here.
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif
//window message loop is necessary for hooks to work? (didn't work with console app)
//provide function pointer to execute when notepad is launched.
__declspec(dllexport) void AttachHook(DWORD threadID) {
    hook = SetWindowsHookEx(WH_CALLWNDPROC, LaunchListener, thisModule, threadID);
}
#ifdef __cplusplus
}
#endif
LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam) {
    // process event here
    if (nCode >= 0) {
        //wparam specifies if the message was sent by the current thread or not.
        CWPSTRUCT * cwp = (CWPSTRUCT *)lParam;
        wchar_t windowName[256];
        GetWindowText(cwp->hwnd, windowName, 256);
        wprintf(L"%#8X: %sn", cwp->message, windowName);
        if (cwp->message == WM_CREATE) {
            __debugbreak();
            wchar_t moduleName[256];
            //cwp->hwnd
            //GetModuleFileName(0, moduleName, 256);
            GetWindowText(cwp->hwnd, moduleName, 256);
            int x = 0;
            x++;
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

没有问题,钩子安装正确。然而,我不知道钩子过程是从窗口过程收到消息的进程的上下文中运行的。

看起来它应该可以工作。只是检查了一些建议。

  • 32位DLL只挂接32位进程。而64位DLL将只挂接64位进程
  • 尝试将dwThreadId设置为0以生成全局挂钩,看看它是否以这种方式工作
  • 确保可以找到挂钩DLL并且目标进程可读