WinApi hooken?



  • profilier dich hier nicht helferlein. wenn er so eine frage noch stellen muss, kriegt er es doch eh nicht hin.



  • vielen Dank helferlein! Ich bin echt von deinem Wissen beindruckt.
    das Problem ist jetzt, woher soll mal vorher wissen welchen Prozess man öffnen muss bzw. welcher Prozess schädliche WinApi calls machen würde?
    Oder muss man dass dann in jeden Prozess machen der da ist?



  • ja aber wozu soll das gut sein. ich sehe keinen sinnvollen grund soetwas zu tun.



  • ja aber wozu soll das gut sein. ich sehe keinen sinnvollen grund soetwas zu tun.

    hey wer klaut da mein nickname 😡

    Tobi5 schrieb:

    das Problem ist jetzt, woher soll mal vorher wissen welchen Prozess man öffnen muss bzw. welcher Prozess schädliche WinApi calls machen würde?
    Oder muss man dass dann in jeden Prozess machen der da ist?

    eigentlich musst du jeden prozess infizieren, der diese funktion auf dein programm
    aufrufen könnte.
    kannst ja eine tabelle mit "harmlosen" prozessen anlegen z.b. explorer.exe oder
    winlogon.exe

    alles andere wird infiziert 😃 (guck mal hier für ein beispiel)

    warum soll ers nicht hinkriegen nur weil er danach fragt?
    so kann man das nie lernen, fragen ist gut !

    da gibbet auchnoch einen guten Artikel in dem die grundlagen gut beschrieben sind.

    MfG helferlein



  • ok thx 🙂
    gibt es eigentlich auch eine möglichkeit sich davor zu schützen?
    Ich meine dann könnte man ja jedes Programm flachlegen. Wenn ja wie?



  • das ganze klappt nicht bei jedem prozess und als nicht-admin bei nochweniger.

    schützen kannst du dich in dem du jede! funktion der api vor dem aufruf
    auf einen sprung überprüfst, der ja mit dem opcode 0xE9 anfängt.

    template <class T>
    bool isFuncOk(T funcptr)
    {
        char *addr = reinterpret_cast<char *>(funcptr);
        return *addr != 0xE9;
    }
    

    gibt aber bestimmt noch andere sprünge außer far-call die das selbe ermöglichen



  • und falls es herausfindet, dass es die Funktion nicht ok ist(gehookt ist) wie kann ich das bypassen?



  • oh man denk doch mal nach!
    Wenn die ersten 5 Bytes überschrieben wurden,
    dann führe diese manuell aus und springe dann zu dem Funktion Offset + 5 Bytes.
    Du öffnest also Olly und suchst nach der WinApi Funktion in den DLLs.
    Nimm die ersten 5 Bytes kopiere sie in dein Programm (Inline Asm) und mach nen jump hin zu der Funktion +5 bytes.



  • ich verstehe nur bahnhof



  • helferlein schrieb:

    das ganze klappt nicht bei jedem prozess und als nicht-admin bei nochweniger.

    schützen kannst du dich in dem du jede! funktion der api vor dem aufruf
    auf einen sprung überprüfst, der ja mit dem opcode 0xE9 anfängt.

    template <class T>
    bool isFuncOk(T funcptr)
    {
        char *addr = reinterpret_cast<char *>(funcptr);
        return *addr != 0xE9;
    }
    

    gibt aber bestimmt noch andere sprünge außer far-call die das selbe ermöglichen

    das ist doch quartsch es gibt jawoll viele möglichleiten api hooking zu betrieben stichwort IAT und viele andere



  • ganz einfach:

    die ersten 5 byte der funktion wurde überschrieben und durch einen farcall
    ersetzt, also dem opcode für den sprung an deine eigene funktion.

    sämtliche funktionen der winapi nutzen die stdcall aufrufkonvention. diese
    funktionen beginnen aufgrund der konvention immer mit den selben 5 bytes.

    push ebp
    mov ebp, esp
    sub esp, xx

    (xx steht für die größe aller lokalen variablen)

    diese wurden überschrieben. um die funktion dennoch aufrufen zu können,
    muss man diese selber ausführen, z.b. mit inline-assembler

    __declspec(naked) DWORD callfunc(void * func) // verhindert dass der kompiler den funktionsprolog hinzufügt
    {
        char *addr = reinterpret_cast<char *>(func) + 5; // 5 bytes weiter
        __asm
        {
            mov ebx, addr // hier speichern wir die addresse
            push ebp
            mov ebp, esp
            sub esp, xx // !!
            jmp ebx
        }
    }
    

    hier haben wir allerdings ein problem, denn wir wissen nicht wieviele variablen
    die funktion auf den stack legt.

    wenn wir zuwenig nehmen überschreiben wir die rücksprungaddresse und den framepointer.
    wenn wir zuviel nehmen, kann es sein dass das selbe problem auftrifft,
    es kann aber auch sein, dass der wert von ebp genommen wird statt die selbe
    größe wieder auf den esp zu addieren. hier weiß ich nicht genau wie die
    winapi das macht, ich befürchte beide versionen gibt es.

    lässt sich bestimmt auch lösen, aber dazu müsste man die funktion
    disassemblieren und ....

    aber ich weiß nicht ob dir das viel bringt, da du die grundlagen verstanden
    haben musst. was dein letzer post nur bestätigt.

    guck dir mal die links an und versuch alles zu verstehen.

    edit:

    klempfner schrieb:

    es gibt jawoll viele möglichleiten api hooking zu betrieben stichwort IAT und viele andere

    es war nur ein beispiel. natürlich gibt es noch viele andere möglichkeiten 🙂



  • helferlein schrieb:

    sämtliche funktionen der winapi nutzen die stdcall aufrufkonvention. diese
    funktionen beginnen aufgrund der konvention immer mit den selben 5 bytes.

    push ebp
    mov ebp, esp
    sub esp, xx

    (xx steht für die größe aller lokalen variablen)

    Aber dann hät ich da mal ne Frage:

    Warum hat dann z.B. FindNextFileW diese ersten 12Bytes:

    6A 2C             PUSH 2C
    68 C8F0807C       PUSH kernel32.7C80F0C8
    E8 0035FFFF       CALL kernel32.7C8024D6
    

    Zumindestens laut Olly?

    Gruß Pingu



  • weil's nur'n stub is 💡



  • 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


Anmelden zum Antworten