2012-03-22 26 views
2

グローバルフックを使用しようとしましたが、フックプロシージャは自分のプログラムスレッドのウィンドウプロシージャメッセージのみを受信し、特定のアプリケーション(スレッド)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

'SetWindowsHookEx'は' NULL'' hModule'で呼び出されるべきです。また、 'LoadLibrary'の戻り値をチェックすることは価値があります。私は過去に相対的な道にいくつか問題がありました。 –

+0

@MikeKwan、 'hModule'は、スレッド' dwThreadId'が同じプロセスによって作成された場合にのみnullになります。この場合、そうではありません。 –

+0

@NickWhaley:どうしてですか?彼はDLLを同じプロセスにロードする 'LoadLibrary'を使っています。 –

答えて

1

問題はありません。フックが正しく取り付けられます。しかし、私は、フックプロシージャがウィンドウプロシージャがメッセージを受け取ったプロセスのコンテキストから実行されることを知らなかった。

1

動作するはずです。ちょうどいくつかの提案をチェックしてください。

  • 32ビットDLLは、32ビットプロセスのみをフックします。 64ビットDLLは64ビットプロセスだけをフックします。
  • dwThreadId0に設定すると、グローバルフックが動作するかどうかだけを確認してください。
  • フックDLLが見つかり、ターゲットプロセスが読み取り可能であることを確認します。
+0

'dwThreadId'を' 0'に設定すると、作成した空のウィンドウ( 'hooking')にポストされたメッセージと' DEFAULT IME'と 'MSCTFIME UI'という2つのウィンドウがVisual C++、chrome 、メモ帳も開いています。 – cplusplus

+0

http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Aother-Proces#section_1を読むと、システム全体のフックが正しくインストールされている可能性がありますが、 'LaunchListener'ターゲットプロセスのコンテキストで呼び出されているので、 'printf'呼び出しは私が持っているコンソールウィンドウに出力されません(プロセス間通信の使用が必要です)。この理論は、単に「フッキング」ウィンドウメッセージを得ることについて説明しています。また、デバッガはターゲットプロセスに接続されておらず、自分のウィンドウに関連付けられたスレッドだけをデバッグしているので、 '__debugbreak()'もトリガされません。 – cplusplus

+0

しかし、私はなぜWH_KEYBOARD'にフックタイプを交換するのがうまくいかないのか分かりません – cplusplus

関連する問題