[Source] Hooking ! [Series part 0]

Posts 115 of 24 · Page 1 of 2
[Source] Hooking ! [Series part 0]
So, since most of you are an uneducated lot, I'll teach/show you (you can leech ) how to hook functions and how hooks work. I'll provide working source code samples, but in some cases you'll have to adapt it to your own environment. In that case I'll show you what to look for. Maybe I'll make it into a series of tutorials, since there's a lot of depth (if not width) to the subject.

Since we'll start form the ground up, this part may not be very interesting to the average/adept hacker. Those people I promise that more advanced (and far more advanced) tutorials are on their way

For starters

To follow along you'll need:

*a debugger
*Cpp/C/ASM/anything (I'll do this tutorial in Cpp so I recommend any C++ compiler, if you want to use any other language you're on your own)

You must understand:

*Assembler and raw instructions/opcodes
*C++/C code

or Wikipedia and Google...

a definition I just made up:

Hooking is the act of detouring or otherwise altering the flow of execution inside a program. Hooking is often used to update programs or (in our case) to use/change information used by the program that was not intended to be Used/Changed.

Environment

First I'll give you the source of our test program. This is the program we're going to place our hooks into:

make a new console project, and add main.cpp

Code:
#include <iostream>

int main(){

	return 0;
}
Now that is done we can begin taking our baby steps towards our goal in this tutorial: Building a basic api hook.

The next step

In this part of the series we're going to hook a windows api function (the sleep function to be more exact). Sleep() delays execution in your threads for a given time. After that Sleep() returns and execution resumes.


msdn:
Suspends the execution of the current thread until the time-out interval elapses
prototype:

Code:
VOID WINAPI Sleep(
  __in  DWORD dwMilliseconds
);
Here's an example of the sleep function:
Copy and paste the bold parts into your main.cpp file and compile or run it

Code:
#include <iostream>
#include <windows.h>

int main(){


printf("Sleeping for 2 seconds!\n");
Sleep(2000);   // sleep is in milliseconds therefore 2000 = 2 seconds
printf("Done sleeping!\n");

std::cin.ignore();
	return 0;
}
Try to compile this, if it fails post your errors and I'll take a look.

Now this is still far from being a hook but at least we can see our target now. To actually hook the Sleep() function, we need to understand what's going on inside the program. And that's why we need a debugger.

This is how the call to the Sleep() function looks inside a debugger (olly)


As you can see in the image, a WinApi function is called like this:

Code:
call dword ptr[address]
This simply means that that function is called through a pointer. Consider this pseudo c++/asm code:

Code:
DWORD* mypointer = Sleep(); // mypointer = the address of the sleep function
*mypointer() // this simply means: call what mypointer points to.
Now that we know that using Sleep() simply calls a pointer, and that that pointer is stored in our program. The next step towards a hook is clear! The only thing we have to do now is changing this pointer so that it points to where we want it to. If we do that successfully our basic hook is set!

To do this we need a little assembler, don't worry I've commented what is going on in the source code. And this is the only bit of assembler you'll have to use this time:

Copy and paste the bold parts into our main.cpp file and compile or run it

Code:
#include <iostream>
#include <windows.h>


void __stdcall hook(DWORD Timeout){   

	/*
	since the caller (the one with the Sleep() in his code) does not know that the function is hooked
	We have access to all the arguments that the function has. We can change and display them before passing on execution,
	or we can even prevent the function from being executed!
	*/

	printf("No rest for the wicked! not even %d seconds!\n",(int) (Timeout/1000));  // display the timeout in milliseconds

return;  // we wont execute the Sleep() function at all, No rest for the wicked!
}

void DoHook(DWORD* func, DWORD* hook){

/*
Here *func (what func points to) still points to the address of sleep.
We however, don't want it to point there, we want it to point to our hook function.
Therefore we're going to change it, this can be done without any modifications to our virtual memory access.
Because the pointers are kept in our .data section, and we have write permission in our .data section.
*/

	*func = (DWORD) hook;      // change what *func points to, remeber that func is the same pointer as used in the call dword[addfress] instruction.                
	return;

}

int main(){

	DWORD* Func;

printf("Sleeping for 2 seconds!\n");
Sleep(2000);   // sleep is in milliseconds 1/1000th second therefore 2000 = 2 seconds
printf("Done sleeping!\n");

__asm{
lea eax, Sleep           // note: lea = Load Extended Address		 moving the address of the pointer to eax
mov Func, eax			 // note: mov = Move 					     now we have the address of the pointer in Func
}


DoHook(Func, (DWORD*)&hook);                       // now detour Sleep()!

printf("Sleeping for 3 seconds!\n");
Sleep(3000);
printf("Done sleeping!\n");

std::cin.ignore();
	return 0;
}
Try to compile this, if it fails post your errors and I'll take a look.

If this program compiles correctly you should see the message:

"No rest for the wicked!'

Appearing on your screen instead of your program waiting three seconds before continuing.

prologue

I do realize that this is not a usefully hook, quite the contrary actually since hack and game alike probably use the sleep function extensively. Not to mention we're not even inside another application at the moment. However this is the easiest way to start I think, and this doesn't involve allot of weird code and hackerisch glue between functions.

If you have any (smart) questions about the code you can post them and I am sure that I or another will answer them.

If you feel like you don't understand any of this, maybe this is still too hard for you. Try programming some basic applications before returning to game hacking.

The future

Although I've referred to a series of tutorials about hooking, I'm not yet completely sure If I'm actually going to write the series or not. I probably will, but don't expect me to post them in any regular pattern of time

-SCHiM
in asm, can't you simply call the address? like
Code:
call [address]
? or am i wrong?
Quote Originally Posted by kibbles18 View Post
in asm, can't you simply call the address? like
Code:
call [address]
? or am i wrong?
call [address] == call dword ptr[address]

or did you mean:

call address?

That second you can't do in assembler.

Call, imm32

Expects an offset and not an absolute address.
sorry my question was a bit off topic. let me rephrase it. if i had a function i found at address 12345, in asm, couldn't i call that function using
Code:
call dword ptr [12345h]
or would i just call the address without derefrencing it? like
Code:
address db 12345h
call [address]
and more on topic:
stdcall is the specifier of how parameters are passed, right?
sometimes i see cdecl or something like that. what does this mean? someone told me it means i have to increase the stack pointer (esp) by 4 * the number of arguments passed (push'd)
Quote Originally Posted by kibbles18 View Post
sorry my question was a bit off topic. let me rephrase it. if i had a function i found at address 12345, in asm, couldn't i call that function using
Code:
call dword ptr [12345h]
or would i just call the address without derefrencing it? like
Code:
address db 12345h
call [address]
Yes that is valid however this: call dword ptr [12345h] will translate to:

say 0x12345 = 401000

call 401000

instead of call 12345h (so not the address 12345 will be called but rather the address that 12345 points to/holds)

I get the feeling I'm being a little vague here, if you want to understand this better, try opening olly and do it by hand. You'll understand it the instant olly shows you what you're doing.
Good Tutorial. (:
ok so instead of calling the address pointed to by 0x12345, i should just call the address by doing
Code:
call dword ptr ds:12345h
?
im trying to relate this to asm, because im trying to do things in assembly.
i think that's what i want, because the function starts at 12345h, not whatever 12345 points to.
Quote Originally Posted by kibbles18 View Post
ok so instead of calling the address pointed to by 0x12345, i should just call the address by doing
Code:
call dword ptr ds:12345h
?
im trying to relate this to asm, because im trying to do things in assembly.
i think that's what i want, because the function starts at 12345h, not whatever 12345 points to.
If you're unsure how a certain cpp code translates to asm there's only one way to find out Just compile the cpp and run it through an disassembler or debugger and you're on your way. Olly even knows the debug information generated by my compiler, so I can see exactly which part of the code I'm currently debugging.
Thanks, This can be used to hook drivers. Like NtOpenProcess
think this should be sticky?
might help a few people out
Thanks for the TuT Schim, was just thinking I should learn how to hook sometime. Just one question though, how do you continue the original execution after the hook completes.

I.e, say we've got Sleep hooked, what if we didn't want to stop the function working, just do something prior to every sleep, but then continue as normal, how would I set the function back on track? Can i just set the pointer back to the original function's address after my code is finished? Or is there a neater way?
Quote Originally Posted by Jason View Post
Thanks for the TuT Schim, was just thinking I should learn how to hook sometime. Just one question though, how do you continue the original execution after the hook completes.

I.e, say we've got Sleep hooked, what if we didn't want to stop the function working, just do something prior to every sleep, but then continue as normal, how would I set the function back on track? Can i just set the pointer back to the original function's address after my code is finished? Or is there a neater way?
If you still want to use the original function you must save the correct pointer to the sleep function before changing it. In combination with using function pointers, you can make it as though you've never hooked the function:

Code:
// as global:
typedef void (__stdcall * OSleep)(DWORD Timout);   // declare a function pointer.
OSleep MySleep;      // MySleep will replace Sleep() as our real sleep function
....
....      // in main:
__asm{
lea eax, Sleep           // note: lea = Load Extended Address		 moving the address of the pointer to eax
mov Func, eax			 // note: mov = Move 					     now we have the address of the pointer in loc 
}

MySleep = (OSleep)*Func;				// the real address of sleep, also this way all the other calls remain hooked, so we don't have to worry about missing calls

DoDetour(Func, (DWORD*)&hook);
....
....  // inside our hooked sleep function:

	printf("No rest for the wicked! not even %d seconds!\n",(int) (Timeout/1000));  // display the timeout in milliseconds

	MySleep(Timeout);   // so sleep
return;  // we wont execute the Sleep() function at all, No rest for the wicked!
Hmm, been trying to figure out how to do it with a non-winapi function...can you do it somehow using GetModuleHandle and GetProcAddress? I was trying it for sleep, but no luck.
Quote Originally Posted by Jason View Post
Hmm, been trying to figure out how to do it with a non-winapi function...can you do it somehow using GetModuleHandle and GetProcAddress? I was trying it for sleep, but no luck.
Only reason this works with sleep like that is because it's called through a pointer, if the game or w/e you're hooking doesn't use a pointer to call the function this will pretty much be useless.

If the function is exported you could do an IAT/EAT hook, if it's not exported you'll probably want to use a JMP(0xE9) hook, a VTable hook if it's a virtual function, INT3(0xC3) hook(exception hook), cause an exception using debug registers, NULL pointer hooks(set a pointer used somewhere in the function to NULL(implying they're not checking it for NULL values) and use the exception to fix up

So many different hooking methods :3
Excuse me sir, May you do more of these.
I bookmarked this cause I am still being frustrated with D3d and Win32 :\; haven't even touched ASM yet, BUT in time i will get there
Posts 115 of 24 · Page 1 of 2
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Need help?