Win32 SEH异常深度探索_5 一个异常帧链表遍历例子

If you're feeling a bit overwhelmed at this point by things like EXCEPTION_REGISTRATIONs, scopetables, trylevels, filter-expressions, and unwinding, so was I at first. The subject of compiler-level structured exception handling does not lend itself to learning incrementally. Much of it doesn't make sense unless you understand the whole ball of wax. When confronted with a lot of theory, my natural inclination is to write code that applies the concepts I'm learning. If the program works, I know that my understanding is (usually) correct.

前面有一大堆名词: EXCEPTION_REGISTRATIONs ( 异常注册 ), scopetables( 异常范围表 ), trylevels(try 块顺序索引 ), filter-expressions( 过滤表达式 ), unwinding( 回退 ) 。你可能会感到疑惑。而编译器生成的异常处理代码更是如此,你必须了解整个细节才能对此有所感觉。我通过一些可以工作的代码来说明我的理解。

 

Figure 10 is the source code for ShowSEHFrames.EXE. It uses _try/_except blocks to set up a list of several Visual C++ SEH frames. Afterwards, it displays information about each frame, as well as the scopetables that Visual C++ builds for each frame. The program doesn't generate or expect any exceptions. Rather, I included all the _try blocks to force Visual C++ to generate multiple EXCEPTION_ REGISTRATION frames, with multiple scopetable entries per frame.

下面一段代码生成了一系列的 SEH 帧并打印出来。 ( 注:这段代码在 VS2005 下需要做很多修改,因为 VS2005 编译器生成的代码和数据结构有了很多变化 )

 

 

The important functions in ShowSEHFrames are WalkSEHFrames and ShowSEHFrame. WalkSEHFrames first prints out the address of __except_handler3, the reason for which will be clear in a moment. Next, the function obtains a pointer to the head of the exception list from FS:[0] and walks each node in the list. Each node is of type VC_EXCEPTION_REGISTRATION, which is a structure that I defined to describe a Visual C++ exception handling frame. For each node in the list, WalkSEHFrames passes a pointer to the node to the ShowSEHFrame function.

ShowSEHFrames 首先打印出 __except_handler3 的地址,然后通过 FS:[0] 获取异常链表的头指针,遍历链表并打印信息。

 

ShowSEHFrame starts by printing the address of the exception frame, the handler callback address, the address of the previous exception frame, and a pointer to the scopetable. Next, for each scopetable entry, the code prints out the previous trylevel, the filter-expression address, and the _except block address. How do I know how many entries are in a scopetable? I don't really. Rather, I assume that the current trylevel in the VC_EXCEPTION_REGISTRATION structure is one less than the total number of scopetable entries.

ShowSEHFrame 可以获取 scopetable 并打印里面信息。

不过这段代码获取 scopetable 的地方在 VS2005 下不能工作,因为 VS2005 是这样保存 scopetable 的:

004020E5  push        offset ___rtc_tzz+11Ch (403870h)          <== Scope table

004020FC  mov        eax,dword ptr [___security_cookie (405004h)]

00402101  xor         dword ptr [ebp-8],eax <== Scope table

也就是它会将 scopetable 的地址值与 ___security_cookie 做个异或,所以取得时候也得做些处理。

同样 scopetable 中有四个 int 空间保存了其他信息,从第五个 int 开始才是 scopetable 内的原素值。

 

You may be wondering why there are three exception frames using __except_handler3 as their callback since ShowSEHFrames plainly has only two functions that use SEH. The third frame comes from the Visual C++ runtime library. The code in CRT0.C from the Visual C++ runtime library sources shows that the call to main or WinMain is wrapped in an _try/_except block. The filter-expression code for this _try block is found in the WINXFLTR.C file.

你运行代码后可能会奇怪打印出来的信息怎么多了一个 SEH 。最后一个来自 VC 运行库,再 CRT0.C 中在调用 main/WinMain 时使用了一个 __try/__except 块包含,其相关 filter-expression 代码在 WINXFLTR.C 中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值