WinApi hooken?



  • nehmen wir mal an es handelt sich um SetCurserPos

    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    BOOL WINAPI __stdcall SetCursorPosA(int x, int y);
    DWORD DLLFunc;
    
    int main()
    {
    	Sleep(2000);
    	HINSTANCE hInst = LoadLibrary(TEXT("user32.dll"));
        DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;  
    	bool somebool = SetCursorPosA(0, 0);
    
    	return 0;
    }
    
    BOOL WINAPI __stdcall SetCursorPosA(int x, int y)
    {
       __asm
       {
          mov  edi, edi
          push ebp
          mov  ebp, esp
          jmp [DLLFunc]
       }
    }
    

    Warum crashed das programm?



  • tester312 schrieb:

    BOOL WINAPI __stdcall SetCursorPosA(int x, int y)
    {
       __asm
       {
          mov  edi, edi
          push ebp
          mov  ebp, esp
          jmp [DLLFunc]
       }
    }
    

    Warum crashed das programm?

    Hi,
    ich würd behaupten das, dass Problem is das du bei jmp ein Offset angeben musst und nicht die Adresse die du z.B. von GetProcAddress() bekommts.
    Und das Offset wäre: Ziel-Absprung.
    Desweiteren wird doch ,wenn du das so machst, der Prolog deiner Funktion + der Prolog von SetCursorPos aufgerufen. Das sollte au nicht so gut sein.
    Schreib lieber statt:

    BOOL WINAPI __stdcall SetCursorPosA(int x, int y)
    

    was zumal sowieso komisch is da ja WINAPI nur ein #define für __stdcall ist,

    BOOL __declspec(naked) SetCursorPosA(int x, int y)
    

    Somit haste kein Prolog und es sollte funktionieren.

    Gruß Pingu



  • 'SetCursorPosA': 'naked' kann nur auf nicht-Memberfunktionsdefinitionen angewendet werden



  • #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    DWORD DLLFunc;
    BOOL __declspec(naked) SetCursorPosA(int x, int y)
    {
        __asm
       {
          mov  edi, edi
          push ebp
          mov  ebp, esp
          jmp [DLLFunc]
       }
    }
    
    int main()
    {
    	Sleep(2000);
    	HINSTANCE hInst = LoadLibrary(TEXT("user32.dll"));
        DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;  
    	SetCursorPosA(0, 0);
    
    	return 0;
    }
    

    Es funktioniert jetzt, die Funktion wird ausgeführt, aber danach Crashed das Programm noch



  • Pingu-Group schrieb:

    ich würd behaupten das, dass Problem is das du bei jmp ein Offset angeben musst und nicht die Adresse die du z.B. von GetProcAddress() bekommts.
    Und das Offset wäre: Ziel-Absprung.

    !!



  • was meinst du mit Ziel- Absprung? Ich verstehe nicht ganz was gemeint ist



  • tester312 schrieb:

    was meinst du mit Ziel- Absprung? Ich verstehe nicht ganz was gemeint ist

    00411113 /E9 D8060000       JMP muh.mainCRTStartup //dieser Jump springt von 0x00411113 nach 0x004117F0 und nicht nach D8060000
    ....
    004117F0 \8BFF              MOV EDI,EDI
    

    Sprich:
    Offset = Ziel - Absprung

    Also musst du das Offset angeben das im "Little-Endian-Format" angegeben ist, was ich auch erst vor ein paar Tagen erfahren hab ;).

    Gruß Pingu



  • danke, ich verstehe wo das Problem liegt aber
    Offset = Ziel - Absprung
    Ziel = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;
    Absprung = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
    Offset = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5; - DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
    ich denke nicht, dass das so gemeint war?



  • tester312 schrieb:

    danke, ich verstehe wo das Problem liegt aber
    Offset = Ziel - Absprung
    Ziel = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;
    Absprung = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
    Offset = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5; - DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
    ich denke nicht, dass das so gemeint war?

    Noe nicht ganz.
    Also Ziel ist korrekt, aber Absprung ist ja:
    SetCursorPosA + länge der Opcodes bist jmp [DLLFunc] + 5 für die länge des Opcodes jmp

    Deswegen is bei meinem Bspl.

    Ziel: 004117F0
    Absprung: 00411118

    Offset: D8060000 //Little Endian

    Wenn nicht klar dann schau mal den Thread hier an:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-230718.html

    Gruß Pingu



  • SetCursorPosA + länge der Opcodes bist jmp [DLLFunc] + 5 für die länge des Opcodes jmp

    Absprung = (DWORD)GetProcAddress(hInst, "SetCursorPosA") + opcodes + 5

    was sind die länge der Opcodes?



  • Also entweder kannste ned lesen oder du verstehst due Grundlagen nicht!?

    In beiden Fällen rate ich dir lass es einfach!



  • also als erstes, ein einfachs +5 tuts nicht. das verschiebt den offset um
    5 * sizeof(funcptr) = 20 bytes. zuerst nach char casten

    der offset wird vom folgenden befehl aus gerechnet

    quelle = newfunc + 5 + 5
    ziel = func + 5

    ziel - quelle = func - newfunc - 5

    edianprobleme hatte ich auf meinem intel x86 nicht 😛
    hab aber auch das ganze DWORD reinkopiert also nicht byteweise

    musste aber n bissel ruumprobierenbis das aufs byte genau passt, ober von
    obriger formel sollte man ausgehen. (disassembly im debugmodus > all)

    morgen guck ich nochmal den genauen wert nach



  • helferlein schrieb:

    edianprobleme hatte ich auf meinem intel x86 nicht 😛
    hab aber auch das ganze DWORD reinkopiert also nicht byteweise

    Also beim schreiben in Inline Assembly war des bei mir au keine Problem, aber beim auslesen eines jmp + Offset eines Prozesses, siehe verheriger Link, wusste ich nicht wo der hinspringt wegen dem Little-Endian-Format und kommte somit meine Funktion nicht patchen.

    Gruß Pingu



  • wie gehört es sich denn richtig?



  • helferline ich habe es so gemacht wie du gesagt hast:

    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    DWORD DLLFunc;
    BOOL __declspec(naked) SetCursorPosA(int x, int y)
    {
        __asm
       {
          mov  edi, edi
          push ebp
          mov  ebp, esp
          jmp [DLLFunc]
       }
    }
    
    int main()
    {
        Sleep(2000);
        HINSTANCE hInst = LoadLibrary(TEXT("user32.dll"));
    	HINSTANCE hInst2 = GetModuleHandle(0);
        DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + (char)5 - (DWORD)GetProcAddress(hInst2, "SetCursorPosA") + (char)5 + (char)5;  
        SetCursorPosA(0, 0);
    
        return 0;
    }
    

    Aber jetzt führt es nichtmal mehr die funktion aus



  • hier nochmal der vorherige code

    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    DWORD DLLFunc;
    BOOL __declspec(naked) SetCursorPosA(int x, int y)
    {
        __asm
       {
          mov  edi, edi
          push ebp
          mov  ebp, esp
          jmp [DLLFunc]
       }
    }
    
    int main()
    {
        Sleep(2000);
        HINSTANCE hInst = LoadLibrary(TEXT("user32.dll"));
        DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;  
        SetCursorPosA(20, 20);
    	Beep(2000, 200);
    	cout << "lol";
    	Sleep(1000);
        return 0;
    }
    

    Alles funktioniert einwandfrei SetCursorPos wird auch ausgeführt und Beep usw auch, erst bei return 0; crashed es. Darauf zeigt der Debugger:
    00344A78 or byte ptr [edx+34h],0
    wie kann etwas bei return 0 crashen oO



  • man schonmal was von nem debugger gehört -wenn du schon solche hässliche frickelei machst, dann debugg den schrott gefälligst selbst 👎



  • ich hab schon den debugger benützt:
    00344A78 or byte ptr [edx+34h],0
    aber das sagt mir nichts



  • Frickel mal richtig:

    BOOL __stdcall __declspec (naked) SetCursorPosA (int x, int y)
    

    Ohne "__stdcall" frickelt der Kompiler noch ein

    PUSH        14
    PUSH        14
    CALLN   FRICKEL.SetCursorPosA
    ADD         ESP,+08 ; <- :open_mouth:
    

    nach dem Funktionsaufruf hinzu, was dann den Stack durcheinanderfrickelt.



  • oberfrickel schrieb:

    BOOL __stdcall __declspec (naked) SetCursorPosA (int x, int y)
    

    Das __stdcall muss denke ich nach __declspec (naked) sonst geht es nicht.
    Falls du kein __stdcall haben willst, kannst du den Stack auch wieder in Ordnung bringen:

    __asm
    	{
    		mov  esp, ebp 
    		pop ebp
    	}
    

Anmelden zum Antworten