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

来源:互联网 发布:vb.net高级开发指南 编辑:程序博客网 时间:2024/05/23 12:55

If you're feeling a bit overwhelmed at thispoint by things like EXCEPTION_REGISTRATIONs, scopetables, trylevels,filter-expressions, and unwinding, so was I at first. The subject ofcompiler-level structured exception handling does not lend itself to learningincrementally. Much of it doesn't make sense unless you understand the wholeball of wax. When confronted with a lot of theory, my natural inclination is towrite code that applies the concepts I'm learning. If the program works, I knowthat 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 thescopetables that Visual C++ builds for each frame. The program doesn't generateor expect any exceptions. Rather, I included all the _try blocks to forceVisual C++ to generate multiple EXCEPTION_ REGISTRATION frames, with multiplescopetable entries per frame.

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

 

 

The important functions in ShowSEHFramesare WalkSEHFrames and ShowSEHFrame. WalkSEHFrames first prints out the addressof __except_handler3, the reason for which will be clear in a moment. Next, thefunction obtains a pointer to the head of the exception list from FS:[0] andwalks 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 handlingframe. For each node in the list, WalkSEHFrames passes a pointer to the node tothe ShowSEHFrame function.

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

 

ShowSEHFrame starts by printing the addressof the exception frame, the handler callback address, the address of the previousexception frame, and a pointer to the scopetable. Next, for each scopetableentry, the code prints out the previous trylevel, the filter-expressionaddress, and the _except block address. How do I know how many entries are in ascopetable? I don't really. Rather, I assume that the current trylevel in theVC_EXCEPTION_REGISTRATION structure is one less than the total number ofscopetable 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 threeexception frames using __except_handler3 as their callback since ShowSEHFramesplainly has only two functions that use SEH. The third frame comes from theVisual C++ runtime library. The code in CRT0.C from the Visual C++ runtimelibrary 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 inthe WINXFLTR.C file.

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

原创粉丝点击