6.5. WINDOWS NT
}
int main()
{
DWORD handler = (DWORD)except_handler; // take a pointer to our handler
// install exception handler
__asm
{ // make EXCEPTION_REGISTRATION record:
push handler // address of handler function
push FS:[0] // address of previous handler
mov FS:[0],ESP // add new EXECEPTION_REGISTRATION
}
RaiseException (0xE1223344, 0, 0, NULL);
// now do something very bad
int* ptr=NULL;
int val=0;
val=*ptr;
printf ("val=%d\n", val);
// deinstall exception handler
__asm
{ // remove our EXECEPTION_REGISTRATION record
mov eax,[ESP] // get pointer to previous record
mov FS:[0], EAX // install previous record
add esp, 8 // clean our EXECEPTION_REGISTRATION off stack
}
return 0;
}
The FS: segment register is pointing to theTIBin win32.
The very first element in theTIBis a pointer to the last handler in the chain. We save it in the stack and
store the address of our handler there. The structure is named_EXCEPTION_REGISTRATION, it is a simple
singly-linked list and its elements are stored right in the stack.
Listing 6.22: MSVC/VC/crt/src/exsup.inc
_EXCEPTION_REGISTRATION struc
prev dd?
handler dd?
_EXCEPTION_REGISTRATION ends
So each “handler” field points to a handler and an each “prev” field points to the previous record in the
chain of exception handlers. The last record has0xFFFFFFFF(-1) in the “prev” field.