Well, I'm bored as hell now, so I decided to do something useful and write this down...
First of all, if you don't have a good understanding of C++ and ASM. Don't bother reading the rest of this...
Well, if you're still reading that means you do know C++/ASM so let's get started
Let's begin with our hooking function, it's pretty straight foward:
This function will place a JMP to dwJumpTo at the pAddress. dwLen is the byte count we're gonna overwrite...Code:void PlaceJMP(BYTE *pAddress, DWORD dwJumpTo, DWORD dwLen){ DWORD dwOldProtect, dwBkup, dwRelAddr; // Basic VirtualProtect... y'all should know this VirtualProtect(pAddress, dwLen, PAGE_EXECUTE_READWRITE, &dwOldProtect); // Calculate the "distance" we're gonna have to jump - the size of the JMP instruction dwRelAddr = (DWORD) (dwJumpTo - (DWORD) pAddress) - 5; // Write the JMP opcode @ our jump position... *pAddress = 0xE9; // Write the offset to where we're gonna jump *((DWORD *)(pAddress + 0x1)) = dwRelAddr; // Overwrite the rest of the bytes with NOPs for(DWORD x = 0x5; x < dwLen; x++) *(pAddress + x) = 0x90; // Restore the default permissions VirtualProtect(pAddress, dwLen, dwOldProtect, &dwBkup); }
For this example, and since I'm a CoD hacker.. we're gonna hook CG_Draw2D. ALso, we're gonna be using TeknoMW3 (1.4.382) offsets if you want to try it yourself
On 1.4.382 Version, the CG_Draw2D function is located at 0x430430 and its assembly looks like this:
For this tutorial we're gonna hook the beginning of the function, but you can easily hook at any place...
So let's take the first 3 instructions, they will be the instructions we're gonna overwrite...
if we look at the opcode, those 3 instructions use a total of 6 bytes. We need a minimum space of 5 bytes to do a Mid Function Hook (the size of the JMP) so that is ok.Code:push esi mov esi, [esp + 4 + arg_0] push esi
push esi = 1 (56)
mov esi, [esp + 4 + arg_0] = 4 (8B 74 24 08)
push esi = 1 (56)
So we know the dwLen that we're gonna use on our PlaceJMP function will be 6. Therefore, the call of the PlaceJMP will be like this:
Where hkDraw2D will be our hooked Draw2DCode:PlaceJMP((BYTE*)0x430430, (DWORD)hkDraw2D, 6);
With this our hook is almost done. We just need to write our hooked Draw2D now
And that's all. Hope this can be useful to someone. Any comment would be really appreciated. Thanks to learn_more and his original tutorial that helped me understand Mid Function Hooks and be able to write this.Code:DWORD dwJMPback = 0x430436; //The Jump Back address is where we're gonna return after our hooked function ends. //0x430430 is where we're gonna hook... 6 is the length. 0x430430 + 6 = 0x430436 __declspec(naked) void hkDraw2D(){ __asm PUSHAD //Push general registers onto the stack __asm PUSHFD //Push EFLAGS Register onto the stack //Do ya Hax magicz here :P __asm POPFD //Pop EFLAGS Register off the stack __asm POPAD //Pop registers off the stack //Here we have to write the intructions we have overwritten with our JMP __asm PUSH ESI __asm MOV ESI, [ESP + 8] __asm PUSH ESI //Now we jump back to the rest of the function //So the game can keep executing without issues :D __asm JMP [dwJMPback] }
Regards
Last edited by MarkHC; 10-03-2012 at 01:58 AM.
CoD Minion from 09/19/2012 to 01/10/2013
Gotta start looking in this section more often.
Found this through google
Thx bro. (y) Coding god.
Hey, i know this post is old, but i wanted to ask you something bout it.
When you do
PlaceJMP((BYTE*)0x430430, (DWORD)hkDraw2D, 6);
In particular (DWORD)hkDraw2D
what exactly are you doing? ive tried it in my own code, and it says some kind of identificator missing error. Thx in advance!
Last edited by abuckau907; 10-20-2013 at 06:49 AM.
'Some things that can be counted, don't matter. And some things that matter, can't be counted' - A.E.
--