Results 1 to 1 of 1
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    [C++] Writing your own detour functions

    I was gonna show nightghost how to make a detour func, but i might as well write it here so others can use it

    Some constants:

    #define JMP32_SZ 5 // the size of JMP <address>
    #define NOP 0x90 // opcode for NOP
    #define JMP 0xE9 // opcode for JUMP


    First thing you need to understand - to write a jump in binary it is NOT a simple case of doing: JMP <addr> in bytes!
    To jump to the right address you must do:

    address = (place_we_want_to_jump_to + start_of_memory_where_jump_is_at) - size_of_a_jmp_address

    So lets say we want to jump to 0x12345678 and the jump is at 0x55555555:

    address = (0x12345678 + 0x55555555) - JMP32_SZ

    We need a pointer to the original, the hook, and the length:
    void *DetourApply(BYTE *orig, BYTE *hook, int len)
    {
    DWORD dwProt = 0;

    Next we allocate a place in memory for the bytes we are going to overwrite in the original, plus the size of a jump <address> instruction:

    BYTE *jmp = (BYTE*)malloc(len+JMP32_SZ);

    Next we want to allow read & write access to the memory at the original function, and save the previous access to dwProt:

    VirtualProtect(orig, len, PAGE_READWRITE, &dwProt);

    Next we want to copy the bytes of original + length to the allocated memory place:

    memcpy(jmp, orig, len);

    Next we want to insert a jump back to the original + length at the end of those intructions we just copied over:
    	jmp += len; // increment to the end of the copied bytes
    jmp[0] = JMP;
    *(DWORD*)(jmp+1) = (DWORD)(orig+len - jmp) - JMP32_SZ;

    For good practice we want to NOP out all the bytes at the original that we have saved to the memory allocated place:

    memset(orig, NOP, len);

    Now we want to write a jump at the original to the hooked function:

    orig[0] = JMP;
    *(DWORD*)(orig+1) = (DWORD)(hook - orig) - JMP32_SZ;

    Next we want to put back the old protection flags:

    VirtualProtect(orig, len, dwProt, 0);

    And finally we want to return a pointer to the start of the memory allocated place (we incremented the pointer by length, so now we do jmp - length)
    Code:
    return (jmp-len);
    }[/c]
    Ok now what if we want to remove the detour? Well we have the original bytes copied to that memory allocated place so its a simple case of copying the bytes from there back to the original
    void DetourRemove(BYTE *orig, BYTE *jmp, int len)
    {
    DWORD dwProt = 0;
    VirtualProtect(orig, len, PAGE_READWRITE, &dwProt);
    memcpy(orig, jmp, len);
    VirtualProtect(orig, len, dwBack, 0);
    }


    Example:
    DWORD dwLoadLibraryAddr = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dl  l"), "LoadLibraryA");
    o_LoadLibraryA = (LoadLibraryA_t) DetourApply((BYTE*) dwLoadLibraryAddr, (BYTE*)h_LoadLibraryA, 5);

    DetourRemove((BYTE*) dwLoadLibraryAddr, (BYTE*)o_LoadLibraryA, 5);

    by Sinner
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •