In a 32 bits Windows binary, I see this code:
push next push fs: mov fs:, esp int3 ... next:
I see that something happens on the
int3 (an error), but I don't understand why, and how to follow execution while keeping control.
Reverse Engineering Stack Exchange is a question and answer site for researchers and developers who explore the principles of a system through analysis of its structure, function, and operation. It only takes a minute to sign up.Sign up to join this community
the first 3 lines set an exception handler (an 'error catcher')
int3 generates an exception
execution resumes at
this trick is (ab)using Structured Exception Handling, a mechanism to define exception handlers, typically by compilers when
catch blocks are used.
In 32bits versions of Windows, they can be set on the fly, without any pre-requirement (unless the binary is compiled with /SafeSEH).
The first element of the exception handlers' chain is pointed by the first member of the Thread Information Block (TIB), in turn a member of the Thread Environment Block (TEB), which is pointed to by
fs:0 (which is also reachable 'directly' - via something like
ds:7efdd00, depending on the OS version etc)
So here is what happens:
the first two
push reserve stack space for the structure
mov sets the current stack position as the new structure. When an exception happens,
next will be now the first called handler.
int3 triggers an exception instantaneously (there are many other kinds of exception triggers).
as an exception is triggered, Windows dispatches the exception to the first handler, and the next one if it's not handled, until one of them has handled it.
This is done here under OllyDbg 1.10. YMMV.
As we want to go through exceptions ourselves, we have to ask OllyDbg not to handle them:
go to debugging options: Alt-O, tab
And when an exception is triggered, we have to enforce that execution is done via exceptions (see below).
Here are 3 methods of increasing level to follow the exception handling execution safely:
As the handler has just been set on the stack, you can manually set a breakpoint then run.
select the new handler address on the stack
Right-click or F10
Follow in Dump
in the dump window, open the menu (same shortcut)
Hardware, on execution
Debug/Run / shortcut F9 / command-line
Exceptions will be triggered
Execute with exception handling: shortcut Shift-F9 / command-line
as the address is on the stack, the easiest way is to type via the command line
ge [esp+4], which means,
Go with Exceptions, until the 2nd address on the stack is encountered. Thus, no need to set and unset a breakpoint.
ge ds:[fs:+4], which just gets the actual address from the TIB.
KiUserExceptionDispatcher is the Windows API handling all user-mode exceptions. Setting a breakpoint there guarantees that you keep full control - but then, you're in the middle of a Windows API ;)
In this case, you can ask OllyDbg to skip exceptions, as you will still break execution manually in any cases. You might also want to combine that with a script.
Of course, some advanced code might check that you set a breakpoint on it before triggering an exception.