Reverse Engineering for Beginners

(avery) #1
CHAPTER 68. WINDOWS NT CHAPTER 68. WINDOWS NT
S is a basic status code: 11—error; 10—warning; 01—informational; 00—success. U—whether the code is user code.

That is why we chose 0xE1223344— 0xE (1110b) mean this it is 1) user exception; 2) error. But to be honest, this example
works fine without these high bits.

Then we try to read a value from memory at address 0. Of course, there is nothing at this address in win32, so an exception
is raised. The very first handler is to be called—yours, and it will know about it first, by checking the code if it’s equal to the
EXCEPTION_ACCESS_VIOLATIONconstant.

The code that’s reading from memory at address 0 is looks like this:

Listing 68.2: MSVC 2010

xor eax, eax
mov eax, DWORD PTR [eax] ; exception will occur here
push eax
push OFFSET msg
call _printf
add esp, 8

Will it be possible to fix this error “on the fly” and to continue with program execution? Yes, our exception handler can fix
theEAXvalue and let theOSexecute this instruction once again. So that is what we do.printf()prints 1234, because
after the execution of our handlerEAXis not 0, but contains the address of the global variablenew_value. The execution
will resume.

That is what is going on: the memory manager in theCPUsignals about an error, the theCPUsuspends the thread, finds the
exception handler in the Windows kernel, which, in turn, starts to call all handlers in theSEHchain, one by one.

We use MSVC 2010 here, but of course, there is no any guarantee thatEAXwill be used for this pointer.

This address replacement trick is showy, and we considering it here as an illustration ofSEH’s internals. Nevertheless, it’s
hard to recall any case where it is used for “on-the-fly” error fixing.

Why SEH-related records are stored right in the stack instead of some other place? Supposedly because theOSis not
needing to care about freeing this information, these records are simply disposed when the function finishes its execution.
This is somewhat like alloca(): (5.2.4 on page 26).

68.3.2 Now let’s get back to MSVC


Supposedly, Microsoft programmers needed exceptions in C, but not in C++, so they added a non-standard C extension to
MSVC^34. It is not related to C++PLexceptions.

__try
{
...
}
__except(filter code)
{
handler code
}

“Finally” block may be instead of handler code:


__try
{
...
}
__finally
{
...
}

The filter code is an expression, telling whether this handler code corresponds to the exception raised. If your code is too
big and cannot fit into one expression, a separate filter function can be defined.

There are a lot of such constructs in the Windows kernel. Here are a couple of examples from there (WRK):

(^34) MSDN

Free download pdf