如果不利用 SEH 的特性跳回异常发生处, 通过 call,pop 来定位异常发生点还是比较方便的.
SEH 是操作系统的一个特性,
Delphi, VC 编译器级别的异常处理应该是差不多的.
VC 用 __except_handler3 来接管用户的异常处理函数,
Delphi 用 _HandleAnyException 来统一处理.
两者都是映射到由操作系统产生的异常处理结构.
再次执行异常发生处, 是操作系统给应用程序一次修复异常的机会.
//------------------------------------------------------------------------------
// 2.再次执行异常发生点的例子
// Written by SkyJacker
//------------------------------------------------------------------------------
var
iEcx: Integer;
// 异常处理函数
function MyExceptHandle(): Integer;
begin
MessageBox(0, 'MyExceptHandle', 'Info', MB_OK);
iEcx := 1; // 修复异常,操作系统给程序一次修复的机会
Result := 0; // 返回异常发生处,再次执行 idiv iEcx
end;
procedure JmpExceptionAddr;
begin
iEcx := 0;
asm
lea eax, MyExceptHandle
push eax
push fs:[0] // 构造新 SEH 节点
mov fs:[0], esp
cdq
idiv iEcx
end;
MessageBox(0, 'OK', 'Hello', 0);
asm
mov eax, [esp]
mov eax, [eax]
mov fs:[0], eax // 恢复原 SEH
add esp, 8 // 堆栈平衡
end;
end;
[ 本帖最后由 skyjacker 于 2007-5-23 10:16 编辑 ]
|