Video Tutorial Mid function hooking

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
12,638
76
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):


C++:
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:


C++:
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:


C++:
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: 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
    __asm popfd
    __asm popad
     */

    // return where we left off
    __asm jmp [retJMP]
}

Now in your injected DLL hook it like that:

C++:
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 ;)
 

Szaka

Coder
Full Member
Nobleman
Mar 14, 2013
161
718
3
c5 u have time and teamviewer/skype? To clarify some things?
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,375
78,998
2,414
Hey c5,

Thank you for posting this useful information. I've never come around to try it and I am trying it at the moment and I must say. It's working like a charm. Thank you for this!


~ Magnificient
 

Szaka

Coder
Full Member
Nobleman
Mar 14, 2013
161
718
3
how can i make hook to msgbox which will change lets say text inside it?
 

Radobot

Newbie
Full Member
Dec 5, 2012
13
182
0
Is there a way to hook a function into an external hack? I mean hooking without injecting DLL.
 

Szaka

Coder
Full Member
Nobleman
Mar 14, 2013
161
718
3
Works with some slight modifications ;]
Good to begin with hooking
 

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
12,638
76
Is there a way to hook a function into an external hack? I mean hooking without injecting DLL.
Sure there is, use some sort of an assembler for that (for the sake of simplicity), there are a few good libraries. Getting the data itself would already be another thing.
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,750
41,528
319
how did you determine the first line was 3bytes , second 3bytes and final 5bytes
Count the bytes:
Address ----- Bytes ---------- Instruction
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

Any disassembler will show you both the opcodes and the bytes.
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods