SetUnhandledExceptionFilter函数学习
2014-02-22 00:54
776 查看
SetUnhandledExceptionFilter函数学习
1、SetUnhandleExceptionFilter函数Windows平台下的C++程序异常通常可分为两种:结构化异常(Structured Exception,可以理解为与操作系统相关的异常)和C++异常。对于结构化异常处理(SEH),可以找到很多资料,在此不细说。对于crash错 误,一般由未被正常捕获的异常引起,Windows操作系统提供了一个API函数可以在程序crash之前有机会处理这些异常,就是 SetUnhandleExceptionFilter函数。(C++也有一个类似函数set_terminate可以处理未被捕获的C++异常。)
SetUnhandleExceptionFilter函数声明如下:
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
__in LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
其中 LPTOP_LEVEL_EXCEPTION_FILTER 定义如下:
typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(
__in struct _EXCEPTION_POINTERS *ExceptionInfo
);
typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
简单来说,SetUnhandleExceptionFilter允许我们设置一个自己的函数作为全局SEH过滤函数,当程序crash前会调用我们的函 数进行处理。我们可以利用的是 _EXCEPTION_POINTERS 结构类型的变量ExceptionInfo,它包含了对异常的描述以及发生异常的线程状态,过滤函数可以通过返回不同的值来让系统继续运行或退出应用程 序。
关于 SetUnhandleExceptionFilter 函数的具体用法和示例请参考MSDN。
首先看下百度上的对此函数的解释。
设置异常捕获函数.
当异常没有处理的时候,系统就会调用SetUnhandledExceptionFilter所设置异常处理函数.
例如一些程序在出错的时候,会向用户报告说程序那出错就是利用这个.例如QQ..
异常处理中的一部分
当发生异常时,比如内存访问违例时,CPU硬件会发现此问题,并产生一个异常(你可以把它理解为中断)
然后CPU会把代码流程切换到异常处理服务例程。操作系统异常处理服务例程会查看当前进程是否处于调试状态
如果时,则通知调试器发生了异常,如果不是则操作系统会查看当前线程是否安装了的异常帧链(FS[0]),如果安装了SEH(try.... catch....),则调用SEH,并根据返回结果决定是否全局展开活局部展开。如果异常链中所有的SEH都没有处理此异常,而且此进程还处于调试状态,则操作系统会再次通知调试器发生异常(二次异常)。如果还没人处理,则调用操作系统的默认异常处理代码UnhandledExceptionHandler,不过操作系统允许你Hook这个函数,就是通过SetUnhandledExceptionFilter函数来设置。大部分异常通过此种方法都能捕获,不过栈溢出、覆盖的有可能捕获不到。
大部分保护壳都采用异常处理技术,跳出正常的代码指令流程,来迷惑Cracker。
说的有点粗略。
下面根据自己的理解阐述下。
SetUnhandledExceptionFilter,根据函数的名字能看出是设置异常处理函数,其实如果程序没设置异常处理函数,程序会调用默认的处理函数处理异常,然后程序终止,一般情况下就弹出个对话框。
如何设置自己的异常处理函数?
LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
参数是一个函数指针,定义如下
LONG UnhandledExceptionFilter(
STRUCT _EXCEPTION_POINTERS *ExceptionInfo
);
函数类型
ExceptionInfo 是对异常描述的一个结构体
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
异常捕获函数有三种返回值
EXCEPTION_EXECUTE_HANDLER:表明异常处理完毕,程序可以退出
EXCEPTION_CONTINUE_EXECUTION:忽略此异常,从异常点继续运行。如果此时再发生异常,还会调用异常处理函数
EXCEPTION_CONTINUE_SEARCH:异常没被识别,交由上一级处理函数处理;
SetUnhandledExceptionFilter返回值,如果为0,表明此时没有附加额外的处理函数(除默认的处理函数),如果非空,则存放到当前顶层的处理函数地址。
需要注意的是,SetUnhandledExceptionFilter设置的异常处理函数为全局的处理函数,是异常发生后,最后一次处理异常的机会。如果程序被调试器附加。调试器将优先于SetUnhandledExceptionFilter设置的异常处理函数处理异常。C++自定义的try{}Catch{}比较。这是C++自定义的异常处理过程,利用SEH来处理发生的异常,如果异常发生,又出现在try{}Catch{}中 将得到优先处理。
相关文章推荐
- 四位科研牛人介绍的文献阅读经验
- cocos2d-x之系统时间和随机数
- 单表数据加载到TreeView(.Node.Level>=2) "蝴蝶效应" SelectedNode注意事项 效能优化 综合问题
- 初试PyOpenGL四 (Python+OpenGL)GPU粒子系统与基本碰撞
- cocos2dx lua json解析
- JS document.URL , windows.location.href 的区别
- 怎样确定研究生论文选题
- eclipse3.5 aptana /myeslipse 8.6 aptana
- Web应用中保证密码传输安全
- 研究生期间怎样发好文章
- SQL serve2008设置用sa登陆
- Javascript 图片自适应不同的屏幕
- As Easy As A+B
- Netty教程—Part1—介绍
- 算法时间复杂度
- 研究生如何读文献 写论文 发文章 毕业论文
- Microsoft report viewer 2012出现无法加载相关dll的解决办法
- c/c++ 有限状态机实现
- extern "C"的用处
- cocos2dx 使用getChildByName()获取不到元素问题