Windows 系統異常處理順序總結
1.核心異常處理
2.偵錯程式異常處理
3.程序VEH4.執行緒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