Tracing exception handlers

Suppose our goal is to dissect a new program. The ultimate method of analysis is single stepping the program of interest. Each executed instruction must be single stepped at least once so we won’t miss anything important.

Single stepping is generally easy but if the program uses SEH exceptions to hide its logic, it is becomes more difficult. It is not obvious from the listing where the exception handler resides and what it will do. All what we get when an exception happens it its name and some additional information like the current EIP. Luckily the debugger gets the exception notifications before the application and we can pass the exception to the application or mask it at our will.
Since we do not want to disturb the program behavior we will pass all exceptions to the application:

Do NOT press Yes if you want to single step the exception handler. We will need to set an additional breakpoint at the beginning of the exception handler and get control as soon as the system executes it. For that we will start with the Task Information Block. It has a dedicated segment (press Ctrl-S to open this window, see TIB in the segment name):

Let’s convert the first dword of this segment to an offset (press O):

and follow it by pressing Enter. We will find another dword at the target address. It contains another offset in its turn. This sequence of dwords is part of the exception handler chain. After each dword there is a pointer to an exception handler. We will pick the first exception handler since it will get control:

We found the exception handler and can put a breakpoint at it. After that we can press F9, pass the exception to the application, and and continue single stepping at the handler:

That’s how we get into an exception handler. Now let’s consider the problem of returning to the ‘normal’ application execution from it.
If we single step through the whole exception handler and it finishes its work, we will find ourselves in ntdll.dll. We do not want to single step the system kernel, much faster is to skip it and continue in our program. The NtContinue() function is used to resume the execution. It looks like this:

Single stepping this function would not work and we would lose control! The call gate would let the program run at full speed.
We need to find out the EIP which will be assigned to the program by the system and put a breakpoint there.
The NtContinue() function takes one parameter – the process context structure. This structure contains the values of all processor registers to be used after the exception. EIP register is also present in this structure.
Let’s open the structures window (Ctrl-F9) and insert (Ins) a new structure called CONTEXT:

IDA knows about this structure and will complete the definition for us.
The next step is to apply the context structure to the address pointed by the parameter of NtContinue():

Now the new EIP is visible and clearly commented. We only need to put a breakpoint at it and press F9 to return to our application from the exception handler.
This is how we return from an exception handler.
We learned how to get into an exception handler and return from it. By the way, when we return, we could check the processor registers and if the application has thrashed some of them (thrashed hardware debug registers?) we could restore them. Also, when we enter the exception handler, we could erase the debug register values so that the application can not check them to detect the debugger.
Ah yes, almost forgot to tell you: these actions can be automated and hooked to a hotkey…. Nice plugin idea, isn’t it? 🙂

6 thoughts on “Tracing exception handlers”

  1. seemed to end up inside _NLG_Notify when I chased the offsets Stack[00000B90]:0012FED4 off_12FED4 dd offset off_12FFB0 ; DATA XREF: TIB[00000B90]:7FFDE000o
    Stack[00000B90]:0012FED8 dd offset loc_4013A8
    on a test program

  2. hehe thats nice i have an unfinished plugin for ollydbg that stops on seh returns 🙂
    actually it doesnt need a plugin too in ollydbg
    conditional breakpoint on ZwContinue
    on pause PASS to plugin (the default commandline plugin that comes with the distribution )
    .bp [[esp+4]+0xb8]
    it autoamtically will stop on seh return
    the logic being [esp+4] holds PContext
    pcontext+0xb8 == eip thats to be executed
    .run is to automate the pause in ntdll.dll
    and may be take a look into this post too that actually
    reflects your idea

  3. I wouldn’t claim it to be my idea, it seems that many others do the same thing and I could not find who was the first.
    It is quite natural thing to do if straightforward method of pressing F7 to return from the exception handler fails 🙂

  4. How does one find the NtContinue() function in the debugged database , I dont seem to ne hitting it

  5. Ideally this feature should be in IDA, and it might end up there one day. Why not today? Mundane reasons, like the necessity to change the API to support the notion of single stepping into a handler and out of it (and to do it in the most system independent way), lack of time, other projects. That’s why I hinted about a plugin – any courageous guy to implement it?

Comments are closed.