WEB开发网
开发学院软件开发C++ Win32结构化异常处理(SEH)探秘(下) 阅读

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

 2010-10-15 09:07:35 来源:Web开发网   
核心提示:未处理异常在文章的前面,我并没有全面描述 UnhandledExceptionFilter 这个 API,Win32结构化异常处理(SEH)探秘(下)(2),通常情况下你并不直接调用它(尽管你可以这么做),大多数情况下它都是由 KERNEL32 中进行默认异常处理的过滤器表达式代码调用,UnhandledExcepti

未处理异常

在文章的前面,我并没有全面描述 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;

// 只有返回值为EXCEPTION_CONTINUE_SEARCH时才会继续执行下去

}

// 调用过SetErrorMode(SEM_NOGPFAULTERRORBOX)吗?

{

harderr.elem0 = pExcptRec->ExceptionCode;

harderr.elem1 = pExcptRec->ExceptionAddress;

if ( EXCEPTION_IN_PAGE_ERROR == pExcptRec->ExceptionCode )


harderr.elem2 = pExcptRec->ExceptionInformation[2];

else


harderr.elem2 = pExcptRec->ExceptionInformation[0];

dwTemp2 = 1;

fAeDebugAuto = FALSE;

harderr.elem3 = pExcptRec->ExceptionInformation[1];

pTib = FS:[18h];

DWORD someVal = pTib->pProcess->0xC;

if ( pTib->threadID != someVal )

{


__try


{


char szDbgCmdFmt[256];


retValue = GetProfileStringA( "AeDebug", "Debugger", 0,



szDbgCmdFmt, sizeof(szDbgCmdFmt)-1 );


if ( retValue )



dwTemp2 = 2;


char szAuto[8];


retValue = GetProfileStringA( "AeDebug", "Auto", "0",



szAuto, sizeof(szAuto)-1 );


if ( retValue )



if ( 0 == strcmp( szAuto, "1" ) )



if ( 2 == dwTemp2 )




fAeDebugAuto = TRUE;


}


__except( EXCEPTION_EXECUTE_HANDLER )


{


ESP = currentESP;


dwTemp2 = 1;


fAeDebugAuto = FALSE;


}

}

if ( FALSE == fAeDebugAuto )

{


retValue=NtRaiseHardError(STATUS_UNHANDLED_EXCEPTION | 0x10000000,


4, 0, &harderr,_BasepAlreadyHadHardError ? 1 : dwTemp2,


&dwUseJustInTimeDebugger );

}

else

{


dwUseJustInTimeDebugger = 3;


retValue = 0;

}

if (retValue >= 0 && (dwUseJustInTimeDebugger == 3)


&& (!_BasepAlreadyHadHardError)&&(!_BaseRunningInServerProcess))

{


_BasepAlreadyHadHardError = 1;


SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr), 0, TRUE };


HANDLE hEvent = CreateEventA( &secAttr, TRUE, 0, 0 );


memset( &startupinfo, 0, sizeof(startupinfo) );


sprintf(szDbgCmdLine, szDbgCmdFmt, GetCurrentProcessId(), hEvent);


startupinfo.cb = sizeof(startupinfo);


startupinfo.lpDesktop = "Winsta0Default"


CsrIdentifyAlertableThread(); // ??? 


retValue = CreateProcessA( 0,  // 应用程序名称


szDbgCmdLine, // 命令行


0, 0,     // 进程和线程安全属性


1,       // bInheritHandles


0, 0,     // 创建标志、环境


0,       // 当前目录


&statupinfo, // STARTUPINFO


&pi);     // PROCESS_INFORMATION 


if ( retValue && hEvent )


{


NtWaitForSingleObject( hEvent, 1, 0 );


return EXCEPTION_CONTINUE_SEARCH;


}

}

if ( _BasepAlreadyHadHardError )


NtTerminateProcess(GetCurrentProcess(), pExcptRec->ExceptionCode);

}

return EXCEPTION_EXECUTE_HANDLER;
}

LPTOP_LEVEL_EXCEPTION_FILTER
SetUnhandledExceptionFilter(

LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter )
{

// _BasepCurrentTopLevelFilter是KERNEL32.DLL中的一个全局变量

LPTOP_LEVEL_EXCEPTION_FILTER previous= _BasepCurrentTopLevelFilter;

// 设置为新值

_BasepCurrentTopLevelFilter = lpTopLevelExceptionFilter;

return previous; // 返回以前的值
}

上一页  1 2 3 4 5  下一页

Tags:Win 结构化 异常

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