| 如果不利用 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 编辑 ]
 |