Keyboard Hook



  • Hi!

    Ich möchte die HookDll aus dem FAQ verwenden und habe dazu dieses Programm geschrieben:

    #include <windows.h> 
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);  
    
    //Deklaration der Windows-Nachrichten-Prozedur 
    typedef void (* SETUP)(HWND);   /* Zeiger auf exportierte Funktion */ 
    typedef void (* UNINSTALL)(void);   /* Zeiger auf exportierte Funktion */ 
    
    int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow) 
    { 
    char szName[] = "Fensterklasse"; 
    WNDCLASS wc; 
    
    wc.style         = CS_HREDRAW | CS_VREDRAW;   // CS = "class style" 
    wc.lpfnWndProc   = WndProc; 
    wc.cbClsExtra    = 0; 
    wc.cbWndExtra    = 0; 
    wc.hInstance     = hI; 
    wc.hIcon         = LoadIcon (NULL, IDI_WINLOGO); 
    wc.hCursor       = LoadCursor (NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); 
    wc.lpszMenuName  = NULL; 
    wc.lpszClassName = szName; 
    
    RegisterClass (&wc); 
    
    HWND hwnd = CreateWindow (szName, "", WS_SYSMENU | WS_THICKFRAME,  
                              200, 100, 600, 400, NULL, NULL, hI, NULL);
    
    ShowWindow   (hwnd, iCmdShow);
    UpdateWindow (hwnd);
    
    // Nachrichten-Schleife
    MSG msg;
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    
    return msg.wParam;
    }
    
    // Windows-Nachrichten-Prozedur 
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
    { 
    HDC hdc; 
    PAINTSTRUCT ps;
    BOOL bError=FALSE; 
    HMODULE hMyLib; 
    SETUP SetupHook = NULL; 
    UNINSTALL UninstallHook = NULL; 
    
    switch (message) 
    {
    case WM_CREATE:
    		hMyLib = LoadLibrary("KeyHook.dll"); 
        if (hMyLib == NULL) { 
            MessageBox(NULL, "Dll konnte nicht geladen werden!","FEHLER!", MB_OK);  /* Funktion nicht gefunden */ 
    		PostQuitMessage(0); 
        } 
        else
    	{
    		SetupHook = (SETUP)GetProcAddress(hMyLib, "SetupHook"); 
    		if (SetupHook == NULL) { 
    			MessageBox(NULL, "Funktion1 nicht gefunden!","FEHLER!", MB_OK);  /* Funktion nicht gefunden */ 
    			bError=TRUE; 
    		} 
    
    		UninstallHook = (UNINSTALL)GetProcAddress(hMyLib, "UninstallHook"); 
    		if (UninstallHook == NULL) { 
    			MessageBox(NULL, "Funktion2 nicht gefunden!","FEHLER!", MB_OK);  /* Funktion nicht gefunden */ 
    			bError=TRUE; 
    		} 
    		if(bError) PostQuitMessage(0);
    
    		else SetupHook(hwnd);
    	}
    	return 0;
    
    case WM_PAINT: 
        hdc = BeginPaint (hwnd, &ps); 
        EndPaint (hwnd, &ps); 
        return 0; 
    
    case WM_DESTROY: 
        PostQuitMessage (0);
    //	UninstallHook();
    	FreeLibrary(hMyLib); 
        return 0; 
    } 
    
    return DefWindowProc (hwnd, message, wParam, lParam); 
    }
    

    Leider findet GetProcAdress() die Funktionen aus der dll nicht, die Zeiger bleiben immer NULL. Woran könnte das liegen?

    Danke!

    achja, frohes neues 🙂



  • Hast du evtl. die DLL als cpp und nicht als c Datei compiliert? Wobei das eigentlich im Code entsprechend geregelt wird 🙄
    LoadLibrary funktioniert aber noch, oder?! Was bringt GetLastError()?



  • LoadLibrary scheint zu funktionieren, bekomme zumindest keine Fehlermeldung.
    Hatte die Dll als .cpp kompiliert, ich dachte, das wäre bei dem FAQ-Beispiel egal. Wenn ich als .c kompiliere, spuckt der Compiler plötzlich folgende Warnungen aus:

    Kompilierung läuft...
    keyhook.c
    ...\keyhook.c(69) : warning C4047: 'function' : Anzahl der Dereferenzierungen bei 'unsigned long ' und 'void *' unterschiedlich
    ...\keyhook.c(69) : warning C4024: 'SetWindowsHookExA' : Unterschiedliche Typen fuer formalen und uebergebenen Parameter 4
    Linker-Vorgang läuft...
       Bibliothek Debug/KeyHook.lib und Objekt Debug/KeyHook.exp wird erstellt
    

    GetLastError() ergab FehlerNr. 127, "Die angegebene Prozedur wurde nicht gefunden."

    Ich blick das irgendwie nicht, wo liegt der Fehler?



  • Hi, hatte mal das gleiche Problem. Mit W32DSM hab ich herausgefunden, dass der Compiler meine so deklarierte Funktion:

    EXPORT LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam);
    

    unter dem Namen "_ShellHookProc@12" exportiert. Deshalb empfehle ich dir die LIB der Dll zu deinem Projekt zu linken, dann kennt der Linker die Adressen automatisch und du brauchst nicht den Umweg über GetProcAddress zu gehen oder du guckst halt auch nach, unter welchem Namen die Funktionen genau exportiert werden.

    Viel Spaß noch.



  • Ok, danke für den Tipp! Die Funktionen wurden tatsächlich als "_SetupHook@4" und "_UninstallHook@0" exportiert (mit W32DSM herausgefunden). Die Funktionen werden jetzt auch gefunden, nur kann ich sie immer noch nicht benutzen. Beim Aufruf von SetupHook(hwnd) kommt eine Dialogbox mit diesem Text:

    Debug Error!

    Programm: ...\KeyHookExe.exe
    Module:
    File: i386/chkesp.c
    Line: 42

    The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

    Bei Aufruf von UninstallHook():

    Unbehandelte Ausnahme in KeyHookExe.exe: 0xC0000005: Access Violation.

    Wenn ich das richtig verstanden habe, dann stimmt wohl noch etwas nicht mit den definierten Funktionsprototypen. Hab leider noch absolut keine Erfahrung mit dlls und so, kann mir nochmal jemand helfen?



  • Möglicherweise ist da ein kleiner Fehler im Beispiel aus den FAQ (oder das Programm, was die Dll nutz ruft die Funktionen anders auf). Ich kenn mich mit Aufrufkonventionen allerdings kaum aus. Aber versuch mal bei diesem Code(bei dir dürfte das ja ähnlich aussehen)

    EXPORT BOOL CALLBACK SetupHook (HWND hParent){ 
        hWindow = hParent ; 
        // Initialisierung der globalen Variable mit dem Eingabe Parameter 
        hhkHook = SetWindowsHookEx (WH_KEYBOARD, KeyboardHookProc, hDllInstance, NULL) ; 
        // Keyboardhook setzen und das Ergebnis in der globalen Variable 
        // hhkHook speichern. 
        return TRUE ; 
    }
    

    das "CALLBACK" wegzulassen (in der Deklaration entsprechend auch). In der Hook-Proc muss es allerdings bleiben!



  • Vielen Dank, jetzt gehts. Die Funktionen haben nun auch wieder ihren eigentlichen Namen. Bei Funktionsaufruf von UninstallHook() kam zwar nochmal der Ausnahme-Fehler, aber das lag daran, dass

    UNINSTALL UninstallHook = NULL;
    

    natürlich static sein muss.

    bye


Anmelden zum Antworten