Mid Function Hook
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...
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.
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 Draw2D 
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.
Regards
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:
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...
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:
Code:
PlaceJMP((BYTE*)0x430430, (DWORD)hkDraw2D, 6);

With this our hook is almost done. We just need to write our hooked Draw2D now

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

