Window Message Hook funktioniert nicht?



  • Hallo zusammen,

    ich versuche gerade eine Window Hook für eine externe Anwendung zu schreiben. Als Test-Anwendung verwende ich Notepad nach einem Beispiel auf stackoverflow. Der Ablauf sieht so aus: Ich habe eine exe, wenn diese gestartet wird lädt sie eine dll welche zusammen mit der exe mein Programm ausführen.

    In dieser dll lade ich jetzt meine callback Funktion für den Window Hook aus einer weiteren dll. Das Ganze sieht etwa so aus:

    void OnStart(void) 
    { 
        // Dieser code wird beim Laden der ersten dll ausgeführt
    	HWND notepad = FindWindow(NULL, L"Test.txt - Editor");
    	DWORD threadID = GetWindowThreadProcessId(notepad, NULL);
    
        // Hier wird die zweite dll geladen
    	HINSTANCE hinstDLL = LoadLibrary(L"Hook.dll");
    
        // Und hier die Hook hinzugefügt
    	void (*AttachHookProc)(DWORD);
        AttachHookProc = (void (*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook"); 
        AttachHookProc(threadID);
    }
    

    Der Code in der zweiten dll, welche die Hook bereitstellen soll sieht dann so aus:

    #include "stdafx.h"
    #include <Windows.h>
    #include <stdio.h>
    
    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;
    
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    	return TRUE;
    }
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    __declspec(dllexport) void AttachHook(DWORD threadID) {
        // WH_CALLWNDPROC funktioniert nicht, WH_KEYBOARD komischerweise schon
        hook = SetWindowsHookEx(WH_CALLWNDPROC, LaunchListener, thisModule, threadID);
    }
    #ifdef __cplusplus
    }
    #endif
    
    LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam) {
        // Message Box zu Testzwecken anzeigen
    	MessageBox(NULL, L"TEST!", L"TEST!",
    				   MB_ICONEXCLAMATION | MB_OK);
    
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }
    

    Das seltsame ist, dass das Ganze mit dem Parameter WH_CALLWNDPROC bei SetWindowsHookEx nicht funktioniert, d.h. es passiert einfach gar nichts wenn ich irgendwas mit dem Notpad Fenster mache (Verschieben, Resize, etc).

    Wenn ich statt WH_CALLWNDPROC aber WH_KEYBOARD verwende, dann funktioniert es einwandfrei!

    Woran kann das liegen?

    Schöne Grüße,
    hs



  • <a href= schrieb:

    MSDN">The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.

    Könnte es daran liegen ?

    Ansonsten werte mal den Rückgabewert von "SetWindowsHookEx" aus.



  • Hallo,

    danke schonmal für die Antwort. Also den Rückgabewert habe ich ausgwertet, und ich bekomme von SetWindowHookEx auch ein Handle ungleich NULL zurück, also müsste das Installieren der Hook ja erfolgreich gewesen sein.

    Hab testweise auch mal NULL anstatt hMod verwendet, aber das bringt leider auch nichts, SetWindowHookEx gibt dann auch NULL zurück, schlägt also fehl.

    Trotzdem, obwohl es mit dem "normalen" hMod Parameter ja funktionieren sollte, passiert gar nichts nachdem die Hook installiert wurde... 😕



  • Vergiss meine letzte Antwort, hab da was durcheinander gebracht.
    Dein Problem wird sein dass notepad 64bit ist, deine Dll aber 32 bit. Deshalb wird windows deine dll auch nur in 32bit prozesse injecten 😉



  • Aber warum funktioniert dann WH_KEYBOARD problemlos? Wenn ich das als Parameter übergebe macht das die dll ja nicht zu einem 64 Bit Prozess (oder?), injected wird sie aber trotzdem korrekt.


  • Mod

    Benutz den Debugger und schau was im Zielprozess passiert.
    Das erübrigt auch so was Unsinniges wie eine MessageBox zu benutzen in der "WndProc"...

    Besser für solche Zwecke geeignet ist auch OutputDebugString!



  • Ja, also ich bin da schon mit dem Debugger durchgegangen (Schritt für Schritt) und das komische ist dass das Program nie in die Callback Funktion der dll reingeht.

    Also bei Startup läuft der schön Schritt für Schritt durch die Hook initialisierung (Funktion OnStart) und erkennt auch alles richtig. Notepad Handle, Prozess Handle etc wird alles richtig erkannt (mit Spy++ gecheckt).

    Nur in die Callback Funktion geht er nie. Wenn ich aber WH_KEYBOARD benutze funktioniert es und ich lande bei gesetztem Breakpoint auch direkt in der Callback Funktion. Leider reichen mir Keyboard Events nicht 😞


  • Mod

    Debugge den Zielprozess. Wird dort die DLL geladen?



  • Also der Zielprozess ist in dem Fall ja meine erste dll, welche die Hook.dll lädt (nur damit ich das richtig verstanden habe)?

    Also in der Funktion OnStart wird die dll welche die Callback Funktion für die Hook lädt erfolgreich geladen. Nach dieser Zeile:

    HINSTANCE hinstDLL = LoadLibrary(L"Hook.dll");
    

    Ist hinstDLL ein Handle ungleich NULL, das Laden muss also erfolgreich gewesen sein. Auch lande ich bei gesetztem Breakpoint in der DllMain Funktion der Hook.dll, das Laden klappt also auf jeden Fall.


  • Mod

    Nein! Dein Zielprozess ist Notepad. Attache Dich mit dem Debugger und schau was passiert.



  • Äh, wie macht man denn so was?

    Hab mittels "Debug->Attach to Process..." den Debuger zu dem Notepad Prozess hinzugefügt, aber wie schau ich jetzt was da intern passiert?

    Wenn ich in der Menüleiste bei Process Notepad.exe auswähle bekomme ich die Meldung:

    "No symbols are loaded for any call stack frame. The source code cannot be displayed."

    Wie soll ich denn ohne den Source Code das Debuggen können?


  • Mod

    1. kannst Du im Debug-Output View sehen ob Deine DLL geladene wird.
    2. Wenn Deine DLL geladen ist, kannst Du auch im fremden Prozess Deine DLL debuggen.



  • Ok, hab das mal gemacht.

    Im Debug Output Fenster wird durch den Aufruf der Funktion OnStart folgendes ausgegeben:

    The thread 'Win64 Thread' (0xa20) has exited with code 0 (0x0).
    'dllDebugger.exe': Loaded 'C:\Users\XYZ\Documents\Visual Studio 2008\Projects\myProject\Hook.dll', Symbols loaded.

    Da steht nichts von notepad.exe. Heißt dass die dll wurde nicht richtig geladen?

    Allerdings: Wenn ich wieder WH_KEYBOARD anstatt WH_CALLWNDPROC verwende steht da genau das Gleiche. Wenn ich dann in notpad irgendwas eintippe wird die callback Funktion korrekt aufgerufen, im Debugger erscheint aber die Meldung:

    First-chance exception at 0x696f1476 (Hook.dll) in dllDebugger.exe: 0xC0000005: Access violation reading location 0x0026000d.

    Könnte das Problem damit zusammenhängen?



  • Hallo,

    ich komm hier leider immer noch nicht weiter... Hab auch extra mal ein paar alte Programme genommen die sicher 32 bit sind, aber daran liegt es auch nicht.

    Was ich bei dem debugging nicht verstehe ist auch dass mir gar nicht angezeigt wird ob die dll jetzt geladen wurde oder nicht. Also ich füge per "Debug->Attach to Process..." den Prozess des jeweiligen Zielprogramms hinzu, aber im Debug-Output View steht nichts davon dass die dll geladen wurde.

    Komischerweise auch bei WH_KEYBOARD nicht, obwohl es da ja offensichtlich klappt mit dem Laden.

    Das kann doch nicht so schwer sein?


Anmelden zum Antworten