+ Antworten
Seite 1 von 2
1 2 LetzteLetzte
Ergebnis 1 bis 10 von 20

Thema: Detours - Was ist das und wie geht das?

  1. #1
    Guru of NOTHING steeno ist ein sehr geschätzer Mensch steeno ist ein sehr geschätzer Mensch steeno ist ein sehr geschätzer Mensch
    Registriert seit
    25.02.2007
    Ort
    Hessen
    Beiträge
    417
    Power
    6

    Detours - Was ist das und wie geht das?

    halihalo sehr geehrte leser,
    heute nehmen wir mal das thema detours ein wenig durch.
    zu aller erst wollen wir mal schauen was das überhaupt ist.

    hier ist ein kleines beispiel eines programmes wie es in assembler aussieht:

    Code:
    7C801D77 > 8BFF             MOV EDI,EDI
    7C801D79   55               PUSH EBP
    7C801D7A   8BEC             MOV EBP,ESP
    7C801D7C   837D 08 00       CMP DWORD PTR SS:[EBP+8],0
    7C801D80   53               PUSH EBX
    7C801D81   56               PUSH ESI
    7C801D82   74 14            JE SHORT kernel32.7C801D98
    theoretisch intercepted eine detour einen funktionsaufruf, fängt ihn so gesehen ab und leitet ihn um.
    praktisch gesehen wird also meistens eine jmp instruction an das erste byte der funktion geschrieben, mit darauf folgender adresse. wodurch wir insgesamt auf 5 bytes kommen die überschrieben werden. jedoch muss man häufig auch noch ein paar bytes mehr mit nop's überschreiben, da man ansonsten irgendeinen befehl zur hälfte überschreibt.

    also würde die funktion in asm jetzt so aussehen:

    Code:
    7C801D77 E9 ADRESSE JMP ADRESSE
    7C801D7C   837D 08 00       CMP DWORD PTR SS:[EBP+8],0
    7C801D80   53               PUSH EBX
    7C801D81   56               PUSH ESI
    7C801D82   74 14            JE SHORT kernel32.7C801D98
    an der adresse zu der wir springen, können wir jetzt irgendeinen code ausführen, müssen jedoch bevor wir zurück zur original adresse ( + 5 bytes, wollen ja nicht nochmal unsere zwischengeschobene funktion aufrufen -> endless loop ) noch die opcodes, sprich die befehle ausführen die wir überschrieben haben. dies würde dann in etwas so aussehen:

    Code:
    5C801D77 > 8BFF             MOV EDI,EDI ; überschrieben opcodes
    5C801D79   55               PUSH EBP
    5C801D7A   8BEC             MOV EBP,ESP
    7C801D7C   E9 ORIGADDRESSE       JMP ORIGADRESSE ; jmp back zur orig. adresse + 5 bytes
    doch genug zur theorie, jetzt folgt ein beispiel wie man eine funktion in c schreiben kann, die genau dies für uns tut.

    zuerst alloziieren wir uns ein wenig speicher für unser gateway im betroffenen prozess. dafür verwenden wir virtualalloc. die funktion hat 4 parameter, der erste ist die startadresse. dort können wir getrost 0 eingeben.
    der zweite gibt an wieviel platz wir benötigen, in dem fall wäre das die größe der überschriebenen bytes + 5 bytes für die jmp instruction zur orig. funktion.
    der dritte parameter ist der typ der speicher alloziation.
    dort hätten wir einmal mem_reserve, womit wir uns ein wenig virtual speicher des prozesses reservieren und dann mem_commit womit wir den speicher mit 0 memsetten. der vierte parameter ist der protection typ des speicherbereiches, bzw. der page. dort benutzen wir PAGE_EXECUTE_READWRITE.
    wenn die funktion failed gibt sie 0 zurück, ansonsten die adresse des reservierten speichers. um genauere infos über den grund warum die funktion einen fehler verursacht hat zu bekommen, sollte man sich anschauen was getlasterror für einen fehler index ausspuckt.

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    }
    joah, dann holen wir uns read und write rechte für die bytes die wir überschreiben möchten. wir kopieren die bytes erstmal an die adresse unseres gateways. dafür benutzen wir entweder memcpy ( wenn man context intern arbeitet, z.b. mit einer geladenen dll ) oder readprocessmemory und writeprocessmemory ( wenn man z.b. aus einer externen application eine detour setzt ). in diesem beispiel mache ich es mit memcpy, da es einfach eine zeile weniger code ist .
    aber zuerst müssen wir wie gesagt die rechte setzen. dazu benutzen wir virtualprotect. hier gibt es wieder 4 parameter, der erste gibt die adresse an von der aus beginnend die speicherrechte geändert werden sollen. jedoch ist davon dann die ganze page betroffen. der zweite gibt wiederrum die menge der bytes an die betroffen sind, falls diese z.b. in eine zweite page reichen ist diese auch komplett davon getroffen. der dritte parameter gibt den protection typ an und der vierte gibt den alten, sprich den aktuellen protection typ zurück. wenn die funktion failed gibt diese widerum auch 0 zurück.

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    DWORD dwOldProtection = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenOpcodes, PAGE_READWRITE, &dwOldProtect ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    }
    jetzt verwenden wir memcpy um die originalen opcodes in unser gateway zu kopieren. hier gibt es 3 parameter. der erste gibt die source adresse an, der zweite die destination adresse und der dritte die anzahl der bytes die kopiert werden sollen.

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    DWORD dwOldProtection = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenOpcodes, PAGE_READWRITE, &dwOldProtect ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    memcpy( dwAddressOfFunctionToIntercept, dwReserveMemorySpace, dwNumberOfOverwrittenBytes );
    }
    gut da wir unser gateway nun mit den originalen opcodes gefüllt haben, schreiben wir die jmp instruction zur originalen funktion hinter den code den wir eben reinkopiert haben. da man allerdings mit relativen adressen arbeiten muss, müssen wir dazu eine kleine berechnung benutzen.
    diese sieht wie folgt aus -> adressewohingesprungenwird - minusadressevonderweggesprungenwird.
    in dem beispiel arbeite ich mit pointern, man kann dazu aber auch genauso gut memcpy oder writeprocessmemory benutzen.

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    DWORD dwOldProtection = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenOpcodes, PAGE_READWRITE, &dwOldProtect ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    memcpy( dwAddressOfFunctionToIntercept, dwReserveMemorySpace, dwNumberOfOverwrittenBytes );
    //jmp opcode [E9]
    *( PBYTE )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes ) = 0xE9;
    //im debugger würde das nun wie folgt aussehen:
    //0xADRESSE orig opcode;
    //0xADRESSE3 orig opcode;
    //0xADRESSE5 orig opcode;
    //0xADRESSE7 jmp;
    //jetzt folgt die angabe der adresse an die gesprungen werden soll, dafür benutzen wir die berechnung wie ich sie vorhin erklärt habe
    *( PDWORD )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes + 0x1 ) = ( ( dwAddressOfFunctionToIntercept + dwNumberOfOverwrittenBytes ) - ( dwReservedMemorySpace + dwNumberOvOverwrittenBytes + 0x5 ) );
    //einige werden sich sicher fragen warum da jetzt 5 bytes dazuadiert werden, das liegt einfach daran, das der jmp erst am ende ausgeführt wird, sprich nach der letzten ziffer der adressenangabe. und da ein jmp 1 opcode ist und eine adresse aus 4 bytes besteht, ist der sprung punkt 5 bytes weiter.
    //im debugger schaut das nun so aus:
    //im debugger würde das nun wie folgt aussehen
    //0xADRESSE 235253 origopcodes;
    //0xADRESSE3 2351 origopcodes;
    //0xADRESSE5 3452 origopcodes;
    //0xADRESSE7 e9 23456321 jmp relativadresse;
    }
    jetzt können wir auch gleich den funktionsaufruf ansich umleiten, dazu gehen wir genau wie bei unserem gateway jmp vor.

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    DWORD dwOldProtection = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenOpcodes, PAGE_READWRITE, &dwOldProtect ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    memcpy( dwAddressOfFunctionToIntercept, dwReserveMemorySpace, dwNumberOfOverwrittenBytes );
    //jmp opcode [E9]
    *( PBYTE )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes ) = 0xE9;
    //im debugger würde das nun wie folgt aussehen:
    //0xADRESSE orig opcode;
    //0xADRESSE3 orig opcode;
    //0xADRESSE5 orig opcode;
    //0xADRESSE7 jmp;
    //jetzt folgt die angabe der adresse an die gesprungen werden soll, dafür benutzen wir die berechnung wie ich sie vorhin erklärt habe
    *( PDWORD )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes + 0x1 ) = ( ( dwAddressOfFunctionToIntercept + dwNumberOfOverwrittenBytes ) - ( dwReservedMemorySpace + dwNumberOvOverwrittenBytes + 0x5 ) );
    //einige werden sich sicher fragen warum da jetzt 5 bytes dazuadiert werden, das liegt einfach daran, das der jmp erst am ende ausgeführt wird, sprich nach der letzten ziffer der adressenangabe. und da ein jmp 1 opcode ist und eine adresse aus 4 bytes besteht, ist der sprung punkt 5 bytes weiter.
    //im debugger schaut das nun so aus:
    //im debugger würde das nun wie folgt aussehen
    //0xADRESSE 235253 origopcodes;
    //0xADRESSE3 2351 origopcodes;
    //0xADRESSE5 3452 origopcodes;
    //0xADRESSE7 e9 23456321 jmp relativadresse;
    //HOOK!!!!!!!!!!!!!!!
    //jmp instruction setzen
    *( PBYTE )dwAddressOfFunctionToIntercept = 0xE9;
    //rva berechnen und setzen
    *( PDWORD )( dwAddressOfFunctionToIntecept + 0x1 ) = ( dwAddressOfFunctionToJmp - ( dwAddressOfFunctionToIntercept + 0x5 ) );
    }
    so jetzt kann es vorkommen, das wenn man einen befehl z.b. zur hälfte überschreibt, das wir die restlichen opcodes noch mit nops belegen müssen.
    dazu können wir eine einfache forschleife verwenden:

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    DWORD dwOldProtection = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenOpcodes, PAGE_READWRITE, &dwOldProtect ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    memcpy( dwAddressOfFunctionToIntercept, dwReserveMemorySpace, dwNumberOfOverwrittenBytes );
    //jmp opcode [E9]
    *( PBYTE )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes ) = 0xE9;
    //im debugger würde das nun wie folgt aussehen:
    //0xADRESSE orig opcode;
    //0xADRESSE3 orig opcode;
    //0xADRESSE5 orig opcode;
    //0xADRESSE7 jmp;
    //jetzt folgt die angabe der adresse an die gesprungen werden soll, dafür benutzen wir die berechnung wie ich sie vorhin erklärt habe
    *( PDWORD )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes + 0x1 ) = ( ( dwAddressOfFunctionToIntercept + dwNumberOfOverwrittenBytes ) - ( dwReservedMemorySpace + dwNumberOvOverwrittenBytes + 0x5 ) );
    //einige werden sich sicher fragen warum da jetzt 5 bytes dazuadiert werden, das liegt einfach daran, das der jmp erst am ende ausgeführt wird, sprich nach der letzten ziffer der adressenangabe. und da ein jmp 1 opcode ist und eine adresse aus 4 bytes besteht, ist der sprung punkt 5 bytes weiter.
    //im debugger schaut das nun so aus:
    //im debugger würde das nun wie folgt aussehen
    //0xADRESSE 235253 origopcodes;
    //0xADRESSE3 2351 origopcodes;
    //0xADRESSE5 3452 origopcodes;
    //0xADRESSE7 e9 23456321 jmp relativadresse;
    //HOOK!!!!!!!!!!!!!!!
    //jmp instruction setzen
    *( PBYTE )dwAddressOfFunctionToIntercept = 0xE9;
    //rva berechnen und setzen
    *( PDWORD )( dwAddressOfFunctionToIntecept + 0x1 ) = ( dwAddressOfFunctionToJmp - ( dwAddressOfFunctionToIntercept + 0x5 ) );
    //nops setzen?!?!
    for( DWORD dwNOP = 0x5; dwNOP < dwNumberOfOverwrittenBytes; dwNOP += 0x1 )
    {
    //opcode von nop ist 90
    *( PBYTE )( dwAddressOfFunctionToIntercept + dwNOP ) = 0x90;
    }
    }
    letzten endes setzen wir wieder die originalen speicherrechte und returnen die adresse des gateways, damit wir dieses im späteren verlauf aufrufen können um die originale funktion ohne unsere detour zu callen.

    Code:
    DWORD dwDetourFunction( DWORD dwAddressOfFunctionToIntercept, DWORD dwAddressOfFunctionToJmp, DWORD dwNumberOfOverwrittenOpcodes )
    {
    char szErrorLog[256];
    DWORD dwReservedMemorySpace = 0x0;
    DWORD dwOldProtection = 0x0;
    
    dwReservedMemorySpace = ( DWORD )VirtualAlloc( 0, ( dwNumberOfOverwrittenOpcodes + 0x5 ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if( dwReservedMemorySpace == NULL )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualAlloc failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenOpcodes, PAGE_READWRITE, &dwOldProtect ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    memcpy( dwAddressOfFunctionToIntercept, dwReserveMemorySpace, dwNumberOfOverwrittenBytes );
    //jmp opcode [E9]
    *( PBYTE )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes ) = 0xE9;
    //im debugger würde das nun wie folgt aussehen:
    //0xADRESSE orig opcode;
    //0xADRESSE3 orig opcode;
    //0xADRESSE5 orig opcode;
    //0xADRESSE7 jmp;
    //jetzt folgt die angabe der adresse an die gesprungen werden soll, dafür benutzen wir die berechnung wie ich sie vorhin erklärt habe
    *( PDWORD )( dwReservedMemorySpace + dwNumberOfOverwrittenBytes + 0x1 ) = ( ( dwAddressOfFunctionToIntercept + dwNumberOfOverwrittenBytes ) - ( dwReservedMemorySpace + dwNumberOvOverwrittenBytes + 0x5 ) );
    //einige werden sich sicher fragen warum da jetzt 5 bytes dazuadiert werden, das liegt einfach daran, das der jmp erst am ende ausgeführt wird, sprich nach der letzten ziffer der adressenangabe. und da ein jmp 1 opcode ist und eine adresse aus 4 bytes besteht, ist der sprung punkt 5 bytes weiter.
    //im debugger schaut das nun so aus:
    //im debugger würde das nun wie folgt aussehen
    //0xADRESSE 235253 origopcodes;
    //0xADRESSE3 2351 origopcodes;
    //0xADRESSE5 3452 origopcodes;
    //0xADRESSE7 e9 23456321 jmp relativadresse;
    //HOOK!!!!!!!!!!!!!!!
    //jmp instruction setzen
    *( PBYTE )dwAddressOfFunctionToIntercept = 0xE9;
    //rva berechnen und setzen
    *( PDWORD )( dwAddressOfFunctionToIntecept + 0x1 ) = ( dwAddressOfFunctionToJmp - ( dwAddressOfFunctionToIntercept + 0x5 ) );
    //nops setzen?!?!
    for( DWORD dwNOP = 0x5; dwNOP < dwNumberOfOverwrittenBytes; dwNOP += 0x1 )
    {
    //opcode von nop ist 90
    *( PBYTE )( dwAddressOfFunctionToIntercept + dwNOP ) = 0x90;
    }
    //speicherrechte wiederherstellen
    if( VirtualProtect( dwAddressOfFunctionToIntercept, dwNumberOfOverwrittenBytes, dwOldProtect, new DWORD ) == 0 )
    {
    sprintf( szErrorLog, "dwDetourFunction -> VirtualProtect failed -> GetLastError: %d", GetLastError( ) );
    MessageBoxA( GetForegroundWindow( ), szErrorLog, "ERROR", MB_ICONERROR | MB_OK );
    return 0x0;
    }
    //whats that ?
    TerminateProcess( GetCurrentProcess( ), 0 );
    return dwReservedMemorySpace;
    }
    und hier ist noch ein kleines anwendungsbeispiel für einen loadlibrarya hook:

    Code:
    //typedefs erstellen
    typedef HMODULE ( WINAPI* LoadLibraryA_Typedef )( LPCTSTR lpFileName );
    LoadLibraryA_Typedef LoadLibraryA_Gate = 0;
    
    //function die wir anstelle der echten loadlibrarya funktion callen
    HMODULE WINAPI LoadLibraryA_Detour( LPCTSTR lpFileName );
    {
    //mache iwas mit params oder so
    //aufruf der originalen loadlibrarya
    return ( *LoadLibraryA_Gate )( lpFileName );
    }
    
    //hooken der loadlibrarya funktion mit unserer detourfunction funktion
    //brauch ansich nur einmal gecalled zu werden, zumindest je nachdem wie der target prozess dies handled
    HANDLE hKernel32 = GetModuleHandle( "kernel32.dll" );
    LoadLibraryA_Gate = ( LoadLibraryA_Typedef )dwDetourFunction( GetProcAddress( hKernel32, "LoadLibraryA" ), &LoadLibraryA_Detour, 0x5 );
    if( LoadLibraryA_Gate == 0 )
    {
    MessageBox( GetForegroundWindow( ), "CRITICAL ERROR, CANT HOOK LOADLIBRARYA, TERMINATING PROCESS", "BURNITLIKEFIRE", MB_ICONERROR | MB_OK );
    TerminateProcess( GetCurrentProcess( ), 0 );
    }
    ihr könnt den code so nicht zu 100% übernehmen, da ihr einige typecast errors bekommt und sich der prozess in dem ihr dies anwendet sofort schließen würde. will damit nur sicherstellen das ihr das grundprinzip auch einigermaßen verstanden habt.
    der code ist auch nicht getestet worden, hab ihn einfach frei hand mit hilfe vom msdn und ein paar überlegungen niedergeschrieben.
    er sollte aber 100% gehen, da das prinzip ansich klar ist. es könnte wie gesagt nur ein paar compiler errors geben, z.b. wegen schreibfehlern oder den besagten typecasts.
    und es gibt auch das eine schmankerl mit dem terminierenden prozess

    demnächst gibts ein paar sachen zu iat und eat hooking.

    doch jetzt muss klein steeno erstmal ins bettele

  2. Die folgenden 9 Benutzer haben sich bereits bedankt:


  3. #2
    Benutzer 2young4nick befindet sich auf einem aufstrebenden Ast
    Registriert seit
    18.01.2007
    Beiträge
    76
    Power
    4
    Ich steh mehr auf Video tuts aber auch schön geschrieben mal sehn wann mein c++ und Co wieder geht und ich Zeit finde das zu testen
    Zitat Zitat von Phil
    Achja: Die Scene braucht wohl keine Programmierer mehr, die Leute stehen mittlerweile eh mehr auf Hexeditoren.

  4. #3
    <3 Avril Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Gordon genießt hohes Ansehen Avatar von Gordon
    Registriert seit
    18.01.2007
    Ort
    Wien
    Beiträge
    1.172
    Power
    57
    gut erklaert, respekt

  5. #4
    * seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen
    Registriert seit
    18.01.2007
    Beiträge
    1.321
    Power
    77
    Jop, gut erklärt. Auch wenn ein paar Begriffe ohne asm-Verständnis vielleicht unklar sein könnten. Beispielsweise "jmp instruction" oder "nop".

    Trotzdem sollte ein Jeder das Prinzip verstehen können.
    Gute Arbeit.

    Edit: Steht ja eh unter "Advanced", da sollte man die Instructions sowieso kennen ^^
    Geändert von seren1ty (15.08.2007 um 08:50 Uhr)

  6. #5
    sidious DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein Avatar von DeepBlueSea
    Registriert seit
    09.03.2007
    Beiträge
    447
    Power
    16
    Erwähnenswert vlt. noch, dass es sich hierbei um Simple Code Overwriting handelt. Es gibt noch zig mehr Methoden zu hooken.

  7. #6
    Erfahrener Benutzer Sharon befindet sich auf einem aufstrebenden Ast
    Registriert seit
    28.01.2007
    Beiträge
    183
    Power
    0
    Sehr gute Arbeit!!!
    Bitte benutzt auch mal die Thanks Butten hat er sich verdient!

  8. #7
    Benutzer Patrick befindet sich auf einem aufstrebenden Ast
    Registriert seit
    28.05.2007
    Beiträge
    54
    Power
    4
    gj steeno, Detours können aber auch einfach Verkehrsumleitungen sein :P

  9. #8
    Guru of NOTHING steeno ist ein sehr geschätzer Mensch steeno ist ein sehr geschätzer Mensch steeno ist ein sehr geschätzer Mensch
    Registriert seit
    25.02.2007
    Ort
    Hessen
    Beiträge
    417
    Power
    6


    ? ^^

  10. #9
    * seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen seren1ty genießt hohes Ansehen
    Registriert seit
    18.01.2007
    Beiträge
    1.321
    Power
    77
    Zitat Zitat von steeno Beitrag anzeigen
    demnächst gibts ein paar sachen zu iat und eat hooking.
    Dann mach ich HW BPs ^^

  11. #10
    sidious DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein DeepBlueSea kann auf vieles stolz sein Avatar von DeepBlueSea
    Registriert seit
    09.03.2007
    Beiträge
    447
    Power
    16
    Dann darf nochjemand Inline SEH nehmen, Relocation Hook, Pageguard Hook und TrapFlag Hook.
    Geändert von DeepBlueSea (15.08.2007 um 16:03 Uhr)

+ Antworten

Lesezeichen

Berechtigungen

  • Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
  • Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
  • Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
  • Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.