Debugging protected code can be hell.
Reverse engineers frequently need to analyze protected code, whether they're evaluating the latest protection system or trying to figure out what a new piece of malware does. We wrote Hades to make that job a little easier.
Hades is a tool for dynamic application analysis. It has function hooking capabilities similar to Microsoft Detours and WinAPIOverride (WAO), and it can also function as a debugger. We developed it to help us analyze some malware binaries that were able to detect Detours and WAO. Both of these tools work by injecting a DLL into a target binary; the DLL places hooks in specific sets of functions and logs information when those functions are called. The malware we were examining could detect that unauthorized DLLs were being loaded into the current process space. To avoid detection, we created an instrumentation tool based on instruction rerouting (to avoid most debugger detection techniques) that runs from the kernel rather than using DLL injection (which avoids DLL detection).
How if works
Hades is based on the concept of instruction rerouting. First, a target executable is identified for instrumentation. The Hades driver registers a callback function using PsSetLoadImageNotifyRoutine to detect when the target executable is loaded. When the target is loaded, but before it begins executing, Hades sets up a system call hook that will allow control to pass from the target to the Hades driver. First, a system call is hooked (any will do). Then a trampoline to a shared area of memory is created. Finally, an instruction rerouting hook (a JMP to the trampoline code) is installed in the process at a user-specified virtual address and target execution is resumed.
Once the instruction pointer hits our rerouting hook control is passed to the trampoline, which invokes an interrupt that will send execution to our hooked system call, where the Hades driver takes control. The driver will save the context (registers, stack, etc.) and display it, change any registers specified by the user, execute the original function bytes, and return control to the process at a point just after the rerouted instruction (virtual address + [JMP size]).
Transitioning from user space to kernel space is achieved by trampolining through the system call dispatcher, which has memory accessible to both kernel and user code. The trampoline is installed in the SharedUserData memory area, which Windows uses as an efficient way to provide processes with certain frequently requested information. Hades uses this area as a scratch space and to host its code for transitioning to the kernel from user space. The trampoline code is installed at offset 0x800 within the SharedUserData area (at address 0x7FFE000 from user space) to place it past Windows function pointers (which are the intended use of this area).
The trampoline is made up of two parts: a hook-specific set of instructions that save the processor state and identify the hooked function, and a generic handler that calls Hades’ hooked system call. Breaking up the trampoline in this way allows us to have multiple function rerouting routines installed in the targeted binary.
How to use it
The most straightforward use is as a function profiler, since that’s what we designed it for. You setup the instrumentation for your functions of interest, point Hades at it, and away you go.
You can also use Hades as a debugger, albeit a limited one. The current version supports a single breakpoint that can fire a single time. This breakpoint works a bit differently from the function hooks in that the stolen bytes (for the control transfer jump) are replaced in the target binary and executed from there.
Where to get it
The GPL-licensed source code to Hades is available at GitHub.