Results 1 to 14 of 14
  1. #1
    .::SCHiM::.'s Avatar
    Join Date
    Sep 2010
    Gender
    male
    Posts
    733
    Reputation
    180
    Thanks
    833
    My Mood
    Twisted

    [Source] The jump hook [series part 1]

    The last time we discussed a very basic hook that would only work inside our own application. Today I'm going to show you the basic and universal hook called the jump hook. With the jump hook you can hook functions regardless of size, location, arguments and whether or not it was originally built in your project or not. The only downside to this hook is that most AC programs detect them quite easily. If there's a jump instruction at a location there shouldn't be one: you're caught.

    To follow along:

    *Assembler knowledge is a must if you don't want to only leech the code
    *A debugger or disassembler
    *C++/C or any language that can create dll files and console executables

    Forward note:

    The EIP (Extended Instruction Pointer) points to the instruction that is currently executed. Once the instruction is executed the EPI is advanced to the next instruction. This is how to processor keeps track of where it's working.

    Understanding jumps

    Jump instruction prototype:

    Code:
    JMP IMM32                // imminent operand 32 bit size
    JMP MEM32               // Memory operand 32 bit zie
    JMP REG32                // 32 bit register (eax, ecx, ebx, edx, esp, ebp, esi, edi)
    
    All offsets are relative to the jump location, remember this!
    
    
    Example: 
    
    401000:    JMP 4             // jumps to an address 4 bytes from here
    ...
    401004:                        // Execution will continue here.
    To understand the jump hook we must first understand how the jump instruction works. When the processor encounters a jump instruction it adds the operand (IMM32, MEM32, REG32) to where the EIP is currently pointing. Consider:







    Code:
    Note: The operands to all instructions are in little-endian, this means that you have to read the number(two digits) from right to left.
    
    eg: 00 10 is actually 10 00 and 10 00 00 00 is actually 00 00 00 10 
    
    E9 10 00 00 00
    As you can see the processor adds the offset bytes (see red bold code above, 0x10) to the EIP register which points to the jump instruction being executed.

    If you have any questions about how the JMP instruction works, you can post them below

    The next step

    Now that we know how the jump instruction works, we can advance to the next problem: How do we redirect the Sleep() function to our hook?

    The answer is simple, we must write our jump code to a place were we are 100% sure it's going to be executed if we do that, every call to Sleep() will end in our Hook() >=D

    The best place (where you are 100% sure) is of course the start of the Sleep() function, since every call to Sleep() will start there.

    Every function has only 1 entry point, and all calls will start at this point

    Now that we know where to place our hook, we can start writing code!

    Create two projects, one console project named target and one dll project named hook

    Target:

    Add a file named main.cpp to your project and copy this into it:

    Code:
    #include <iostream>
    #include <windows.h>
    
    int main(){
    
    printf("I'm going to sleep for a long while\n");           // to show us it's working
    
    	while(1){
    	
    		Sleep(1000);                     // this sleep will get executed many times
    
    	}
    
    return 0;
    
    }
    Hook:

    Add a file named main.cpp to your project and copy this into it:

    Code:
    #include <windows.h>
    #include <iostream>
    #include <string.h>
    
    void MainThread();
    
    BOOL APIENTRY DllMain( HANDLE hModule, DWORD  fdwReason, LPVOID lpReserved ){    // main() function inside the dll
    
    	if( fdwReason == DLL_PROCESS_ATTACH){
           CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MainThread, NULL, NULL, NULL);
    	   return TRUE;
    	}
    
        return TRUE;
    }
    
     
    void __stdcall SleepHook(DWORD Timout){								// our hook
    	MessageBox(NULL, "Not sleeping!", "SCHiM", MB_OK);       // display a messagebox instead of sleeping
    	return;
    }                                                            // ret
    
    void DoHook(DWORD* Address, DWORD* Hook){   
    
    	/* 
    	This time it's not as easy as in part 1 where we could just replace one pointer to point at our hook.
            Here we need to replace 5 bytes with our jump code, E9 ** ** ** ** (where ** = offset bytes)
    	Luckily can just place them at the start of the Sleep() function so that we're sure they get executed
    	To do that we first need to change the memory protection so that we can write to it (we can't by default)
    	*/
    
    	DWORD OldProt;     //                        -5 is there because the offset bytes of the jump instruction are relative to the address of the jump instruction, so the 5 bytes (length of the jump instruction) must be subtracted
    	DWORD HookOffset = (DWORD)Hook-(DWORD)Address-5;             // calculate the offset bytes and store the result into hookoffset
    
    	VirtualProtect((void*) Address, 40, 0x40, &OldProt);       // change the memory protection and give us write access.
    
    
    	char* CharPointer = (char*) Address;    // sizeof(char) == 1, 0E9h == 1, we need a char for the size
    
    	*CharPointer = '\xE9';                  // *CharPointer(Sleep()) now equals E9h (the jump opcode)
    											// we now need to place the operands						
    	CharPointer++;                          // the size problem again, incrementing Address (Address++) would result in the pointer advancing 4 bytes
    
    	Address = (DWORD*)CharPointer;		    // Advance the pointer with 1 byte to where the offset bytes need to come
    
    	*Address = 	HookOffset;                 // the correct offset 
    
    	VirtualProtect((void*) Address, 40, 0x40, &OldProt);      // change the memory protection back to the old values (it doesn't really matter if we do this or not, but it's just proper)
    
    return;                       // the hook is set!
    }
    
    
    void MainThread(){		// our main function to work with
    
    DWORD* AddressOfSleep	= (DWORD*) GetProcAddress(GetModuleHandle("Kernel32.dll"), "Sleep");          // get the address of the Sleep() function through the address of kernel32.dll
    
    if( AddressOfSleep == NULL){  // oops
    	MessageBox(NULL, "Could not find the address of Sleep()!", "SCHiM", MB_OK);
    	return;
    }
    
    DoHook( AddressOfSleep, (DWORD*)&SleepHook); // hook it! >;)
    
    
    return;
    
    }
    Compile/build the projects in release mode or something like it, as long as it's not debug mode

    As usual the code is commented to help you understand it, I suggest you read it before compiling/continuing

    If you have any problems with this code or if you don't understand something, post and I'll take a look


    To test this code you run Target.exe and then you inject hook.dll into it. If all is well you should see a MessageBox saying: "Not sleeping!"

    Reentry

    If you've successfully tested the code above, you can continue here for there is yet another problem to be solved. In the code above we only show a MessageBox in our hook before returning. What if we instead want to change the timeout value of sleep and then resume the normal execution flow of the program executing Sleep()?

    We've replaced 5 bytes at the start of the Sleep() function, so we can't just call Sleep() nor can we call Sleep()+5 (skipping the jump) for we have overwritten critical prologue code, without this prologue code the program will crash if you try to execute Sleep().

    This problem is the problem of reentry in all it's glory: You can't know exactly what prologue code you've overwritten so you can't hardcode a solution, nor can you just jump back-in and you can't call it directly either.

    The more absolute readers probably see the way out by now, and there's only one good solution to this problem: we have to save the bytes at the start of the function and execute them before we jump back into the Sleep() function.

    But that isn't the end of our problems, there's one last thing I kept back as to not discourage you at the start of this tutorial. Remember you need a debugger or a disassembler? Well here's why:

    That prologue code I talked about with the Sleep() function? That's also in your Hook(), and in your Main() and in every other function you ever made or used. At the start of a function the prologue code does two things: It pushes the original base pointer to the stack and then moves the current stack pointer to the base pointer. There's also a matching Epilogue code undoing what the prologue code did, it moves the base pointer to the stack pointer, and then pops the previous base pointer from the stack. This Epilogue code is executed right before a Return; statement.

    To keep it simple I'll only tell you about the foremost reason why this is a problem to us: At the end of a function when we Return; the processor thinks that the stack pointer is pointing to the return address. So it can properly return the execution to where it came from. However we're not going to return we're going to jump back into the Sleep() function therefore the epilogue will never be executed. Because of that the stack pointer is NOT pointing at the return address. The function will fail when it's ready to return because it finds that our prologue code is where it's return address should be.

    Luckily we can hardcode our own epilogue code because it will not change from hook to hook (we only have one hook function, remember?)

    Here's how my compiler implements the prologue code:

    Code:
    10001049   55               PUSH EBP
    1000104A   8BEC             MOV EBP,ESP
                                       push ebx
                                       push esi
                                       push edi
    My epilogue code looks like this:

    Code:
                                       pop edi
                                       pop esi
                                       pop ebx
    100010A2   8BE5             MOV ESP,EBP
    100010A4   5D               POP EBP
    You'll have to find how your compiler implements pro/epi code but this is how it generally looks.

    If you have any questions about this section, you should try playing around in a debugger a bit with epilogue/prologue code before asking, because I have the feeling a lot of people won't get this.

    Now that we know what to do with the prologue and epilogue code, lets get back to the source codes!!

    The final step

    hook:

    Just c+p this over the code that is in main.cpp previously

    The green code is specific to my environment, yours may differ. Instructions on how to find your won epilogue code can be found in the "Reentry" section

    Code:
    #include <windows.h>
    #include <iostream>
    #include <string.h>
    
    void MainThread();
    
    DWORD* gPrologPointer;						// this pointer will point at the prologue code of Sleep()
    
    BOOL APIENTRY DllMain( HANDLE hModule, DWORD  fdwReason, LPVOID lpReserved ){    // main() function inside the dll
    
    	if( fdwReason == DLL_PROCESS_ATTACH){
           CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MainThread, NULL, NULL, NULL);
    	   return TRUE;
    	}
    
        return TRUE;
    }
    
     
    void __stdcall SleepHook(DWORD Timout){								// our hook
    	MessageBox(NULL, "Not sleeping!", "SCHiM", MB_OK);       // display a messagebox instead of sleeping
    
    	Timout = 5000;                     // make it sleep longer 5 seconds instead of 1
    
    	__asm{
    
    		pop edi
    		pop esi
    		pop ebx
    		mov esp, ebp    // MY epilogue code, to match MY prologue code, note that this is suited to MY environment, yours may differ
                    pop ebp
    		mov eax, gPrologPointer
    		jmp eax                       // jump to Sleep's prologue code
    	}
    
    
    	return;
    }                                                            // ret
    
    void DoHook(DWORD* Address, DWORD* Hook){   
    
    	/* 
    	This time it's not so easy as in part 1 where we could just replace one pointer.
        Now we need to replace 5 bytes with our jump code, E9 ** ** ** ** (where ** = offset bytes)
    	Luckely can just place them at the start of the Sleep() function so that we're sure they get executed
    	To do that we first need to change the memory protection so that we can write to it. 
    
    	We also need to save the prologue code at the start of the Sleep() function and execute them after our own Epilogue code.
    	Luckily I've done all this for you, and the only thing you have to do is C+P :p
    	*/
    
    	DWORD OldProt;
    	DWORD* OffsetPointer;
    	char* CharPointer;                                          
    
    	gPrologPointer = (DWORD*) new char[10];                   // we only need 10 bytes, sizeof(char) = 1
    	
    	CharPointer = (char*) gPrologPointer;                     // size control again
    
    	memcpy((void*)CharPointer, (void*)Address, 5);            // copy the porlogue code of sleep to our buffer
    
    	CharPointer[5] = '\xE9';                                  // this code will jump from the prologue code to the Sleep() function
    
    	CharPointer += 6;                                         // advance the pointer
    
    	OffsetPointer = (DWORD*)CharPointer;                      // Offsetpointer now points at where to offset bytes need to come 
     
    
    	DWORD JumpTwoOffset = (DWORD)Address-(DWORD)OffsetPointer+1; // no -5 this time, because we want to skip the jump on the other end( jump back into the sleep() not in an endless loop)
    	
    	*OffsetPointer = JumpTwoOffset;                           // fix this jump
    
         VirtualProtect((void*)gPrologPointer, 40, 0x40, &OldProt);     // we need to be able to execute the prologue code
    
    
    
    	     //                        -5 is there because the offset at the jump instruction is relative to the address of the jump instruction, so the 5 bytes (length of the jump instruction) must be substracted
    	DWORD HookOffset = (DWORD)Hook-(DWORD)Address-5;             // calculate the offset bytes and store the result into hookoffset
    
    	VirtualProtect((void*) Address, 40, 0x40, &OldProt);       // change the memory protection and give us write access.
    
    
    	CharPointer = (char*) Address;    // sizeof(char) == 1, 0E9h == 1, we need a char for the size
    
    	*CharPointer = '\xE9';                  // *CharPointer(Sleep()) now equals E9h (the jump opcode)
    											// we now need to place the operands						
    	CharPointer++;                          // the size problem again, incrementing Address (Address++) would result in the pointer advancing 4 bytes
    
    	Address = (DWORD*)CharPointer;		    // Advance the pointer with 1 byte to where the offset bytes need to come
    
    	*Address = 	HookOffset;                 // the correct offset 
    
    	VirtualProtect((void*) Address, 40, 0x40, &OldProt);      // change the memory protection back to the old values (it doesn't really matter if we do this or not, but it's just proper)
    
    return;                       // the hook is set!
    }
    
    
    void MainThread(){		// our main function to work with
    
    DWORD* AddressOfSleep	= (DWORD*) GetProcAddress(GetModuleHandle("Kernel32.dll"), "Sleep");          // get the address of the Sleep() function through the address of kernel32.dll
    
    if( AddressOfSleep == NULL){  // oops
    	MessageBox(NULL, "Could not find the address of Sleep()!", "SCHiM", MB_OK);
    	return;
    }
    
    DoHook( AddressOfSleep, (DWORD*)&SleepHook); // hook it! >;)
    
    
    return;
    
    }
    Overview

    Because this is a daunting scheme I'll post an overview of what's going on here:



    This hasty scrawling of mine should be enough to show you what we're doing here.

    Now to address a question that will be poping up in some of you:

    You may have noticed some hackers doing things like this:

    Code:
    Hook(foo, bar){
    
    foobar = foo;
    bar();
    ...
    ...
    ...
    Return oFoo(foo, bar); 
    }
    What they are doing here is this: They are calling the original (the real) function in the hooked function, and return the return value to the caller.
    This may look simpler and cleaner too you and it probably is, however it's not better because this is more easily detected then our function (which cleans the stack as though it has never been there). If the AC developers have even a slight idea of what they are doing they can check if the all came from the right function (by using the return address). If they see your hook's return address: you're caught!

    Ca is not that good though, so can try this, I knew a few games were this was detected from day 1 however.

    Any questions can be asked as long as they are not too stupid

    -SCHiM

    I'm SCHiM

    Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.

    Polymorphic engine
    Interprocess callback class
    SIN
    Infinite-precision arithmetic
    Hooking dynamic linkage
    (sloppy)Kernel mode Disassembler!!!

    Semi debugger




  2. The Following 14 Users Say Thank You to .::SCHiM::. For This Useful Post:

    -Bl00d- (09-10-2011),ctpsolo (07-11-2011),DareoTheOreo (07-11-2011),Drake (07-13-2011),fakeness (11-30-2011),gunman353 (07-23-2012),[MPGH]Jason (07-16-2011),kibbles18 (07-11-2011),Pronome191 (08-24-2012),seho jeong (05-13-2012),SrNooB (07-12-2011),supercarz1991 (07-12-2011),swatfx (07-11-2011),_Fk127_ (07-12-2011)

  3. #2
    kibbles18's Avatar
    Join Date
    Oct 2008
    Gender
    male
    Location
    US
    Posts
    860
    Reputation
    5
    Thanks
    124
    in the c++ code, why do you have __stdcall? isn't c++ stdcall by defualt?
    Last edited by kibbles18; 07-11-2011 at 03:22 PM.

  4. #3
    Jason's Avatar
    Join Date
    Apr 2010
    Gender
    male
    Location
    /dev/null
    Posts
    5,706
    Reputation
    907
    Thanks
    7,297
    My Mood
    Mellow
    Fan-fucking-tactic. I'm on my iPhone at the moment so I can't see the code properly, but the actual content seemed really well explained. Thanks SCHiM

  5. #4
    ctpsolo's Avatar
    Join Date
    Jan 2010
    Gender
    male
    Posts
    252
    Reputation
    10
    Thanks
    34
    My Mood
    Amused
    Just wanted to say that your tutorials seems awesome so far. I played around with C++ for 3-4 years now and yet I've never really learned how hooks work simply because every tutorial I looked at was so complex and advanced. Just by reading this I was able to follow and understand most of the things you did even though I haven't had a chance to try it out yet. But I will and I think that this time I will finally learn how to do it

    You explain what you're doing very well, keep that up and I really hope to see more tutorials on this!

  6. #5
    DareoTheOreo's Avatar
    Join Date
    Jul 2010
    Gender
    male
    Location
    Under your bed
    Posts
    2,791
    Reputation
    92
    Thanks
    180
    My Mood
    Confused
    dude... you are a-freaking-mazing...
    I've made way to many mistakes... >.<

    If you wish to come in contact with me, please @ mention me, or vm/pm me, or you can email dareon454@yahoo.com
    Dareo's Inject (made by me and Shunnai) : Dareo's Inject
    Dareo's Inject CA Version V1.0 (made by me and Shunnai) : Dareo's Inject CA Version V1.0

  7. #6
    c0ke187's Avatar
    Join Date
    Jan 2011
    Gender
    male
    Posts
    13
    Reputation
    10
    Thanks
    6
    This is good good shit rite here chef-boy-rd yah feel me!

  8. #7
    .::SCHiM::.'s Avatar
    Join Date
    Sep 2010
    Gender
    male
    Posts
    733
    Reputation
    180
    Thanks
    833
    My Mood
    Twisted
    Wow thanks guys, It's very nice to hear that you like it

    @kibbles18

    I believe it is, however for some strange reason my hook crashes if I try to hook sleep with a function not declared as __stdcall, I thought that it couldn't hurt, so that's how it is.

    I'm SCHiM

    Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.

    Polymorphic engine
    Interprocess callback class
    SIN
    Infinite-precision arithmetic
    Hooking dynamic linkage
    (sloppy)Kernel mode Disassembler!!!

    Semi debugger




  9. #8
    supercarz1991's Avatar
    Join Date
    Jul 2010
    Gender
    male
    Location
    North of Hell, South of Heaven
    Posts
    6,067
    Reputation
    323
    Thanks
    3,323
    My Mood
    Doh
    i know i need to go get more ASM and C++ knowledge because even with how well explained this is, i still don't get it lol but still great

    commando: You're probably the best non-coder coder I know LOL


  10. #9
    coogle007's Avatar
    Join Date
    Dec 2009
    Gender
    male
    Posts
    267
    Reputation
    18
    Thanks
    297
    My Mood
    Aggressive
    Yeah. Good Job i understand only the 40% of this but anyway GJ!
    My last Hack D3d Chams/Esp/Opk/Telekill
    A me me piace 'o blues e tutt'e journe aggio cantà'
    pecchè so stato zitto e mo è 'o mumento 'e me sfucà'
    sono volgare e so che nella vita suonerò
    pe chi tene 'e complessi e nun 'e vò
    A me me piace 'o zucchero ca scenne dinto 'o cafè
    e cu 'na presa d'annice ma chi è meglio 'e me
    tengo 'a cazzimma e faccio tutto quello che mi va
    pecchè so blues e nun voglio cagnà'

  11. #10
    .::SCHiM::.'s Avatar
    Join Date
    Sep 2010
    Gender
    male
    Posts
    733
    Reputation
    180
    Thanks
    833
    My Mood
    Twisted
    Quote Originally Posted by coogle007 View Post
    Yeah. Good Job i understand only the 40% of this but anyway GJ!
    That's a start at least

    I'm SCHiM

    Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.

    Polymorphic engine
    Interprocess callback class
    SIN
    Infinite-precision arithmetic
    Hooking dynamic linkage
    (sloppy)Kernel mode Disassembler!!!

    Semi debugger




  12. #11
    SrNooB's Avatar
    Join Date
    Sep 2009
    Gender
    male
    Location
    df
    Posts
    61
    Reputation
    17
    Thanks
    3
    Quote Originally Posted by .::SCHiM::. View Post
    That's a start at least
    may I add you SCHiM?
    @.::SCHiM::.

  13. #12
    .::SCHiM::.'s Avatar
    Join Date
    Sep 2010
    Gender
    male
    Posts
    733
    Reputation
    180
    Thanks
    833
    My Mood
    Twisted
    Quote Originally Posted by SrNooB View Post
    may I add you SCHiM?
    @.::SCHiM::.
    With what? Sure you can add me on mpgh.

    I'm SCHiM

    Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.

    Polymorphic engine
    Interprocess callback class
    SIN
    Infinite-precision arithmetic
    Hooking dynamic linkage
    (sloppy)Kernel mode Disassembler!!!

    Semi debugger




  14. #13
    Departure's Avatar
    Join Date
    Nov 2010
    Gender
    male
    Posts
    818
    Reputation
    125
    Thanks
    1,785
    My Mood
    Doh
    Nice tutorial Shim, I belive once people grasp the basic concept it actually very easy too hook functions directly or indirectly using inline assembly by means of code caves... Anyway excellent job. Also im pretty sure the _Stdcall derives from C code meaning the "_" part. I am not a C or C++ coder so I don't really know, but your tutorial is good for any programming language as it explains the basic concept and methods very well.

  15. #14
    GM-Eric's Avatar
    Join Date
    Jul 2011
    Gender
    male
    Posts
    1
    Reputation
    10
    Thanks
    0
    NICE dude awesome

Similar Threads

  1. [Tutorial] [Source] Hooking ! [Series part 0]
    By .::SCHiM::. in forum Combat Arms Hack Coding / Programming / Source Code
    Replies: 23
    Last Post: 08-03-2011, 07:13 AM
  2. [Tutorial] The basics of Direct3D[Series][Part 1]
    By Hell_Demon in forum C++/C Programming
    Replies: 10
    Last Post: 06-26-2011, 11:23 PM
  3. The Epicness Of Dave: Part II
    By Hyperion in forum Combat Arms Hacks & Cheats
    Replies: 31
    Last Post: 08-12-2008, 02:49 PM
  4. I WANT THE D3D HOOK HACK UPDATED
    By n4m3l3ss in forum Spammers Corner
    Replies: 5
    Last Post: 11-01-2007, 03:45 PM
  5. Lina Inverse, The Slayer. (DotA Series.)
    By August2007 in forum Art & Graphic Design
    Replies: 9
    Last Post: 10-22-2007, 04:32 AM