I\'m injecting a c++ DLL into a game and I\'d like to hook a function to some of my own code. Since the DLL is mapped to a different location each time, It would be easier t
I never tried this kind of things,
but I think you should use the offset from a known memory location of the game (to find with ollydbg) so every time you add this (fixed) offset to the (variable) address. This address could be, for example, the return address found at ss:ebp
(since your function is called by the game) and the offset from that is computed with help of ollyDBG.
You can code it like this (gcc-style / AT&T assembly syntax):
jmp *.Ltgtaddr
.Ltgtaddr: .long absoluteAddrOfFunctionToCall
This assembles into ten bytes (on 32bit x86) - ff 25
for the absolute jmp with 32bit memory operand, then the four bytes with the address of the following word, followed by the contents which then is the (absolute) target address of your code.
Edit: I've updated the section below with a compiled and tested example.
You can, from C sourcecode, dynamically create such a trampoline. Example source (requires 32bit x86, left as an exercise to the reader how to convert the trampoline to 64bit):
#include <sys/mman.h>
#include <stdio.h>
void oneWay(char *str, int arg)
{ printf("string is \"%s\", int is %d\n", str, arg); }
void otherWay(char *str, int arg)
{ printf(str, arg); printf("\n"); }
void *trampGen(void *tgtAddr)
{
char *trampoline = mmap(NULL, 10, PROT_EXEC | PROT_WRITE | PROT_READ,
MAP_PRIVATE | MAP_ANON, -1, 0);
trampoline[0] = (char)0xff; trampoline[1] = (char)0x25;
*(char**)(trampoline+2) = trampoline + 6;
*(void**)(trampoline+6) = tgtAddr;
return trampoline;
}
int main(int argc, char **argv)
{
void * (*funcptr)(char*, int) = trampGen(oneWay);
*funcptr("Test %d String", 12345);
*(void **)(((char *)funcptr) + 6) = otherWay;
*funcptr("Test %d String", 12345);
munmap(funcptr, 10);
return 0;
}
Output for me:
$ ./tt
string is "Test %d String", int is 12345
Test 12345 String
Note it's slightly inefficient to set aside an entire MMU page to use only ten bytes of it. Implement your own memory manager for trampolines if you need more than one of them ...