Saturday, December 17, 2011

SEH Hooking

In this example, I will cover a method of hooking which uses SEH (Structured Exception Handling) in order to hook code in any location without overwriting the code. This method of hooking is very much alike the SEH Hooking which is used by many debuggers to place breakpoints, but has two small differences.
  1. Instead of writing INT3 Breakpoints and catching the BREAKPOINT Exception, I'm setting the memory to PAGE_NOACCESS and catching the ACCESS_VIOLATION Exception.
  2. Instead of writing the address of my handler to the PEB directly, I'm using a VEH (Vectored Exception Handler), which is being added using the AddVectoredExceptionHandler() WinAPI Function.
This method of hooking works by modifying the protection of a byte of memory at the location of our hook to PAGE_NOACCESS. When this memory is executed, our VEH catches an ACCESS_VIOLATION Exception. It then checks the instruction pointer to see if the violation occurred at the location of our hook. If this ACCESS_VIOLATION is not our hook, we return CONTINUE_SEARCH to allow other handlers to work with the exception. However, if it is our hook, we do 3 things:
  1. Execute our hook's callback
  2. Restore the memory access to its original state
  3. Set the trap flag, which will trigger a single step
We then return CONTINUE_EXECUTION. This time, the hooked code executes it's first byte flawlessly and then triggers a SINGLE_STEP Exception. This single step is a result of setting the trap flag, and it allows us to set the hooked memory back to PAGE_NOACCESS so our hook will execute again the next time the hooked memory is accessed.

Since our exception handler's ContextRecord contains a pointer to the top of the stack, we are also able to access function arguments and find return addresses. Because of this, we can block the execution of a function or change the input, just like in a normal hook. To block execution, we can place a JMP [ReturnAddressFromStack] in our hook handler. While this jumps right back into execution and skips steps 2 and 3 of our exception handling, it is jumping back to the calling function and not the hooked code. The NOACCESS remains in place for next time.

While this rendition of SEH Hooking isn't flawless, it does illustrate the concept and get the job done. In most cases, if you plan on using SEH Hooking, I would recommend using INT3 Breakpoints, though. This method, however, is a good way to bypass modification detection. While programs may checksum their code, they don't usually verify the memory protection of every page in the program.

In the example code, I hook the MessageBoxA() WinAPI Function. Inside my handler, I call printf() to print the caption and text to the console. I then block execution of MessageBoxA().


3 comments:

  1. Only issue with this is that the minimum page size on windows is 4KB. If you have 2 break points set within one 4KB code page and you hit a breakpoint your call to restore the page protection level:

    VirtualProtect((LPVOID)replaceHook, 1, activeHook.originalProtection, &oldAccess);


    Will reset the full page and disable any other breakpoints on that page.

    ReplyDelete
  2. Can't find the sample source code. Could you come post this in our forums with sample code? This is one of the main focuses of our site and I welcome you to share the info we provide and maybe provide some of your own and network with us to get your stuff out there. http://xor.cx is our portal and if you register you can blog to it or post to the forums. Come by irc.xor.cx #neworder and hit me up.

    -f0x90

    ReplyDelete
  3. Hey man,
    Nice post.. Gave another point of view for hooking :)
    Btw i was working the previous days on API Hooking and made a tool for that providing full source code, and included vectored exception handling for the injected code..
    Whoever is interested can see it here http://www.133tsec.com/2011/12/23/api-hooking-tool-injecting-code-in-the-pe-tool-explanation-and-application-examples/
    Includes video examples

    ReplyDelete