Windows exception handling process

xiaoxiao2021-03-05  28

Windows exception handling process

Create time: 2004-12-10 Article property: Original Windows exception handling process is first distinguished from abnormalities and interrupts. Interrupts can occur at any time, which is independent of what instructions are performing with the CPU, and the interrupt is primarily triggered by hardware such as I / O devices, processor clocks, or timers, which can be allowed or canceled. An exception is due to the CPU executes some instructions, which may include memory access violations, except 0 or specific commissioning instructions, etc., the core also treats system services as an abnormality. Interrupt and abnormal more underlying differences When there is a generalized interrupt (including exception and hardware interrupt), if it is not set in the service register (using the command number 0xB to 8259-1 interrupt controller 0x20 port, used in service register 1) 0xB is read from the 8259-2 interrupt controller 0xA0 port in Service Register 2) related to the service bit (8 bits in the service register, a total of IRQ 0-15), which is an exception of the CPU, otherwise the hardware interrupt . Below is the definition of the Windows 2000 according to the Intel X86 processor, which registers the previous items in the IDT (different operating systems are different, which gives it different from other materials. Because this is a specific implementation of Windows): Interrupt Number Name Reason 0x0 Swarf error 1, div and idiv command except 0 2, division result overflow 0x1 debug trap 1, EFLAG TF position bit 2, execute to debug register (DR0-DR4 ) Setup breakpoint 3, execute the INT 1 instruction 0x2 NMI interrupt to place the NMI input pin setting of the CPU (the exception to the hardware is unbroof interrupt) 0x3 breakpoint execution INT 3 instruction 0x4 integer overflow execution INTO directive and OF Location 0x5 Bound boundary Check error Bound instruction comparison value 0x6 Invalid Operation Code instructions Unable to recognize the 0x7 coprocessor does not use 1, CR0 EM position bit, perform any coprocessor instructions 2, coprocessor work Another exception 0x9 coprocessor segment overrun floating point command reference memory exceeds the descriptor included in the section 0xA invalid task segment in the Duan 0xA invalid task segment (Windows does not use TSS for environmental switching, So this abnormality shows that there is other problem) 0xB segment does not exist that the referenced segment is replaced by the memory 0xc stack error 1, the reference memory exceeds the stack segment limit 2, the PRESENT position of the descriptor loaded into the SS register 0 0XD General Protection Error All other exception handling routines Unable to process an exception 0xE page error 1, access to the address is not swapped into memory 2, the access operation violates the page protection rule 0x10 Coprocessor error CR0 execution WAIT or ESCAPE directive 0x1 1 Align check error alignment check When the ON (EFLAG Alignment Location Bit) Access Unorganized Data Other exceptions also include obtaining system startup time service int 0x2a, user callback int 0x2b, system service int 0x2e, debugging service int 0x2d and other systems to implement yourself The part of the function is through an abnormal mechanism, and the trigger mode is to perform the corresponding INT instruction.

Here are several important exception handling structure: TrapFrame trap frame structure (frame ExceptionFrame abnormal structure mentioned later is actually a structure KTRAP_FRAME): typedef struct _KTRAP_FRAME {ULONG DbgEbp; ULONG DbgEip; ULONG DbgArgMark; ULONG DbgArgPointer; ULONG TempSegCs ; ULONG TempEsp; ULONG Dr0; ULONG Dr1; ULONG Dr2; ULONG Dr3; ULONG Dr6; ULONG Dr7; ULONG SegGs; ULONG SegEs; ULONG SegDs; ULONG Edx; ULONG Ecx; ULONG Eax; ULONG PreviousPreviousMode; PEXCEPTION_REGISTRATION_RECORD ExceptionList; ULONG SegFs; ULONG EDI; Ulong ESI; Ulong EBP; Ulong EBP; Ulong Eip; Ulong Segcs; Ulong EFLAGS; Ulong Hardwareesp; Ulong Hardwaresegss ; ULONG V86Es; ULONG V86Ds; ULONG V86Fs; ULONG V86Gs;} KTRAP_FRAME; Environmental Context structure: typedef struct _CONTEXT {ULONG ContextFlags; ULONG Dr0; ULONG Dr1; ULONG Dr2; ULONG Dr3; ULONG Dr6; ULONG Dr7; FLOATING_SAVE_AREA FloatSave; ULONG SegGs Ulong segfs; ulong segding; ulong edi; ulong ESI; Ulong EBX; Ulong EDX; Ulong ECX; Ulong EIX; Ulong EBP; Ulong Eip; Ulong Segcs;

ULONG EFlags; ULONG Esp; ULONG SegSs; UCHAR ExtendedRegisters [MAXIMUM_SUPPORTED_EXTENSION];} CONTEXT; abnormal recording ExceptionRecord structure: typedef struct _EXCEPTION_RECORD {NTSTATUS ExceptionCode; ULONG ExceptionFlags; struct _EXCEPTION_RECORD * ExceptionRecord; PVOID ExceptionAddress; ULONG NumberParameters; ULONG_PTR ExceptionInformatio [EXCEPTION_MAXIMUM_PARAMETERS]; } Exception_record; After an exception occurs, the CPU records the current register status and establishes trap trapframe in the kernel stack, and then controls the control to the corresponding abnormal trap processing program. When the trap handler can handle an exception, such as the page program MMAccessFault, when the page is swapped into physical memory, returns an exception by IRET. But most of them cannot handle exceptions, first call CommondispatChexception to establish exception records ExceptionRecord and exception frame ExceptionFrame in the kernel stack. ExceptionRecord is important, it records exception code, exception addresses, and some additional additional parameters. Then call KidispatChexception for exception assignment. This function is the core function of exception processing under Windows, responsible for abnormal distribution. KidispatCHException process (whenever the routine processed when the exception is handled by a routine, returns false. When any one of the routines have returned TRUE, KidispatChexception is returned normally Before the abnormality of the user-state, first determined whether the exception comes from user mode, if the context.contextflags (this time the Context structure is still initialized, it does not assign the initial value) or CONEXT_FLOATING_POINT, meaning Exceptions from user mode always try to assign floating point status, which allows an exception handler or debugger to check and modify the status of the coprocessor. Then remove the register value from the trap frame to fill in the context structure, and determine if it is a breakpoint exception (INT 0x3 and INT 0x2D), if so, will first reduce the context.eip to point to int 0x3 instructions (whether it is int 0x3 Or an exception caused by INT 0x2D, ​​since the previous trap handler has changed the EIP in TrapFrame). Then determine that the exception occurs in the kernel mode or user mode, take different processing procedures according to different modes. If an exception occurs in a kernel mode, the first opportunity to the kernel debugger and the second chance to deal with exceptions. When an exception is processed, the trap frame will be set and returned to the trap handler, where IRET returns an abnormal place to continue execution. The kernel mode exception handling process is: (first opportunity) Judging whether kidebugroutine is empty, not empty, put context, trap frame, exception record, abnormal frame, an exception mode, etc., and hand it over to KidebugRoutine. | | | If kidebugroutine is empty (normal system is not empty here.

Normal start-up system kidebugroutine is kdpstub, and the KidebugRoutine of the system in boot.ini and / debug starts is KDPTrap. If this is empty, the system crashes due to the abnormality generated by DBGPrint this type of INT 0x2D, ​​or KidebugRoutine has not processed an exception, then the Context structure and exception record ExceptionRecord stack and calls the kernel mode RTLDispatChexception in the kernel stack. The abnormality processing routine of the frame. | | R r isPatChexception Call RTLPGETREGISTRATIONHEAD Gets the current thread exception processing Link Pointer from FS: [0] (0xffdff000) and calls RTLPGETSTACKLIMITS from 0xffdff004 and 0xFFDFF008 to remove the current thread stack bottom and top. Then start the abnormal processing list pointer traversal chain table to find an exception handling routine (if the VEH processes the VEH again in XP and 2003), this is SEH, but there is a bit different from the user state that has neither a top abnormality processing routine ( Top Level SEH) also has no default exception handling routine. Then check for each current exception handling Lin table pointer to determine if the stack is valid (whether the stack range or is not aligned) and the stack are DPC stack. If DPCROUTINAACTIVE is TRUE, the dpcstack is removed to the True and the pile top and the bottom at the 0xFFDFF81C (a kernel stack size), if the renewal stack top and bottom is DPCSTACK and DPCSTACK-0x3000 and continue processing, otherwise the abnormality record structure ExceptionRecord.ExceptionFlags Setting_stack_INVALID is indicated as an invalid stack and returns false. | | | | Call an exception handling the exception handling routine to insert a new node on the exception handling routine, the corresponding exception handling routine is used to handle nested abnormalities, that is, when processing exceptions. Another exception. Call RtlRaiseException into KiDispatchException post if it is ExceptionContinueExecution, if abnormal signs ExceptionRecord.ExceptionFlags EXCEPTION_NONCONTINUABLE not be resumed is not set, TRUE is returned to the floor, or doing some work: RtlDispatchException exception handling routines to determine the return value after treatment The second opportunity processing section. If you exceptionContinueSearch, you will continue to find an exception handling routine. For ExceptionNestedException, nesting exceptions. Keep the current exception handling Link Pointer is the inner abnormality handling lin list and processes the exception handling routine. When the current exception handling linked list address is greater than the remaining inner abnormality, the current exception handling linked list is the more inner layer of the current exception, because the stack is expanded from high-directions, the higher the address, the more early, indicated In the inner layer), the value is given to the inner abnormality processing linked list pointer, except for the first end value, the inner abnormality processing linked list pointer, which represents the nesting, more than one exception. When searching for a new exception handling Lin table pointer and the reserved inner abnormality handling the linked list pointer, clear the nesting anomalous bit (& (~ Exception_NESTED_CALL)) of ExceptionRecord.exceptionFlags, indicating that the anomaly of the nested has been processed. All other return values ​​are considered invalid, call RTLRAISEEXCEPTION to return to KidispatChexception to the second chance processing section. When an exception handling a linked list pointer is 0xffffffFFF, the exception handling routine is in the head.

If RTLDISPATCHEXCEPTION cannot handle exceptions, (Second opportunity) Judging whether kidebugroutine is empty, do not hand it over to KidebugRoutine processing for the flight. | | | When all routines cannot process an exception, call the KebugCheckex blue screen, the error code is kmode_exception_not_handled, and no one has dealt with an exception, and the system treats this exception to failure to recover. It is completed until this kernel mode is completed. If an abnormality occurs in user mode, the first opportunity to debug the first chance and the second chance will be debugged. Only because the debugger is a user status initiator, the message is sent to the session manager SMSS.exe via the LPC, and the message is forwarded to the debugger. User mode exception processing procedure: If kidebugroutine is not empty, it is not empty to press the context, trap frame, abnormality record, abnormal frame, an exception mode, etc., and will be handed over to KidebugRoutine. When the processing is used to set the trap frame with Context and return to the previous routine. (First Opportunity) Otherwise, the exception record is stack and calls DBGKFORWARDEXCEPTION, and the HideFromDebugger member of the current thread Ethread structure is determined in DBGKFORWARDEXCEPTION If the current thread is (to true indicators to the user debugger), the debug port of the current process is (Debugport) Sends an LPC message. | | | When the previous step cannot be processed, copy the Context structure to the user stack, set a trap frame in the stack, the EIP of the trap frame is KE (i) UseRexceptionDisptcher ((i) means the key of the KE and Ki headers of this function In fact, it is a matter of time), then returns the trap handler, returning the user-state execution of the trap handler IRET (I) UseRexceptionDispatcher (this function is a KE (Ki) head, but is not the function in the core. The same nature is also special With Ke (i) RaiseUseRexceptionDispatcher, ke (i) UserCallbackDispatcher, ke (i) UserApcdispatcher. Their common feature is not called, but is set by the kernel routine TRAPFRAME.EIP to this function. of). Ke (i) UsexceptionDisptcher calls RTLDISPATCHEXCEPTION (User state) Looking for frame-based exception processing routines in the stack (if the XP and 2003 processes the VEH and then processed SEH), this process should be very familiar, that is, Search SEH Link list If you do not process, you call the top Abnormally SEHS routine. When it is no longer processed, the default exception handling routine is called to terminate the process (which is changed here when there is VC). A bit different is that RTLDISPATCHEXCEPTION under the user state only judges that the return value is ExceptionContinueexecution or ExceptionContinuesearch. If RTLDISPATCHEXCEPTION is found to process an exception, call ZwContinue to continue executing according to the setup structure, otherwise call ZwraiseException, and set the third Boolean parameter to false, indicating that the second opportunity is handled. | | | ZwraiseException After a series of calls finally call KidispatChexception, the Boolean firstchance is set to false, and directly enter the second opportunity in the KidispatChexception.

| | | (Second Opportunity) Send a message to the process of debugport, if it is unable to process, the EXCEPTIONPORT message of the process (here the same is not visible to the user debugger, it will only be sent to ExceptionPort). The difference between DEBUGPORT and ExceptionPort is that if you send a message to an ExceptionPort, stop the execution of all threads in the target process until the thread returns to the response message, and the message is sent to the DEBUGPORT, and there is no need to stop the thread operation. There is also a message to the session manager, and ExceptionPort is sent to the Win32 subsystem. When sending a message to the ExceptionPort, it is no longer given any chance to the user status debugger :). | | | When an exception still cannot be processed, terminate the current thread and call the KebugCheckex blue screen, the error code is kmode_exception_not_handled. The exception is completed in this user mode. One thing to explain is that this only lists the operations of the operating system. If you look at the drive or an application now, join the __TRY / __EXCEPT code, but did not find the exception handling routine corresponding to the node on the SEH and the relationship with yourself. The reason is because the compiler of M is encapsulates SEH's mechanism in the system inside the system. The exception handling routine on the abnormal processing routine chain table node is actually _except_handler3, this function has implemented a mechanism similar to SEH internally, which is to establish a table for each function, including all in this function. The __TRY block corresponds to the corresponding function in the __TRY () parentheses, if the parentheses are exception_execute_handler, the filter exception routine is simply assigned to the corresponding 1, 0 or -1 Then return, corresponding to exception_execute_handler, exception_continue_search, and handption_continue_execute and handle routine pointer (__except {} and address of code in __final {}). Therefore, each called function is registered on the SEH linked list and establishes a table. Like such as Exception_execute_Handler, Exception_Continue_Search, Exception_Continue_execute is actually returned to the return value of _except_handler3 instead of returning to RTLDISPATCHEXCEPTION. It is a bit dizzy, huh, huh. Summarize the process (refer to the complete process that is not processed. If the exception is processed from the process from the link to the process of continuing the original normal program code): KidispatChexception -> (first opportunity) KidebugRoutine > RTLDISPATCHEXCEPTION Looking for SEH (VEH) -> (Second Opportunity) KidebugRoutine-> KebugCheckex User Mode: KidebugRoutine -> KidebugRoutine -> (First Opportunity) Send Messages to Process Debug Ports -> RTLDispatChexception in User Stack Look for SEH (VEH) -> ZwraiseException Back to KidispatChexception -> (Second Opportunity) Send Messages to Process Debugging or Exception Port -> KebugCheckex. It's so simple, huh, huh. For example, an example is to illustrate the abnormal process.

The program is debugged by joining int 0x3 in our program, how is the exception generated by INT 0x3? If INT 0x3 occurs in kernel mode (in the driver), it is divided into kernel debugger whether it is loaded. When the kernel debugger is not loaded, kidebugroutine (kdpstub) does not process int 0x3 exception, then search for SEH registered by the driver writer in the stack, if there is no processing of INT 0x3 exception, then call the kebugCheckex blue screen, the error code is Kmode_exception_not_handled (no one is working, the system has only sorrowful and angry). If the kernel debugger is loaded, kidebugroutine (kdptrap) can handle int 0x3 exception, and the abnormality is processed to be returned normally. The processing method is to send the current processor status (such as various registers, etc.) to the kernel modulator on the host connected by the serial port, and has been waiting for the kernel debugger to respond, and the system calls a KD function in KDPTRAP. The KdpsendWaitContinue loop is waiting for data from the serial port (kernel debugger and the debugged system through serial port) until the kernel debugger will continue the command, the system can be done from INT 0x3 instructions. If INT 0x3 occurs in user mode, it is also divided into user debugger loading. When the user debugger is not loaded, KidebugRoutine does not process int 0x3 exception, and the user process has no DEBUGPORT, copy the related structure of the recording exception to the user's stack, the RTLDispatChexception, the user's stack, the SEH in the user's stack. If there is no processing of INT 0x3 abnormalities, the default exception handling routine is called. By default, the process is terminated will occur. If there is a user debugger loading, send the abnormal LPC message to the process of the DEBUGPORT or ExceptionPort and determines the return status of the send function. If the user debugger continues to execute, return Status_Success, the kernel is considered to have resolved continued execution. It also illustrates this, which is the same error, which occurs in the intra-nuclear state than being fatal under the user state. Other abnormal processing processes are basically the same. A small number of different exceptions are debugprint, debugprompt, load and uninstall Symbol, etc. By calling DebugService (this is actually generated by generating an exception INT 0x2D). It can be processed in KdpStub (the processing is simple, just add the EIP of the Context structure to the current INT 0x2D), and if it is processed in KDPTRAP, it is further interacting with the kernel debugger. For more detailed introduction to KDPSTUB, KDPTRAP, and DebugService, see another article "Analysis of the Principle of Windows Nuclear Trial". Postscript: I found out that half of the article has been written in the past few days ago. At that time, because there were still something that I didn't understand, I didn't finish it, and the result was half a year. Now, I will find a lot of things after I finish writing, and I also take the experience to give you a reference, it is a throwing brick jade:) QQ: 36701839Email: jarodlau @ 163..com

转载请注明原文地址:https://www.9cbs.com/read-38487.html

New Post(0)