Wednesday, June 22, 2011

The way to hook

The following post is a bit more technical then usual, so my apologies for my none-pirate friends. Hooking is the art of altering code in memory to introduce new functionality to an existing program. I won’t be discussing all the uses that might be found for hooking, but rather the different techniques for doing so. In general there are four common ways to implement a hook function under Windows platforms.
  1. Windows standard hooking API. 
  2. Detours technique 
  3. AIT hooks, AKA Rechter’s hooks 
  4. Dll proxy 
I’ll cover these briefly in this post. After that I’ll tell the reader about my small and insignificant addition to method number three. All of the methods are well covered in Ivo Ivanov’s codeproject page http://www.codeproject.com/KB/system/hooksys.aspx
The more general principle of what hooking really is, is covered in Wikipedia http://en.wikipedia.org/wiki/Hooking
So I won’t dive into details, as it would take much more than a single blog post to cover just the simplest of the four.

#1
The windows standard hooking is the somewhat official way to write hooks, and is part of the Win32 APIs. The main functions to look for in the MSDN is SetWindowsHookEx, and it’s all well covered in the following MSDN link:
(http://msdn.microsoft.com/en-us/library/ms644959%28v=vs.85%29.aspx).
If you are looking for a way to hook Windows Messages or Intercept those, this might be your way to go.

#2
Detours are the idea of injecting a small piece of code to the beginning of a function to jump to other place in memory and execute the code from there, before going back and executing the original function. The main problem with this method, is that in the injection process we have to overwrite a small part of the original function, and then we have to recover it in the “detour” function.
Microsoft provides us with a nice library to automate the detours injection, and recovering of the deleted code with their Detours library http://research.microsoft.com/en-us/projects/detours/
Other detours projects:
Easyhook:
A. http://easyhook.codeplex.com/
B. http://code.google.com/p/easyhook-continuing-detours/
This method is also good for performance testing and other debugging issues.
BTW: Microsoft like this method so much that they introduced a compiler flag that makes sure we would have a room for injecting our detour. If the flag is set, the compiler would add the “mov edi, edi” opcode to the beginning of every function, and some extra free space between every two functions. Detouring becomes very easy when working on a program that has been compiled with the flag.

#3
First introduced by the great Jeffrey Richter, and well documented with simple source code in his book “Windows via C/C++” http://www.wintellect.com/cs/blogs/jeffreyr/archive/2008/03/14/windows-via-c-c-table-of-contents.aspx. The principle behind this method is changing the Import Address Table (IAT) of a DLL / EXE, to prefer different functions from the ones it’s supposed to. The code samples from Jeffrey’s book are available at http://wintellect.com/Books.aspx. This technique is very strong for hooking at run-time. Best combined with DLL preload (AppInit_DLLs). A good usage example is presented in the following blog post: http://www.the-interweb.com/serendipity/index.php?/archives/2-Skinmine-Elaborating-on-Jeffrey-Richters-Trojan-DLL-method-for-API-hooking.html
Note: There is a very similar method on most *nix platforms called LD_PRELOAD.

#4
Create a DLL with the same name as the DLL containing the function we want to hook. The new DLL should contain stab functions for all the functions that we don’t want to hook, meaning a small function that just calls the original function from the original DLL, and a hook function for all the functions that we do want to hook. There are many good tutorials on this subject, and they can be easily found using Bing Google. I’ll have to recommend the ones from codeproject.com: http://www.codeproject.com/KB/DLL/CreateYourProxyDLLs.aspx
http://www.codeproject.com/KB/DLL/Creating_a_Proxy_DLL.aspx
If you are looking for a good way to create persistent hooks, that are not injected at run-time, this might be your choice.

Now for my small original contribution:
I've started working on a Python C++ code generator (That's a Python script to generate C++ code) for hooks of type 3. The idea is to make life easier for writing many hooks. I’ll be taking advantage of this new code generator on Thursday at the DC9723 Hacktahon (http://dc9723.org/Hackathon), for creating a module to alter OpenGL / DirectX behavior in real-time. The project is Open Source and anyone can browse it at: https://xp-dev.com/svn/DirectHook/trunk/ Or SVN to it at: http://xp-dev.com/svn/DirectHook/ Please contact me to commit changes, or to join me in developing. Hopefully, this module would allow a user to alter 3d games by changing camera Angles, changing the light conditions, modifying textures or just seeing throw walls. One of the targets is to get to something like this:
(Stolen from wikipeida http://en.wikipedia.org/wiki/Valve_Anti-Cheat)

Happy hooking,
Assaf.

--------------------------------------------------------------------------------
Update:
It was lots of fun working at the Hackton, thanks to all the Ninjas who helped with the coding. I found the problem that caused the demo to run very slow. It seems like opengl32.dll calls LoadLibrary about every time a OpenGL API is getting invoked. What makes the hooking method we used quite problematic, as it adds a small overhead to the LoadLibrary calls. The small overhead got very big, thanks to the extended use. I would refactor the code to use proxy dll next time I’ll have a few hours to spare.


Cheers,
Assaf.

2 comments:

  1. Anonymous19/10/11

    you done great post
    if i can help you
    feel free to contact me

    ReplyDelete
  2. Thanks.
    I couldn't find the time to continue working on that lately. The very first thing that we have to do next at this project is to switch hooking library, as the Rechter's library that we are currently using has few bugs in it. Tell me if you want permissions to write to the SVN project at http://xp-dev.com/svn/DirectHook/

    Cheers,
    Assaf.

    ReplyDelete