?
很久木有管博客了?? 最近也沒有學什么???
Dos系統下發生異常后,系統會調用int 24h服務例程,然后根據中斷的返回值決定下一步要做什么,他會在屏幕上顯示ignore Retry Fail Abort? 讓用戶選擇進而進行下一步操作
這樣的話? 只要應用程序截取int 24h中斷,就可以隨意的"胡作非為"了
?
Windows操作系統對異常的處理流程相對復雜,其依靠80x86的保護模式機制來主動捕獲異常.
?
用SetUnhandledExceptionFilter函數設置異常處理回調函數
<span style="font-family:Microsoft YaHei;font-size:13px;">invoke SetUnhandledExceptionFilter,addr _Handlermov lpOldHandler,eax</span>
函數返回的是原回調函數的地址
?
篩選器回調函數的格式如下
_Handler proc lpExceptionInfo
lpExceptionInfo? 指向一個EXCEPTION_POINTERS結構
<span style="font-family:Microsoft YaHei;font-size:13px;">EXCEPTION_POINTERS STRUCTpExceptionRecord DWORD ? ;指向一個EXCEPTION_RECORD結構ContextRecord DWORD ? ;指向一個CONTEXT結構EXCEPTION_POINTERS ENDS</span>
?(1)EXCEPTION_RECORD結構
<span style="font-family:Microsoft YaHei;font-size:13px;">typedef struct _EXCEPTION_RECORD { DWORD ExceptionCode; //異常事件代碼DWORD ExceptionFlags; //異常標志 struct _EXCEPTION_RECORD *ExceptionRecord; //下一個Exception_Record結構地址PVOID ExceptionAddress; DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
</span>
ExceptionCode指定了一系列的錯誤代碼,說明了錯誤的原因
ExceptionFlags說明了錯誤的標志 ,由一系列的數據位組成
位0:代表發生的異常是否允許被恢復執行,當位0被復位的時候,表示回調函數在對異常進行處理后可以指定讓程序繼續運行,置位時候表示這個異常是不可恢復的,,這個時候程序最好進行退出前的掃尾工作,并選擇終止應用程序,如果這個時候非要指定讓程序繼續執行的話,Windows會再次以EXCEPTION_NONCONTINUABLE_EXCEPTION異常代碼調用回調函數.為了程序的可讀性,可以通過2個預定義值來測試這個位,EXCEPTION_CONTINUABLE(定義為0)和EXCEPTION_NONCONTINUABLE(定義為1)
位1:EXCEPTION_UNWINDING標志.表示回調函數被調用的原因是進行了展開操作
位2:EXCEPTION_UNWINDING_FOR_EXIT標志,表示回調函數被調用的原因是進行最終退出前的展開操作
當異常處理函數的代碼設計得不完善而在運行中引發新的異常時,回調函數會被嵌套調用,在這種情況下EXCEPTION_RECORD結構中的pExceptionRecord字段會指向下一個EXCEPTION_RECORD結構....如果沒有發生嵌套異常,這個值為NULL
?(2)CONTEXT 線程上下文
<span style="font-family:Microsoft YaHei;font-size:13px;">typedef struct _CONTEXT { // // The flags values within this flag control the contents of // a CONTEXT record. // // If the context record is used as an input parameter, then // for each portion of the context record controlled by a flag // whose value is set, it is assumed that that portion of the // context record contains valid context. If the context record // is being used to modify a threads context, then only that // portion of the threads context will be modified. // // If the context record is used as an IN OUT parameter to capture // the context of a thread, then only those portions of the thread's // context corresponding to set flags will be returned. // // The context record is never used as an OUT only parameter. // DWORD ContextFlags; // // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT // included in CONTEXT_FULL. // DWORD Dr0; DWORD Dr1; DWORD Dr2; DWORD Dr3; DWORD Dr6; DWORD Dr7; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_FLOATING_POINT. // FLOATING_SAVE_AREA FloatSave; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_SEGMENTS. // DWORD SegGs; DWORD SegFs; DWORD SegEs; DWORD SegDs; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_INTEGER. // DWORD Edi; DWORD Esi; DWORD Ebx; DWORD Edx; DWORD Ecx; DWORD Eax; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_CONTROL. // DWORD Ebp; DWORD Eip; DWORD SegCs; // MUST BE SANITIZED DWORD EFlags; // MUST BE SANITIZED DWORD Esp; DWORD SegSs; // // This section is specified/returned if the ContextFlags word // contains the flag CONTEXT_EXTENDED_REGISTERS. // The format and contexts are processor specific // BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; } CONTEXT;
typedef CONTEXT *PCONTEXT;
</span>
(3)異常處理程序的返回值
回調函數返回后,Windows執行默認的異常處理程序,這個程序會根據回調函數的返回值決定如何進行下一步動作
回調函數的返回值可以有3種取值:EXCEPTION_EXECUTE_HANDLER(定義為1),EXCEPTION_CONTINUE_SEARCH(定義為0)和EXCEPTION_CONTINUE_EXECUTION(定義為-1)
當返回值為1時,進程將被終止,但是在終止之前,系統不會顯示出錯提示對話框;當返回值為0時,系統同樣將終止程序,但是在終止之前會顯示出錯的提示對話框.使用這2種返回值的時候,異常處理程序完成的工作一般是退出前的掃尾工作.
當返回值為-1時,系統將CONTEXT設置回去的并繼續執行程序..
?
當異常的標志位為EXCEPTION_NONCONTINUABLE的標志位時候,不應該設置EXCEPTION_CONTINUE_EXECUTION返回值,這樣只會引發一個新的異常
?
一個異常處理的小程序? ...
<span style="font-family:Microsoft YaHei;font-size:13px;"> .386.model flat,stdcalloption casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>L macro var:VARARGLOCAL @lbl.const@lbl db var,0.codeexitm <offset @lbl>
endm
.data?
lpOldHandler dd ?
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;功能: 篩選器 ---全局的 Handler --------- 異常處理程序
;參數: 指向一個EXCEPTION_POINTERS
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Handler proc _lpExceptionPointLOCAL @szBuffer[256]:bytepushad;關聯esi到EXCEPTION_POINTERS結構體mov esi,_lpExceptionPointassume esi:ptr EXCEPTION_POINTERSmov edi,[esi].ContextRecord ;指向一個EXCEPTION_RECORD結構mov esi,[esi].pExceptionRecord ;指向一個Thread Context結構assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT;彈出異常信息invoke wsprintf,addr @szBuffer,L("異常發生的位置:%08x,異常代碼:%08X,標志:%08X"),[edi].regEip,[esi].ExceptionCode,[esi].ExceptionFlagsinvoke MessageBox,NULL,addr @szBuffer,L("哈哈--異常啦"),MB_OK;回到安全地方mov [edi].regEip,offset _SafePlaceassume edi:nothing,esi:nothingpopadmov eax,EXCEPTION_CONTINUE_EXECUTIONret
_Handler endpstart:invoke SetUnhandledExceptionFilter,addr _Handlermov lpOldHandler,eax;下面是引發異常的指令xor eax,eaxmov dword ptr [eax],0;這里的代碼沒有被執行哦invoke MessageBox,NULL,L("這里沒有被執行哦"),L("------"),MB_OK;安全地方
_SafePlace:invoke MessageBox,NULL,L("哈哈 到安全地方啦"),L("成功"),MB_OKinvoke SetUnhandledExceptionFilter,lpOldHandler invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start</span>
?
?
?
?
?