pe of a function. Or if we need speed and want to access the data fast through specific registers, or just need to synchronize with the game as soon as the function is called and do our stuff there.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void placeJMP(BYTE * address, DWORD jumpTo, DWORD length) { DWORD oldProtect, newProtect, relativeAddress; VirtualProtect(address, length, PAGE_EXECUTE_READWRITE, &oldProtect); relativeAddress = (DWORD) (jumpTo - (DWORD) address) - 5; *address = 0xE9; *((DWORD *)(address + 0x1)) = relativeAddress; for(DWORD x = 0x5; x < length; x++) { *(address + x) = 0x90; } VirtualProtect(address, length, oldProtect, &newProtect); } Now, we have to see which instructions to overwrite/where to write our jump. And remember: We need to save the instructions we are going to overwrite and use them in our hooked function (you may also not break any instruction into separate parts), so the program flow won't get interrupted with any corrupt data or messed stack.. Generally patching 6 bytes we'll be enough, I'll be patching 10 bytes in this example, to be more precise, I'll be overwriting: |
1 2 3 |
00640BF1 8B41 18 MOV EAX,DWORD PTR DS:[ECX+0x18] // 3 bytes 00640BF4 D940 28 FLD DWORD PTR DS:[EAX+0x28] // 3 bytes 00640BF7 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+0x4] // 5 bytes Now what I need to know is that I'll be jumping from 0x00640BF1 to my function and returning to 0x00640BFB, because that's where the next instruction will be at.. Lets write our function: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
DWORD myData = 0; // just something i'll be using for this example DWORD retJMP = 0x00640BFB; __declspec(naked) void myMidfuncHook() // __declspec(naked) says to the compiler that we will worry about the prolog/epilog/return of the function { __asm mov eax,dword ptr ds:[ecx+0x18] // do what we overwrote __asm fld dword ptr ds:[eax+0x28] __asm mov edx,dword ptr ss:[esp+0x4] // do what you want now, i'll obtain data from EBX register, for example, and store it for later use __ asm mov myData, ebx /*//if you want to do any other calls to other functions, etc and don't need the registers/stack anymore push it //for example: __asm pushad // push all general registers __asm pushfd // push all flags // do your stuff here.. calls, calculations.. // remember, you can't do everything in a naked function, it's limited.. // see: http://msdn.microsof*****m/en-us/libr...=vs.80%29.aspx //restore stack/registers, so we don't corrupt any data and program flow continues as it should __asm popfd __asm popad */ // return where we left off __asm jmp [retJMP] } |
1 2 |
placeJMP((BYTE*)0x00640BF1, (DWORD)myMidfuncHook, 10); // 10 - length to overwrite |