快速业务通道

Win32结构化异常处理(SEH)探秘(下)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
lCaptureContext函数来创建一个空的CONTEXT结构,这个结构也变成了在展开阶段调用每个异常回调函数时传递给它们的一个参数。

RtlUnwind函数的其余部分遍历EXCEPTION_REGISTRATION结构链表。对于其中的每个帧,它都调用 RtlpExecuteHandlerForUnwind 函数,后面我会讲到这个函数。正是这个函数带 EXCEPTION_UNWINDING 标志调用了异常处理回调函数。每次回调之后,它调用RtlpUnlinkHandler 移除相应的异常帧。

RtlUnwind 函数的第一个参数是一个帧的地址,当它遍历到这个帧时就停止展开异常帧。上面所说的这些代码之间还有一些安全性检查代码,它们用来确保不出问题。如果出现任何问题,RtlUnwind 就引发一个异常,指示出了什么问题,并且这个异常带有EXCEPTION_NONCONTINUABLE 标志。当一个进程被设置了这个标志时,它就不允许再运行,必须终止。

未处理异常

在文章的前面,我并没有全面描述 UnhandledExceptionFilter 这个 API。通常情况下你并不直接调用它(尽管你可以这么做)。大多数情况下它都是由 KERNEL32 中进行默认异常处理的过滤器表达式代码调用。前面 BaseProcessStart 函数的伪代码已经表明了这一点。

图十三是我为 UnhandledExceptionFilter 函数写的伪代码。这个API有点奇怪(至少在我看来是这样)。如果异常的类型是 EXCEPTION_ACCESS_VIOLATION,它就调用_BasepCheckForReadOnlyResource。虽然我没有提供这个函数的伪代码,但可以简要描述一下。如果是因为要对 EXE 或 DLL 的资源节(.rsrc)进行写操作而导致的异常,_BasepCurrentTopLevelFilter 就改变出错页面正常的只读属性,以便允许进行写操作。如果是这种特殊的情况,UnhandledExceptionFilter 返回 EXCEPTION_CONTINUE_EXECUTION,使系统重新执行出错指令。

图十三 UnHandledExceptionFilter 函数的伪代码

UnhandledExceptionFilter( STRUCT _EXCEPTION_POINTERS *pExceptionPtrs )
{ 

PEXCEPTION_RECORD pExcptRec;

DWORD currentESP;

DWORD retValue;

DWORD DEBUGPORT;

DWORD dwTemp2;

DWORD dwUseJustInTimeDebugger;

CHAR szDbgCmdFmt[256]; // 从AeDebug这个注册表键值返回的字符串

CHAR szDbgCmdLine[256]; // 实际的调试器命令行参数(已填入进程ID和事件ID)

STARTUPINFO startupinfo;

PROCESS_INFORMATION pi;

HARDERR_STRUCT harderr; // ???

BOOL fAeDebugAuto;

TIB * pTib; // 线程信息块



pExcptRec = pExceptionPtrs->ExceptionRecord;

if ( (pExcptRec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)

&& (pExcptRec->ExceptionInformation[0]) )

{

retValue=BasepCheckForReadOnlyResource(pExcptRec->ExceptionInformation[1]);

if ( EXCEPTION_CONTINUE_EXECUTION == retValue )


return EXCEPTION_CONTINUE_EXECUTION;

}

// 查看这个进程是否运行于调试器下

retValue = NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,

&debugPort, sizeof(debugPort), 0 );

if ( (retValue >= 0) && debugPort ) // 通知调试器

return EXCEPTION_CONTINUE_SEARCH;

// 用户调用SetUnhandledExceptionFilter了吗?

// 如果调用了,那现在就调用他安装的异常处理程序

if ( _BasepCurrentTopLevelFilter )

{

retValue = _BasepCurrentTopLevelFilter( pExceptionPtrs );

if ( EXCEPTION_EXECUTE_HANDLER == retValue )


return EXCEPTION_EXECUTE_HANDLER;

if ( EXCEPTION_CONTINUE_EXECUTION == retValue )


return EXCEPTION_CONTINUE_EXECUTION;

// 只有返回值为E

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号