//================================================== // MYSEH - Matt Pietrek 1997 // Microsoft Systems Journal, January 1997 // FILE: MYSEH.CPP // To compile: CL MYSEH.CPP //================================================== #define WIN32_LEAN_AND_MEAN #include #include /*#ifdef __MINGW32__*/ #include DWORD scratch; EXCEPTION_DISPOSITION #ifdef __MINGW32__ #else __cdecl #endif _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; #ifndef __MINGW32__ __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 mov eax,0 // Zero out EAX mov [eax], 1 // Write to EAX to deliberately cause a fault } #else __asm__ __volatile__ ( "pushl %0" : /* None */ : "a"(handler)); __asm__ __volatile__ ( "pushl %fs:0 \n\t" "mov %esp,%fs:0 \n\t" "mov $0,%eax \n\t" "movb $1,(%eax)"); #endif printf( "After writing!\n" ); #ifndef __MINGW32__ __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 } #else __asm__ __volatile__ ( "mov (%esp),%eax \n\t" "mov %eax,%fs:0 \n\t" "add $8,%esp"); #endif return 0; }