Tutorial Call Instruction Hooking

Hexui Undetected CSGO Cheats PUBG Accounts


Dank Tier VIP
Jul 15, 2018

Something that people haven't realised about the Coronavirus is the health scare has driven down the cost of hookers and cocaine massively (seriously). If you've ever wanted to try to try hookers and blow now is a really good time to get your feet wet. But sadly in this tutorial we're going to be looking at something not nearly as cool call instruction hooking.

So generally what people will do when hooking for the first time is use something called a mid function hook and a trampoline. So for example say we have our function that we want hook and it looks something like this:


Pretty straight forward it's a x64 program adjusting the value of an int32 value (the entity health). So the instruction we're interested in is the sub eax instruction. Because typically dying with cheats enabled is considered poor form to most game hackers.

In a mid function hook we'd overwrite part of the function like this:


Then in our hook function / trampoline we'd restore the bytes that we overwrote and/or modify the entity health.

So something like this:

inc eax, dword [var_ch]
The problem is this method can be messy. I'm not exactly sure why this method gets passed around more than a $4 hooker in Bangkok but its definitely not something you want to be doing unless you're damn sure you specifically need it.

The better way:

Call Instruction Hooking

Much like how hooking noobs will drive around looking for tang hooking pros know they should use an agency. While hooking noobs will use midfunction hooks, hooking pros know that it's the right tool for the job. Sometimes simplicity and elegance works out better. My general rule when editing programs is modifying as few bytes as possible, in fact it's a bit of a game to me. What's the fewest number of bytes I can change to get the desired effect.

What we're talking about is modifying the CALL instruction some advantages of this method are:
  1. No requirement for trampoline.
  2. No requirement for additional bytes.
  3. Hooking under specific circumstances.
I used this type of hook for my Timb3rium Wars project if you're interested in a practical example.

How to do it:

So using our previous Entity TakeDamage function, we go back in the disassembly and find the location where it gets called from:


So at offset 0x0001168 we see our call instruction E8 25 00 00 00.

So the calculation for modifying a call instruction is as follows:

The function we want to call - (Current Instruction Address) - 5.

So using our example:

Hook_TakeDamage (0x00001179) - (0x00001168) - 5 = C

Why subtract 5? Because that's the instruction length of the call instruction: E8 25 00 00 00 (5 bytes).

We can check this by editing 0x25 to 0x0C and seeing if it now points to the correct address:


And this is what our hook function looks like:


We're just calling the original function from inside our hook.

If you're playing at home you'll recall we only patched a single byte to install our hook. Simple, clean and effective.
Last edited by a moderator:


No hack no life
Dank Tier VIP
Dank Tier Donator
Oct 31, 2013
Oh boy seems @timb3r is now offering same day delivery on tutorials <3

Thanks for your tutorial. I still do have a couple of questions though:

1. Did you compile this bitch AMD64? Since all these calls seem to be AMD64 __fastcalls?
2. Our hook function has this additional void* argument to pass "thispointer" right?
3. Since we are using an actual function signature and no declspec (naked) crap I assume I can just define it in source like so?
void Hook_TakeDamage(void* arg1, int arg2)


    int damage = arg2;

    damage /= 2;

    //Do what I want
    //but pray that my code doesnt fuk up imporant regisers such as RDI????


4. How do I ensure that my c++ code doesnt fuck up other registers that originalTakeDamage() might expect to hold a certain value? Especially since I can't just inline asm pushfd -> popfd in VS for x64 projects.
5. Can you add the full source of this project? I know you linked Timb3erium wars as an example but would be cool to have the exact corresponding project.

My attempt to do the hooking would have been to jmp to a trampoline using shellcode
JMP [RIP+0] aka <--- 0xff 0xeb 0x88 0x77 0x66 0x55 0x44 0x33 0x22 0x11
in the trampoline pushing all registers in a fixed order (and adjust rsp) then calling my

void __fastcall hookedFunc(struct x64Registers* regs)


    //Do whatever I want

    int damage = regs->esi;

   //can only write to pointers since every register gets restored after

Then popping all the registers registers before doing a JMP [RIP+0] back to the original function. All but definition of hookedFunc in shellcode.
Is there any reason that wouldnt work besides the cancer of setting the shellcode stub up once?

I do that for void __fastcall hookedFunc(struct x86Registers* regs) but there ofc I dont need shellcode

edit: also am I stupid or will this method require my hooked function to be within +- 2gb of address of original call? (RIP + 4byte relativ offset)
I thought the whole problem with x64 is that you want to be able to hook an 8byte offset. Why don't I used regular x86 detour 0xe8 JMP for x64 hooking?
What if my .dlls functions are not within 2gb of orgininal function or if I use the JMP method and VirtualAlloc gives me a page that is too far away?
Last edited:


I'm not your friend
Jan 21, 2014
This premium section post has been released to the public, donate if you would like early access to our content
  • Like
Reactions: BroBRo
Community Mods