Windows使用筛选器来处理异常
来源:互联网 发布:单片机输入输出 编辑:程序博客网 时间:2024/05/22 11:11
很久木有管博客了 最近也没有学什么
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 STRUCT pExceptionRecord 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;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>includewindows.incincludeuser32.incincludekernel32.incincludelibuser32.libincludelibkernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>L macro var:VARARGLOCAL @lbl.const@lbl db var,0.codeexitm <offset @lbl>endm.data?lpOldHandlerdd?.code;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;功能: 筛选器 ---全局的 Handler --------- 异常处理程序;参数: 指向一个EXCEPTION_POINTERS;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_Handlerproc_lpExceptionPointLOCAL@szBuffer[256]:bytepushad;关联esi到EXCEPTION_POINTERS结构体movesi,_lpExceptionPointassume esi:ptr EXCEPTION_POINTERSmovedi,[esi].ContextRecord;指向一个EXCEPTION_RECORD结构movesi,[esi].pExceptionRecord ;指向一个Thread Context结构assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT;弹出异常信息invokewsprintf,addr @szBuffer,L("异常发生的位置:%08x,异常代码:%08X,标志:%08X"),[edi].regEip,[esi].ExceptionCode,[esi].ExceptionFlagsinvokeMessageBox,NULL,addr @szBuffer,L("哈哈--异常啦"),MB_OK;回到安全地方mov[edi].regEip,offset _SafePlaceassume edi:nothing,esi:nothingpopadmoveax,EXCEPTION_CONTINUE_EXECUTIONret_Handler endpstart:invokeSetUnhandledExceptionFilter,addr _HandlermovlpOldHandler,eax;下面是引发异常的指令xoreax,eaxmovdword ptr [eax],0;这里的代码没有被执行哦invokeMessageBox,NULL,L("这里没有被执行哦"),L("------"),MB_OK;安全地方_SafePlace:invokeMessageBox,NULL,L("哈哈 到安全地方啦"),L("成功"),MB_OKinvokeSetUnhandledExceptionFilter,lpOldHandlerinvokeExitProcess,NULL;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>end start</span>
- Windows使用筛选器来处理异常
- 使用筛选器处理异常
- 筛选器异常处理
- 使用Windows筛选器
- 使用ThreadGroup来处理异常
- JavaScript可以使用try...catch来进行异常处理
- JavaScript可以使用try...catch来进行异常处理
- Android中使用UncaughtExceptionHandler来处理未捕获的异常
- 如何使用 DataView 来筛选数据
- 谨慎使用TakeWhile来筛选数据
- Windows异常处理流程
- Windows异常处理流程
- Windows异常处理流程
- Windows异常处理流程
- windows异常处理剖析
- Windows异常处理流程
- Windows异常处理流程
- Windows异常处理流程
- rman增量备份
- Enum使用方法,为什么使用typedef enum--转载
- WebApp最佳实践用户体验篇之移动设计
- Java HttpClient实例
- 你需要的真是移动App吗?还是一个更好的网站?
- Windows使用筛选器来处理异常
- 信号处理领域英文期刊部分LaTeX模版
- 60款很酷的 jQuery 幻灯片演示和下载
- 防ssh掉线
- Mongodb Aggregation Framework
- JBPM4 常用表结构及其说明
- YiBo微博客户端设置自定义尾巴详细教程之一
- 一个简单的跨域跨数据库事务处理架构
- Messenger:使用消息的跨进程通信