Exception distribution and processing are performed within the thread range. The registration of exception processors is also relative to the thread. In Windows, every user-state Thread has a Thread Environment Block (Thread Environment Block), which defines the TEB structure. At the beginning of the TEB structure, there is always a structure called Thread information Block (TIB. In the first field of TIB, The predictionlist record is used to register the header address of the chain table for handling structural exceptions. In x86 systems, the segment register FS always points to the TEB/TIB structure of the thread. FS: [0] always points to the header of the list for handling structured exceptions. Therefore, this chain table is called FS: [0] chain. Structured exception handling can be seen as a model of hardware and software exceptions of the operating system and user code. The FS: [0] chain is the interface for collaboration between the two. When an exception needs to be handled, the operating system uses the FS: [0] chain to find the exception processor, giving the user a chance of code exception.
You can manually write code to register and deregister the exception processor. First, you need to write an exception processor function, which should have a standard sehHandler prototype, then create an EXCEPTION_REGISTRATION_RECORD structure on the stack, and register the address of this structure to FS: [0] In the linked list.
The code for registering FS: [0] is as follows:
# Include "stdafx. h" # Include <windows. h> // Define an exception handling function that complies with the sehHandler prototype. If this function detects that // Except for zero exception, change the value of the ECX register in the context structure to 10 to continue execution. // Code that causes an exception. The code can be executed smoothly because the divisor is no longer 0 during the second execution. Prediction_disposition _ cdecl _ raw_seh_handler (struct _ prediction_record * predictionrecord, Void * establisherframe, Struct _ CONTEXT * ContexRecord, Void * DispacherContext ) { Printf ("_ raw_seh_handler: code-0x % x, flags-0x % x \ n ", Predictionrecord-> predictioncode, Predictionrecord-> predictionflags ); If (ExceptionRecord-> ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO) { ContexRecord-> Ecx = 10; Return ExceptionContinueExecution; } Return ExceptionContinueSearch; } Int main (int argc, char * argv []) { _ ASM { // Manually register the abnormal function to the FS: [0] linked list Push offset _ raw_seh_handler Push FS: [0] MoV FS: [0], ESP // An error occurred while performing the division by zero operation. XOR edX, EDX MoV eax, 100 XOR ECx, ECx Idiv ECx MoV eax, [esp] MoV FS: [0], eax Add ESP, 8 } Printf ("Hello world! \ N "); Return 0; } |