GetMessage() empfängt von Hook, durchläuft aber Schleife nicht



  • Hallo,
    ich habe gerade angefangen WINAPI zu lernen, und versuche einen Keylogger zu schreiben. Was ich weiß:
    GetMessage() liefert MSG's aus der eigenen Thread-Queue zurück.
    SetWindowsHookEx() liefert genau an den Thread MSG's, der den Hook installiert hat.
    Folglich muss der Thread, der SetWindowsHookEx() aufruft auch der sein der die Hook-MSG's durch die GetMessage() empfängt.

    Mein folgender Code funktioniert, bis auf die Tatsache, dass das printf("\mMSG"); nicht ausgeführt wird, was schließen lässt, dass auch keine MSG's gelesen werden. Wie kann das aber sein? Wenn ich die while-Schleife ersetzte mit einem Sleep(10000) und dann Knöpfe drücke, passiert nichts!

    Danke für eure Hilfe!
    Grüße;
    Linzus

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    LRESULT CALLBACK LLKBProc(int nCode, WPARAM wParam, LPARAM lParam) {
        KBDLLHOOKSTRUCT *keyMetaP = (KBDLLHOOKSTRUCT *) lParam;
        printf("\nkey = %x", keyMetaP->vkCode);
        CallNextHookEx(NULL, nCode, wParam, lParam);
        return 0;
    }
    
    void logging() {
        printf("\nTHREAD:");
    
        // get handle to process
        HINSTANCE hExe = GetModuleHandle(NULL);
        printf("\nHinstance = %i", hExe);
    
        // set hook
        HHOOK keyHook;
        keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) LLKBProc, hExe, 0);
        printf("\nkeyHook = %i", keyHook);
    
        // rx messages from hook
        int i = 0;
        MSG msg;
        while ( GetMessage(&msg, 0, 0, 0) != -1 && (i < 10) ) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            i++;
            printf("\nMSG");
        }
    
        UnhookWindowsHookEx(keyHook);
    
        return;
    }
    
    int main()
    {
        HANDLE thread = CreateThread(0, 0, logging, 0, 0, 0);
        WaitForSingleObject(thread, INFINITE);
        return 0;
    }
    

    PS: Wie wenn nicht mit "

    " kann ich den Code ordentlich formatieren?



  • Du denkst zu kompliziert. Hier mal ein kleines Beispiel:

    #include <windows.h>
    #pragma comment(linker, "/entry:Startup /subsystem:console")
    
    LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, PKBDLLHOOKSTRUCT lParam);
    
    INT Startup(VOID)
    {
    	SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, *(PDWORD)(__readfsdword(0x30) + 8), 0);
    
    	while(GetMessage(0, 0, 0, 0));
    
    	ExitProcess(EXIT_SUCCESS);
    }
    
    LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, PKBDLLHOOKSTRUCT lParam)
    {
    	if (wParam == WM_KEYDOWN)
    	{
    		printf("KeyDown:\t%08X\n", lParam->vkCode);
    	}
    	else if (wParam == WM_KEYUP)
    	{
    		printf("KeyUp:\t\t%08X\n", lParam->vkCode);
    	}
    
    	return CallNextHookEx(0, nCode, wParam, lParam);
    }
    


  • linzus schrieb:

    Hallo,
    PS: Wie wenn nicht mit "[code="c"][/code]" kann ich den Code ordentlich formatieren?

    Überprüfe mal in deinem Profil, ob "BBCode immer aktivieren:" auf "Ja" steht.
    Und dann editiere und speichere deinen Beitrag nochmal (und schau, daß "BBCode in diesem Beitrag deaktivieren" nicht angehakt ist).



  • Th69 schrieb:

    linzus schrieb:

    Hallo,
    PS: Wie wenn nicht mit "[code="c"][/code]" kann ich den Code ordentlich formatieren?

    Überprüfe mal in deinem Profil, ob "BBCode immer aktivieren:" auf "Ja" steht.
    Und dann editiere und speichere deinen Beitrag nochmal (und schau, daß "BBCode in diesem Beitrag deaktivieren" nicht angehakt ist).

    @Th69
    Super danke, hat funktioniert. War sowohl im Profil als auch im Beitrag deaktiviert.

    @Suznil:
    Danke für das Beispiel. Ich weiß jetzt aber immer noch nicht wieso die message-loop denn nicht durchlaufen wird. MSDN https://msdn.microsoft.com/de-de/library/windows/desktop/ms644985(v=vs.85).aspx schreibt:

    Remarks

    An application installs the hook procedure by specifying the WH_KEYBOARD_LL hook type and a pointer to the hook procedure in a call to the SetWindowsHookEx function.
    This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.

    Also bedeutet das doch, dass der Hook ausgelöst wird, indem dem installierenden Thread eine msg gesendet wird. Wieso wird dann aber der loop dennoch nicht durchlaufen?

    @Susnil:
    mit *(PDWORD)(__readfsdword(0x30) + 😎 ließt du vom FS beginnend 0x30 entfernt aus (also Prozess Environment Block?) und dort dann mit dem Offset 8 also die Ldd-Struktur und ließt dort das erste DWORD (32bit unsigned) was nicht sein kann, weil dort "Reserved" steht.
    https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa813706(v=vs.85).aspx
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa813708(v=vs.85).aspx

    Ich würde gerne verstehen wie du die HINSTANCE bekommst ohne GetModule(NULL) 🙂

    Danke und Grüße,
    Linus



  • Ich würde gerne verstehen wie du die HINSTANCE bekommst ohne GetModule(NULL) 🙂

    GetModuleHandle(NULL) liefert immer nur HINSTANCE der EXE nicht unbedingt, die des aktuellen Modules (also einer DLL).

    Dein hInstance bekommst Du automatisch in Deinem WinMain Startcode.

    Du hast eine Cconsole Anwendung. Da wird auch hinstance übergeben, das wird aber intern von der CRT verdeckt, weil diese wiederum Deinen main Code aufruft, der eben keinen hInstance Parameter kennt.

    Hier hilft __ImageBase...
    Siehe https://blogs.msdn.microsoft.com/oldnewthing/20041025-00/?p=37483

    Grundsätzlich habe ich das mal vor langer Zeit hier diskutiert:
    http://blog.m-ri.de/index.php/2007/12/12/die-unsitte-immer-getmodulehandlenull-fuer-hinstance-in-createwindow-und-registerclass-zu-verwenden/comment-page-1/



  • Martin Richter schrieb:

    Ich würde gerne verstehen wie du die HINSTANCE bekommst ohne GetModule(NULL) 🙂

    Grundsätzlich habe ich das mal vor langer Zeit hier diskutiert:
    http://blog.m-ri.de/index.php/2007/12/12/die-unsitte-immer-getmodulehandlenull-fuer-hinstance-in-createwindow-und-registerclass-zu-verwenden/comment-page-1/

    Sehr interessant, danke.