|
One safe hook handler - E8 Method, paper
There exist different libraries to set hooks, lot of them in Windows, but time ago we faced a specific problem for which no solution nor documentation were found about. The problem is: how to setup hooks for several APIs in runtime, reading from a configuration file that gives the APIs and prototypes? When discussing about this idea I got another question in response: why do you want to do that? My answer was: I don't want to develop a different handler for every hooked API and compile every time for it to work, and I don't want to build a run time Handler creator. We cam sum up in two requisites: 1.- Use some kind of technology that does not require previous compiling. 2.- Develop some kind of macro to simplify the coding and reduce compile errors. As I was not convinced of these solutions, I started to think about this problem and about what I really want, so the right question appeared: What do I need to do what I want? And the answer is simple: Having one handler for every hook, just know when it is called, which API/hook is the caller and then take proper decissions. That's it!, I need and "API ID". Or best expressed, I need a "hook_caller ID" This is the point where I need to mention that the hook method I need is "Detours" [R.9] [R.6], said, insert a JMP, PUSH + RET ... in the address where we want to place the hook. I selected this method [R.9] taking care about that some of the other methods have a problem when you call directly the memory address where the hook lies, so the handler it is not executed, i.e. IAT HOOKING. In the methods that insert JMP, PUSH + RET... in reserved memory or padding bytes, direct calls don't execute the handler. As my first priority was to intercept every call to the hooked APIs, the "Detours" method [R.9] [R.6] that overwrites instructions where we want our hook placed, looked the best. Though this method implies the use of some kind of LDE (Length-Disassembler Engine) [R.7], among other things, there exist libraries in the web that allow us to use this method in Windows without any trouble. Now, we just need only to answer the question: how can I know which hook is calling the handler in runtime? After some serious thinking about the problem I got an "Eureka!": I will replace the JMP method by a CALL-style method, and I will check from the hanlder the return address that CALL places in the stack, using this return address as the "hook_caller ID". As every hook is in a different memory position, every CALL will place a different value in the stack, so it can be used as an identificator. Then, we need only to modify the normal method so the handler will process this "hook_caller ID" and will remove it from the stack. Problem solved. Now the last thing left was to find a name, this name appeared when coding the problem: "E8 Method". As a JMP (no SHORT) in the address XXXXXXXX to YYYYYYYY, will be coded as: "E9 ZZZZZZZZ", and a CALL from the same address to the other address will be coded as: "E8 ZZZZZZZZ". Eureka! (again). The part that changed was the opcode for the instruction, as it was opcode for CALL, E8, so I decided to call the method "E8 Method". But "E8 Method" it is not only to replace the JMP type hook by the CALL type, it is the concept and/or the style of implementing a global handler ("One hook handler") that could obtain the "hook_caller ID" in runtime. After the development of the first proof of concept (POC) I had some problems, like stack buffer overflows when the hooked APIs where called directly and indirectly from the hooh handler, Microsoft Visual Studio checks to detect when the stack is corrupted using the EDI value my hook handler was modifying internally, etc. So it was not only to create a hook handler; I have had to create a safe hook handler taking care of most of there problems. As long as the project grew it was neccesary to code some pieces in C/C++ resulting a problematic hybrid code between ASM/C/C++, so I developed a low-level layer that allowed me to code everything in C/C++ without further troubles. There appeared some stack buffer overflows too when calling the hooked API, but I found an ellegant solution in the easy hook called Threat Deadlock Barrier (TDB) [R.8]. This documento is about how to use and implement the "E8 Method" with only one hook handler for every hook that will be safe and will be implemented in C/C++: "One safe Hook Handler". Two public libraries, where a hack has been applied, will be used: 1.- Microsoft Detours Library [R.6] 2.- Easy-Hook [R.8] Download in English: http://fr33project.org/papers/One%20safe%20hook%20handler%20-%20E8%20Method.txt Download in Spanish: http://fr33project.org/spanish/papers/One%20safe%20hook%20handler%20-%20E8%20Method.txt Comments
| ||||||||||||||||||