[C++] Writing your own detour functions
by Sinner
Some constants:
#define JMP32_SZ 5 // the size of JMP
#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
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:
1 2 3 | 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 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:
1 2 3 | 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
1 2 3 4 5 6 7 | 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:
1 2 3 4 | 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); |
0 comentarios:
Publicar un comentario