Figure 3: MYSEH.CPP

//==================================================
// MYSEH - Matt Pietrek 1997
// Microsoft Systems Journal, January 1997
// FILE: MYSEH.CPP
// To compile: CL MYSEH.CPP
//==================================================
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

DWORD  scratch;

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext )
{
    unsigned i;

    // Indicate that we made it to our exception handler
    printf( "Hello from an exception handler\n" );

    // Change EAX in the context record so that it points to someplace
    // where we can successfully write
    ContextRecord->Eax = (DWORD)&scratch;

    // Tell the OS to restart the faulting instruction
    return ExceptionContinueExecution;
}

int main()
{
    DWORD handler = (DWORD)_except_handler;

    __asm
    {				// Build EXCEPTION_REGISTRATION record:
	push    handler		// Address of handler function
	push    FS:[0]		// Address of previous handler
	mov     FS:[0],ESP	// Install new EXECEPTION_REGISTRATION
    }

    __asm
    {
	mov     eax,0		// Zero out EAX
	mov     [eax], 1	// Write to EAX to deliberately cause a fault
    }

    printf( "After writing!\n" );

    __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;
}