引言:_except_handler3是BaseProcessStart的异常处理函数。
相应的伪代码:
EXCEPTION_DISPOSITION __cdecl __except_handler3 (
_In_ struct _EXCEPTION_RECORD *argExceptionRecord,
_In_ void * argEstablisherFrame,
_Inout_ struct _CONTEXT *argContextRecord,
_Inout_ void * argDispatcherContext
)
{
EXCEPTION_POINTERS varXPointers;
DWORD dwTryLevel,dwRetFilter;
//方向标志复位
__asm cld
if(!(argExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND_CONTEXT))
{
varXPointers->ExceptionRecord = argExceptionRecord;
varXPointers->ContextRecord = argContextRecord;
//提供VC++扩展SEH的异常帧结构中的[ebp-14]值
//内联函数GetExceptionInformation将从[ebp-14]提取信息
(PEXCEPTION_POINTERS)((DWORD)argEstablisherFrame-4)= &varXPointers;
//验证SEH异常帧
if(__ValidateEH3RN(argEstablisherFrame))
{
//一个函数仅有一个异常帧,一个函数可以有多个__try/__except结构
//嵌套的__try/__except通过scopetable->prevtrylevel关联起来
//向上搜索当前异常帧中嵌套的__try/__except过滤函数和处理函数
dwTryLevel = argEstablisherFrame->trylevel;
while(dwTryLevel != 0xFFFFFFFF)
{
//不存在过滤函数,继续向上一层__try/__except搜索
if(!argEstablisherFrame->scopetable[dwTryLevel].lpfnFilter)
{
dwTryLevel = argEstablisherFrame->scopetable[dwTryLevel].prevtrylevel;
continue;
}
//保存当前ebp
__asm push ebp
//切换ebp回lpfnFilter所在位置
__asm lea ebp,&argEstablisherFrame->_ebp;
//调用过滤函数
dwRetFilter = argEstablisherFrame->scopetable[dwTryLevel].lpfnFilter();
//恢复当前ebp
__asm pop ebp
//检查过滤函数的返回值
if(dwRetFilter == EXCEPTION_CONTINUE_SEARCH)
{
dwTryLevel = argEstablisherFrame->scopetable[dwTryLevel].prevtrylevel;
continue;
}
else if(dwRetFilter == EXCEPTION_CONTINUE_EXECUTION)
{
//异常已经修复,重新执行引发异常的指令
return ExceptionContinueExecution;
}
//找到__except(EXCEPTION_EXECUTE_HANDLER)
//全局展开
__global_unwind2(argEstablisherFrame);
//切换ebp,注意:之前没有保存当前ebp
__asm lea ebp,&argEstablisherFrame->_ebp;
//对当前__try/__except进行局部展开
__local_unwind2(argEstablisherFrame,dwTryLevel);
//作用未知!
__NLG_Notify(1);
//把异常帧的trylevel设置成__except(EXCEPTION_EXECUTE_HANDLER)
//的上一个__try/__except
argEstablisherFrame->trylevel =
argEstablisherFrame->scopetable[dwTryLevel].prevtrylevel;
//调用__except {}块,这个调用并不会返回
argEstablisherFrame->scopetable[dwTryLevel].lpfnHandler();
}
//当前异常帧搜索结束,但仍然没有找到__except(EXCEPTION_EXECUTE_HANDLER)
//向下一个异常帧搜索,也就是向__except_handler3的调用函数搜索异常帧
return ExceptionContinueSearch;
}
else
{
//异常帧的栈无效
//向下一个异常帧搜索,也就是向__except_handler3的调用函数搜索异常帧
if(argExceptionRecord->ExceptionFlags==EXCEPTION_STACK_INVALID)
{
return ExceptionContinueSearch;
}
}
}
else
{
//保存当前ebp
__asm push ebp
//切换ebp回引发异常的函数
__asm lea,&argEstablisherFrame->_ebp;
//对引发异常的函数进行局部展开
__local_unwind2(argEstablisherFrame,0xFFFFFFFF);
//恢复当前ebp
__asm pop ebp
return ExceptionContinueSearch;
}
}
示意图(也就是__try/__except的示意图):
遗留:还不太清楚__NLG_Notify的作用,哪位朋友可以提点一下,非常感谢!!附__NLG_Notify: