快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
我为 KiUserExceptionDispatcher 函数和一些相关函数写的伪代码。这个函数在NTDLL.DLL中,它是异常处理执行的起点。为了绝对准确起见,我必须指出:刚才说的并不是绝对准确。例如在Intel平台上,一个异常导致CPU将控制权转到ring 0(0特权级,即内核模式)的一个处理程序上。这个处理程序由中断描述符表(Interrupt Descriptor Table,IDT)中的一个元素定义,它是专门用来处理相应异常的。我跳过所有的内核模式代码,假设当异常发生时CPU直接将控制权转到了 KiUserExceptionDispatcher 函数。

图十四 KiUserExceptionDispatcher 的伪代码:

KiUserExceptionDispatcher( PEXCEPTION_RECORD pExcptRec, CONTEXT * pContext )
{

DWORD retValue;

// 注意:如果异常被处理,那么 RtlDispatchException 函数就不会返回

if ( RtlDispatchException( pExceptRec, pContext ) )

retValue = NtContinue( pContext, 0 );

else

retValue = NtRaiseException( pExceptRec, pContext, 0 );

EXCEPTION_RECORD excptRec2;

excptRec2.ExceptionCode = retValue;

excptRec2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;

excptRec2.ExceptionRecord = pExcptRec;

excptRec2.NumberParameters = 0;

RtlRaiseException( &excptRec2 );
}

int RtlDispatchException( PEXCEPTION_RECORD pExcptRec, CONTEXT * pContext )
{

DWORD stackUserBase;

DWORD stackUserTop;

PEXCEPTION_REGISTRATION pRegistrationFrame;

DWORD hLog;

// 从FS:[4]和FS:[8]处获取堆栈的界限

RtlpGetStackLimits( &stackUserBase, &stackUserTop );

pRegistrationFrame = RtlpGetRegistrationHead();

while ( -1 != pRegistrationFrame )

{

PVOID justPastRegistrationFrame = &pRegistrationFrame + 8;

if ( stackUserBase > justPastRegistrationFrame )

{


pExcptRec->ExceptionFlags |= EH_STACK_INVALID;


return DISPOSITION_DISMISS; // 0

}

if ( stackUsertop < justPastRegistrationFrame )

{


pExcptRec->ExceptionFlags |= EH_STACK_INVALID;


return DISPOSITION_DISMISS; // 0

}

if ( pRegistrationFrame & 3 ) // 确保堆栈按DWORD对齐

{


pExcptRec->ExceptionFlags |= EH_STACK_INVALID;


return DISPOSITION_DISMISS; // 0

}

if ( someProcessFlag )

{


hLog = RtlpLogExceptionHandler( pExcptRec, pContext, 0,


pRegistrationFrame, 0x10 );

}

DWORD retValue, dispatcherContext;

retValue= RtlpExecuteHandlerForException(pExcptRec, pRegistrationFrame,


pContext, &dispatcherContext,


pRegistrationFrame->handler );

if ( someProcessFlag )


RtlpLogLastExceptionDisposition( hLog, retValue );

if ( 0 == pRegistrationFrame )

{


pExcptRec->ExceptionFlags &= ~EH_NESTED_CALL; // 关闭标志

}

EXCEPTION_RECORD excptRec2;

DWORD yetAnotherValue = 0;

if ( DISPOSITION_DISMISS == retValue )

{


if ( pExcptRec->ExceptionFlags & EH_NONCONTINUABLE )


{


excptRec2.ExceptionRecord = pExcptRec;


excptRec2.ExceptionNumber = STATUS_NONCONTINUABLE_EXCEPTION;


excptRec2.ExceptionFlags  = EH_NONCONTINUABLE;


excptRec2.NumberParameters = 0;


RtlRaiseException( &excptRec2 );


}


else


return DISPOSITION_CONTINUE_SEARC

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号