Felt like I haven't contributed for a while, been busy, and didn't see that covered here on the site so here it is. Something for people new to hooking
When I first started using hooks, I began with mid function hooks. I suppose writing mid function hooks and reversing at the same time explains (makes it easier to understand) the whole process of hooking a lot better than just hooking some API calls with detours. Anyhow, hopefully you know some C++ and Assembly..
When do we(I) use it? - Mainly when some parts of a function are being scanned by anticheats, while other parts are not and we want to exploit them. Or when we can't make up the parameters/type 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.
So, I assume you are familiar with reverse engineering and found the function you want to hook. The function I'll be hooking is at 0x00640BF1 and looks like this in Olly:
I am especially interested in the contents of EDX register after the first three opcodes have done their job..
Now what we have to do is place a jump instruction somewhere in the function, so it jumps to our function, does what we want, and then jumps back and continues where it left off. We will do that by patching some instructions with a jump to our function. This is the function I'll be using for that (it will make our life easier because we don't have to manually calculate the length of jump):
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:
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:
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
__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: https://msdn.microsoft.com/en-us/library/4d12973a%28v=vs.80%29.aspx
//restore stack/registers, so we don't corrupt any data and program flow continues as it should
// return where we left off
__asm jmp [retJMP]
Now in your injected DLL hook it like that:
placeJMP((BYTE*)0x00640BF1, (DWORD)myMidfuncHook, 10); // 10 - length to overwrite
If you've done everything correctly, your hook should be working as it should.. Just remember the most common holes when using this are corrupting stack or overwriting instructions in a wrong place and not actually saving them.
And that's pretty much all there is to it, to the midfunction hooking, have fun lads