WEB开发网
开发学院网络安全黑客技术 Structured Exception Handling 阅读

Structured Exception Handling

 2007-01-14 20:14:46 来源:WEB开发网   
核心提示: HomeGrownhandler:ExceptionCode:C0000005ExceptionFlags0HomeGrownhandler:ExceptionCode:C0000027ExceptionFlags2EH_UNWINDINGCaughttheExceptioninmain(
HomeGrownhandler:ExceptionCode:C0000005ExceptionFlags0
HomeGrownhandler:ExceptionCode:C0000027ExceptionFlags2
                       EH_UNWINDING
CaughttheExceptioninmain()

比较由“HomeGrownHandler”开始的两行,其区别是显然的,即第一次的异常标志为0,而第二次则为2。这里就需要提到unwinding的概念。进一步讲,当异常回调拒绝处理异常时,就又被调用了一次。这次回调并没有立即发生,二是更为复杂。我还需要再进一步明确异常发生时的情景。

当异常发生时,系统遍历EXCEPTION_REGISTRATION结构体链表直至找到处理此异常的处理程序。一旦找到了处理程序,系统再一次遍历此链表,直到处理异常的节点。在第二次遍历中,系统对所有的异常处理函数进行第二次调用。关键的区别就是在第二次调用中,异常标志被设为值2。这个值对应着EH_UNWINDING(EH_UNWINDING的定义在VisualC++运行时库源代码的EXCEPT.INC里,但Win32SDK里并没有等价的定义)。

EH_UNWINDING是什么意思呢?当异常回调被第二次调用时(带有EH_UNWINDING标志),操作系统就给处理函数一次做所需清理的机会。什么样的清理呢?一个很好的例子就是C++类的析构函数。当函数的异常处理函数拒绝处理异常时,控制流一般并不会以正常的方式从函数中退出。现在考虑一个函数,此函数声明了一个局部的C++类。C++规范指出析构函数是必须被调用的。第二次标志为EH_UNWINDING的异常处理回调就是为做调用析构函数和_finally块此类的清理工作提供机会。在异常被处理并且所有之前的exceptionframes都被调用以进行unwind之后,程序从回调函数选择的地方继续。但是记住,这并不等于将指令指针设为所要的代码地址并继续执行。继续执行出的代码要求堆栈和帧指针(IntelCPU的ESP和EBP寄存器)都设为在处理异常的堆栈帧中相应的值。因此,接受某一异常的处理程序负责将堆栈指针和堆栈帧指针设为包含处理异常的SEH代码的堆栈帧中的值。

上一页  2 3 4 5 6 7 8 9 10  下一页

Tags:Structured Exception Handling

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接