Windows 系统异常处理顺序总结

首先要明白异常处理是分层的,有:

1.内核异常处理

2.调试器异常处理

3.进程VEH

4.线程SEH

5.系统默认的异常处理函数 UnhandledExcetionFilter().

SetUnhandledExceptionFilter()来注册新的Top Level Exception Filter函数

应用程序触发异常时,系统在前面没有异常处理的情况下,会调用Kernel32.dll中的UnhandledExceptionFilter()函数。

UnhandledExceptionFilter()函数里会利用ntdll.dll中的NtQueryInformationProcess()来判断是否被调试。

若判断在被调试,异常给调试器处理(OD调试器显示无法处理异常,进程终止)。

若判断未被调试,则调用Top Level Exception Filter函数。

默认的Top Level Exception Filter 函数根据 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug子键中的项来处理.


异常发生时,顺序执行为:
CPU捕获异常->Ring0内核异常处理->Ring3层调试器->Ring3层的异常处理 ntdll.dll中的KiUserExceptionDispatcher().
void stdcall KiUserExceptionDispatcher (EXCEPTION_RECORD *er, CONTEXT *con) 

注:如int 3,EFlags的Trap Flag,在OD关闭忽略异常,strongOD选项不选,将不会触发KiUserExceptionDispatcher()函数.


KiUserExceptionDispatcher执行流程(根据某一过程的返回值,来决定下一步动作)


Windows 2000:

线程栈中单链表SEH(unwind)->进程SetUnhandledExceptionFilter()注册的函数->系统默认的异常处理Top Level Exception Filter 函数


 XP异常处理顺序:

进程堆中双链表VEH->线程栈中单链表SEH(unwind)->进程SetUnhandledExceptionFilter()注册的函数->系统默认的异常处理Top Level Exception Filter 函数


结合OD的个人调试经验,若想知道整个进程的异常情况,可以在KiUserExceptionDispatcher 下条件断点(shift+F4):

1.异常原因: [[esp]]

Log data
地址       消息
77B46FE8   COND: 异常信息 = 80000003
77B46FE8   断点位于 ntdll.KiUserExceptionDispatcher


2.发生异常的地址:[[esp]+0c]  或者 [[esp+4]+0b8]     (注意:[[esp+4]+b8]将会提示未知的标示符,A-F前面必须加0)

77B46FE8   COND: 异常地址 = 00411C31
77B46FE8   断点位于 ntdll.KiUserExceptionDispatcher

你可能感兴趣的:(Windows 系统异常处理顺序总结)