2012-03-22 73 views
2

我試過使用全局鉤子,但hookprocedure只接收到我的程序線程的窗口過程消息,並且針對特定應用程序(線程)根本沒有消息。掛鉤後沒有收到Window Procedure消息WH_CALLWNDPROC

我正確地使用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: %s\n", 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); 
} 
+0

應該用'NULL'' hModule'調用'SetWindowsHookEx'。也可能需要檢查LoadLibrary的返回值。過去我有一些相對路徑問題。 – 2012-03-22 23:42:46

+0

@MikeKwan,如果線程'dwThreadId'是由相同的進程創建的'hModule'應該只是null。在這種情況下,它不是。 – 2012-03-23 00:14:47

+0

@NickWhaley:爲什麼不呢?他使用'LoadLibrary',將DLL加載到同一個進程中。 – 2012-03-23 00:17:12

回答

1

沒有問題,掛鉤安裝正確。但是我不知道鉤子過程從窗口過程已經獲得消息的過程的上下文中運行。

1

看起來它應該工作。只是檢查一些建議。

  • 32位DLL只會掛鉤32位進程。而一個64位DLL只會掛鉤64位進程。
  • 嘗試將dwThreadId設置爲0以創建全局鉤子,以查看它是否以此方式工作。
  • 確保掛鉤DLL可以找到並且可以被目標進程讀取。
+0

當我將'dwThreadId'設置爲'0'後,它將獲取消息發佈到我創建的空窗口('hooking'),以及另外兩個名爲DEFAULT IME的窗口和僅僅使用visual C++,chrome的'MSCTFIME UI' ,記事本也打開。 – cplusplus 2012-03-23 03:11:15

+0

閱讀http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_1之後,可能系統範圍的鉤子已正確安裝,但「LaunchListener」在目標進程的上下文中被調用,所以任何'printf'調用都不會輸出到我擁有的控制檯窗口(需要使用進程間通信)。這個理論只解釋了「掛鉤」窗口消息。此外,調試器沒有附加到目標進程,只是調試與我的窗口相關的線程...所以'__debugbreak()'也不會被觸發。 – cplusplus 2012-03-23 03:52:56

+0

但我不確定爲什麼交換鉤子類型爲'WH_KEYBOARD'使其工作 – cplusplus 2012-03-23 03:58:42