首页
社区
课程
招聘
[原创]SEH分析笔记(X86篇)
发表于: 2011-10-5 12:46 37093

[原创]SEH分析笔记(X86篇)

2011-10-5 12:46
37093

历史:
        v1.0.0, 2011-10-05:最初版本。
        v1.0.1, 2011-10-06:补充总结之前的资源泄漏示例。
        v1.0.2, 2011-10-31:调整若干描述语句;增加 ExceptionNestedException 返回值的补充说明。
        注:本帖内容没有同步更新,请下载附件。

[不介意转载,但请注明出处 boxcounter.com
     附件里有本文的原始稿,一样的内容,更好的高亮和排版。分别是 html 和 rtl 格式。
     后面的部分代码可能会因为自动换行变得很乱,需要的朋友手动复制到自己的代码编辑器就可以正常显示了]

        这两天琢磨了下SEH,这里记录一下自己琢磨的一些心得。
        SEH 这个概念我就不啰嗦了,任何一个介绍 SEH 的资料都有讲。我主要记录一些自己的理解。可能有一些概念理解的不够清晰,有一些说法比较狭隘,欢迎看到本文的朋友一起讨论、修正,非常感谢。
        首先,SEH 是针对于异常的一种处理机制,这个异常分为硬件异常和软件异常,这里所说的硬件异常是狭义的异常,也就是 CPU 产生的异常。比如除零操作,CPU 执行除零操作时候,会自主启动异常处理机制。软件异常,就是程序模拟的异常,比如调用 RaiseException 函数。软件异常是可以随意触发的,windows 系统内部遇到问题会触发,开发人员高兴了也可以触发。
        抛出了问题,就要有解决方案。那这么多问题和解决方案,如何管理呢?windows 系统当仁不让的提供了它管理方案 —— SEH。我看一些资料有详细的讨论 SEH 的确切含义,这里我不参与讨论,而只是简单的理解为“系统提供的异常处理机制,以及编译器对其进行增强的部分”。

        来说说系统提供的异常处理机制。
        windows 提供的异常处理机制实际上只是一个简单的框架,一般情况下开发人员都不会直接用到。咱通常所用的异常处理(比如 C++ 的 throw、try、catch)都是编译器在系统提供的异常处理机制上进行加工了的增强版本。这里先抛开增强版的不提,继续说原始版本。
        原始版本的机制很简单:谁都可以触发异常,谁都可以处理异常(只要它能看得见)。但是不管是触发还是处理都得先登记。系统把这些登记信息保存在一个链表里,并且这个链表保存在线程的数据结构里。也就是说,异常所涉及的一些行为都是线程相关的。比如,线程 T1 触发的异常就只能由线程 T1 来处理,其他线程根本就不知道 T1 发生了什么事,更不会狗拿耗子。
        等登记完毕后,线程就可以抛出或处理异常了,系统也可以做相应的管理工作了。(这里啰嗦一句,系统提供的 SEH 其实是一个针对于“触发异常-解决异常”的管理机制,系统自身是不提供任何具体异常的解决方案的。解决方案还是要由用户自身来提供(增强版里编译器也会来提供解决方案,来帮“不负责”的程序猿擦屁股,这是后话))
        系统提供的管理工作简单来说包括(但不限于):找到触发异常的线程的异常处理链表(前头登记的那个),然后按照规则(具体的规则后续再说)对该异常进行分发,根据分发后的处理结果再进行下一步的分发或者结束处理。
        系统管理所使用的数据结构和宏:

[font=Consolas][color=#000000]    [/color][color=#0000FF]#define [/color][color=#000000]EXCEPTION_CHAIN_END [/color][color=#000080](([/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_REGISTRATION_RECORD [/color][color=#000080]* [/color][color=#000000]POINTER_32[/color][color=#000080])-[/color][color=#800080]1[/color][color=#000080])

    [/color][color=#0000FF]typedef enum [/color][color=#000000]_EXCEPTION_DISPOSITION [/color][color=#000080]{
        [/color][color=#000000]ExceptionContinueExecution[/color][color=#000080],
        [/color][color=#000000]ExceptionContinueSearch[/color][color=#000080],
        [/color][color=#000000]ExceptionNestedException[/color][color=#000080],
        [/color][color=#000000]ExceptionCollidedUnwind
    [/color][color=#000080]} [/color][color=#000000]EXCEPTION_DISPOSITION[/color][color=#000080];

    [/color][color=#0000FF]typedef struct [/color][color=#000000]_EXCEPTION_RECORD [/color][color=#000080]{
        [/color][color=#000000]DWORD ExceptionCode[/color][color=#000080];
        [/color][color=#000000]DWORD ExceptionFlags[/color][color=#000080];
        [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_RECORD [/color][color=#000080]*[/color][color=#000000]ExceptionRecord[/color][color=#000080];
        [/color][color=#000000]PVOID ExceptionAddress[/color][color=#000080];
        [/color][color=#000000]DWORD NumberParameters[/color][color=#000080];
        [/color][color=#000000]ULONG_PTR ExceptionInformation[/color][color=#000080][[/color][color=#000000]EXCEPTION_MAXIMUM_PARAMETERS[/color][color=#000080]];
    } [/color][color=#000000]EXCEPTION_RECORD[/color][color=#000080];

    [/color][color=#0000FF]typedef [/color][color=#000000]EXCEPTION_RECORD [/color][color=#000080]*[/color][color=#000000]PEXCEPTION_RECORD[/color][color=#000080];

    [/color][color=#0000FF]typedef
    [/color][color=#000000]EXCEPTION_DISPOSITION
    [/color][color=#000080](*[/color][color=#000000]PEXCEPTION_ROUTINE[/color][color=#000080]) (
        [/color][color=#000000]IN [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_RECORD [/color][color=#000080]*[/color][color=#000000]ExceptionRecord[/color][color=#000080],
        [/color][color=#000000]IN PVOID EstablisherFrame[/color][color=#000080],
        [/color][color=#000000]IN OUT [/color][color=#0000FF]struct [/color][color=#000000]_CONTEXT [/color][color=#000080]*[/color][color=#000000]ContextRecord[/color][color=#000080],
        [/color][color=#000000]IN OUT PVOID DispatcherContext
        [/color][color=#000080]);

    [/color][color=#0000FF]typedef struct [/color][color=#000000]_EXCEPTION_REGISTRATION_RECORD [/color][color=#000080]{
        [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_REGISTRATION_RECORD [/color][color=#000080]*[/color][color=#000000]Next[/color][color=#000080];
        [/color][color=#000000]PEXCEPTION_ROUTINE Handler[/color][color=#000080];
    } [/color][color=#000000]EXCEPTION_REGISTRATION_RECORD[/color][color=#000080];

    [/color][color=#0000FF]typedef [/color][color=#000000]EXCEPTION_REGISTRATION_RECORD [/color][color=#000080]*[/color][color=#000000]PEXCEPTION_REGISTRATION_RECORD[/color][color=#000080];
[/color][/font]
[font=Consolas][color=#000000]    [/color][color=#0000FF]typedef struct [/color][color=#000000]_EXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION[/color][color=#000080];
    [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_REGISTRATION[/color][color=#000080]{
        [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_REGISTRATION [/color][color=#000080]*[/color][color=#000000]prev[/color][color=#000080];
        [/color][color=#0000FF]void [/color][color=#000080](*[/color][color=#000000]handler[/color][color=#000080])([/color][color=#000000]PEXCEPTION_RECORD[/color][color=#000080], [/color][color=#000000]PEXCEPTION_REGISTRATION[/color][color=#000080], [/color][color=#000000]PCONTEXT[/color][color=#000080], [/color][color=#000000]PEXCEPTION_RECORD[/color][color=#000080]);
        [/color][color=#0000FF]struct [/color][color=#000000]scopetable_entry [/color][color=#000080]*[/color][color=#000000]scopetable[/color][color=#000080];
        [/color][color=#0000FF]int [/color][color=#000000]trylevel[/color][color=#000080];
        [/color][color=#0000FF]int [/color][color=#000000]_ebp[/color][color=#000080];
        [/color][color=#000000]PEXCEPTION_POINTERS xpointers[/color][color=#000080];
    };[/color][/font]
[font=Consolas][color=#000000]    [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_REGISTRATION[/color][color=#000080]{
        [/color][color=#0000FF]struct [/color][color=#000000]_EXCEPTION_REGISTRATION_RECORD ExceptionRegistrationRecord[/color][color=#000080];
        [/color][color=#0000FF]struct [/color][color=#000000]scopetable_entry [/color][color=#000080]*[/color][color=#000000]scopetable[/color][color=#000080];
        [/color][color=#0000FF]int [/color][color=#000000]trylevel[/color][color=#000080];
        [/color][color=#0000FF]int [/color][color=#000000]_ebp[/color][color=#000080];
        [/color][color=#000000]PEXCEPTION_POINTERS xpointers[/color][color=#000080];
    }; [/color][color=#008000]// 注:本结构体只用于理解原始版和增强版的区别,实际代码中并没有这种形式的定义    [/color][/font]

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 10
支持
分享
最新回复 (49)
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
一、SEH 创建代码
        这里我没有继续使用上面的 SimpleSeh 进行分析,而是新写了一个简单的 SehTest 函数。
[font=Consolas][color=#000000]        VOID SehTest[color=#000080]()
        {
            [color=#000000]ULONG ulVal [color=#000080]= [color=#800080]0[color=#000080];

            [color=#000000]__try [color=#008000]// 第一个 __try 域
            [color=#000080]{
                [color=#000000]ulVal [color=#000080]= [color=#800080]0x11111111[color=#000080]; [color=#008000]// 最后一位为1表示“在 __try 代码块中”
            [color=#000080]}
            [color=#000000]__except[color=#000080]([color=#000000]Filter_0[color=#000080]())
            {
                [color=#000000]ulVal [color=#000080]= [color=#800080]0x11111110[color=#000080]; [color=#008000]// 最后一位为0表示“在 __except/__finally 代码块中”
            [color=#000080]}

            [color=#000000]__try [color=#008000]// 第二个 __try 域
            [color=#000080]{
                [color=#000000]ulVal [color=#000080]= [color=#800080]0x22222222[color=#000080];

                [color=#000000]__try [color=#008000]// 第三个 __try 域
                [color=#000080]{
                    [color=#000000]ulVal [color=#000080]= [color=#800080]0x33333333[color=#000080];

                    *(([color=#000000]ULONG[color=#000080]*)[color=#000000]NULL[color=#000080]) = [color=#000000]ulVal[color=#000080]; [color=#008000]// 触发异常
                [color=#000080]}
                [color=#000000]__finally
                [color=#000080]{
                    [color=#000000]ulVal [color=#000080]= [color=#800080]0x33333330[color=#000080];
                }
            }
            [color=#000000]__except[color=#000080]([color=#000000]Filter_2[color=#000080]())
            {
                [color=#000000]ulVal [color=#000080]= [color=#800080]0x22222220[color=#000080];
            }

            [color=#0000FF]return[color=#000080];
        }
[/font]


        反汇编代码如下:
        (需要说明一下我的命名习惯是,"l_"前缀的变量是函数的局部变量,没有任何前缀的变量是传入的参数)

kd> uf passthrough!SehTest
;PassThrough!SehTest [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 604]:
f8720040 mov edi,edi
f8720042 push ebp ; l_ExceptionRegistration->_ebp
f8720043 mov ebp,esp
f8720045 push 0FFFFFFFEh ; l_ExceptionRegistration->trylevel = TRYLEVEL_INVALID (-2)
f8720047 push offset PassThrough!__safe_se_handler_table+0x8 (f8721468) ; l_ExceptionRegistration->scopetable
f872004c push offset PassThrough!_except_handler4 (f8720390) ; l_ExceptionRegistration->handler
f8720051 mov eax,dword ptr fs:[00000000h]
f8720057 push eax ; _EXCEPTION_REGISTRATION::prev
f8720058 add esp,0FFFFFFF4h ; 这里分配了 0xc 字节的栈空间,其中紧贴着 l_ExceptionRegistration->prev
; 的4个字节存放着 l_ExceptionRegistration->xpointers
f872005b push ebx
f872005c push esi
f872005d push edi
f872005e mov eax,dword ptr [PassThrough!__security_cookie (f87220b0)]
f8720063 xor dword ptr [ebp-8],eax ; 对 scopetable 进行异或加密
f8720066 xor eax,ebp ; 对 __security_cookie 进行加密
f8720068 push eax ; 把加密了的 __security_cookie 也压入栈中,后面用来对 scopetable 进行解密
f8720069 lea eax,[ebp-10h]
f872006c mov dword ptr fs:[00000000h],eax ; 将 l_ExceptionRegistration 挂入线程异常链表中
f8720072 mov dword ptr [ebp-18h],esp
f8720075 mov dword ptr [ebp-1Ch],0
f872007c mov dword ptr [ebp-4],0 ; 进入第一个 __try 域,l_ExceptionRegistration->trylevel = 0
f8720083 mov dword ptr [ebp-1Ch],11111111h
f872008a mov dword ptr [ebp-4],0FFFFFFFEh ; 离开第一个 __try 域,l_ExceptionRegistration->trylevel = TRYLEVEL_NONE (-2)
f8720091 jmp PassThrough!SehTest+0x6a (f87200aa)
; ---------------------------------------------------------------------------------
; 这里有个空洞,用 uf 命令是不会显示的。范围是 f8720093 到 f87200a9,汇编码如下
;
; PassThrough!SehTest+0x53 [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 611]:
; f8720093 call PassThrough!Filter_0 (f8720010)
; f8720098 ret
;
; f8720099 mov esp,dword ptr [ebp-18h] ; 第一个 __except 处理域
; f872009c mov dword ptr [ebp-1Ch],11111110h
; f87200a3 mov dword ptr [ebp-4],0FFFFFFFEh ; 离开第一个 __try 域,l_ExceptionRegistration->trylevel = TRYLEVEL_NONE (-2)
; ---------------------------------------------------------------------------------
;PassThrough!SehTest+0x6a [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 616]:
f87200aa mov dword ptr [ebp-4],1 ; 进入第二个 __try 域,l_ExceptionRegistration->trylevel = 1
f87200b1 mov dword ptr [ebp-1Ch],22222222h
f87200b8 mov dword ptr [ebp-4],2 ; 进入第三个 __try 域,l_ExceptionRegistration->trylevel = 2
f87200bf mov dword ptr [ebp-1Ch],33333333h
f87200c6 mov eax,dword ptr [ebp-1Ch]
f87200c9 mov dword ptr ds:[00000000h],eax ; 触发异常
f87200ce mov dword ptr [ebp-4],1 ; 离开第三个 __try 域,l_ExceptionRegistration->trylevel = 1
f87200d5 call PassThrough!SehTest+0x9c (f87200dc)
f87200da jmp PassThrough!SehTest+0xa4 (f87200e4)
; ---------------------------------------------------------------------------------
; 空洞,范围是 f87200dc 到 f87200e3,汇编码如下
;
; PassThrough!SehTest+0x9c [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 628]:
; f87200dc c745e430333333 mov dword ptr [ebp-1Ch],33333330h ; __finally 域
; ---------------------------------------------------------------------------------
;PassThrough!SehTest+0xa4 [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 630]:
f87200e4 mov dword ptr [ebp-4],0FFFFFFFEh ; 离开第二个 __try 域,l_ExceptionRegistration->trylevel = TRYLEVEL_NONE (-2)
f87200eb jmp PassThrough!SehTest+0xc4 (f8720104)
; ---------------------------------------------------------------------------------
; 空洞,范围是 f87200ed 到 f8720103,汇编码如下
;
; PassThrough!SehTest+0xad [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 631]:
; f87200ed e83effffff call PassThrough!Filter_2 (f8720030)
; f87200f2 c3 ret
;
; f87200f3 8b65e8 mov esp,dword ptr [ebp-18h] ; 第二个 __except 处理域
; f87200f6 c745e420222222 mov dword ptr [ebp-1Ch],22222220h
; f87200fd c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh ; 离开第三个 __try 域,l_ExceptionRegistration->trylevel = TRYLEVEL_NONE (-2)
; ---------------------------------------------------------------------------------
;PassThrough!SehTest+0xc4 [d:\workspace\code\mycode\r0\passthrough\passthrough.c @ 637]:
f8720104 mov ecx,dword ptr [ebp-10h]
f8720107 mov dword ptr fs:[0],ecx ; 恢复旧的 EXCEPTION_REGISTRATION。即从线程异常链表中摘除 l_ExceptionRegistration
f872010e pop ecx
f872010f pop edi
f8720110 pop esi
f8720111 pop ebx
f8720112 mov esp,ebp
f8720114 pop ebp
f8720115 ret


        来看看 scopetable 的内容:

        kd> dd f8721468
        f8721468  fffffffe 00000000 ffffffd4 00000000  < 16个字节的坑
        f8721478  [fffffffe f8720093 f8720099] [fffffffe
        f8721488  f87200ed f87200f3] [00000001 00000000
        f8721498  f87200dc] 00000000 00000000 00000000
        f87214a8  00000000 00000000 00000000 00000000
        f87214b8  00000000 00000000 00000000 00000000
        f87214c8  00000000 00000000 00000000 00000000
        f87214d8  00000000 00000000 00000000 00000000

        前16个字节是坑,坑的作用晚点再说。之后就是三个 scopetable_entry,被我用大括号扩起来了。对照前面的汇编码可以发现,scopetable_entry::lpfnFilter 和 scopetable_entry::lpfnHandler 就是汇编码中的空洞处的代码。其中,第三个 scopetable_entry::lpfnFilter 是 NULL,对照代码可以发现,是因为这是一个 __try & __finally 块,没有 lpfnFilter。

        汇编代码很简单,注释里也有详细的分析过程了,我不再多啰嗦。只提两点:
        1. EXCEPTION_REGISTRATION::scopetable 指针被用 __security_cookie 进行了异或加密。
        2. EXCEPTION_REGISTRATION::scopetable 并不直接指向 scopetable_entry 数组,在第一个 scopetable_entry 之前有 16 个字节的坑。后续分析中会看到,它的主要作用是帮助验证 scopetable 是否被破坏。第三个 DWORD,即上文中的 ffffffd4 是一个偏移量,后续的分析过程中会看得很清楚。
2011-10-5 12:54
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
二、MSC 提供的 EXCEPTION_REGISTRATION::handler 函数
        之前咱们有说过 EXCEPTION_REGISTRATION::handler 指向由 MSC 编译器提供的一个函数,这个函数内部负责调用 scopetable[?]->lpfnFilter/lpfnHandler。这个函数通常为 module!_except_handler?,其中module为模块名,? 表示某数字。在分析过程中发现,有的模块完整实现了该函数,有的模块直接使用了系统提供的 nt!_except_handler?。不知道是因为版本的问题,还是编译选项的问题。我没有深究。
        我继续以 passhThrough 模块为例,来说明这个函数。
        首先需要再次说明一下我的注释习惯:后续列出来的反汇编代码中,最左边的:<>符号表示跳转,是我在分析的过程中为了方便理解流程手写的。其中 < 表示跳转源,> 是跳转目标,: 用于组成连接线。
        为了方便对照,我把经过整理的 PassThrough!_except_handler4 的原型列在这里:

        EXCEPTION_DISPOSITION _except_handler4 (
            PEXCEPTION_RECORD pExceptionRecord,
            PEXCEPTION_REGISTRATION pExceptionRegistration,
            PCONTEXT,
            PDISPATCHER_CONTEXT
        );

        反汇编代码:
[font=Consolas][color=#000000]    kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_except_handler4
                  PassThrough!_except_handler4 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]255[/color][color=#0A246A]]:
                    [/color][color=#000000]f8720390  [/color][color=#0A246A]mov     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
                    [/color][color=#000000]f8720392  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
                    [/color][color=#000000]f8720393  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp
                    [/color][color=#000000]f8720395  [/color][color=#0A246A]sub     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]14h
                    [/color][color=#000000]f8720398  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
                    [/color][color=#000000]f8720399  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration
                    [/color][color=#000000]f872039c  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
                    [/color][color=#000000]f872039d  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; esi = pExceptionRegistration->scopetable
                    [/color][color=#000000]f87203a0  [/color][color=#0A246A]xor     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A])]    [/color][color=#008000]; 用 __security_cookie 对 scopetable 解密
                    [/color][color=#000000]f87203a6  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
                    [/color][color=#000000]f87203a7  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]]
                    [/color][color=#000000]f87203a9  [/color][color=#0A246A]mov     byte ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]1[/color][color=#0A246A]],[/color][color=#800080]0   [/color][color=#008000]; ebp-1 存放的是一个 BOOLEAN 值,用来表示是否执行过任何 scopetable_entry::lpfnFilter
                    [/color][color=#000000]f87203ad  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#800080]1  [/color][color=#008000]; ebp-8 被用来存放本函数的返回值,这里初始化为 ExceptionContinueSearch (1)
                    [/color][color=#000000]f87203b4  [/color][color=#0A246A]lea     [/color][color=#FF8000]edi[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]]        [/color][color=#008000]; edi = pExceptionRegistration->_ebp 
                    [/color][color=#000000]f87203b7  [/color][color=#0A246A]cmp     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh       [/color][color=#008000]; 检查 scopetable 中坑的第一个 DWORD 值,后续来做相关的安全处理
[/color][color=#0A246A]<                   [/color][color=#000000]f87203ba  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x39 [/color][color=#0A246A]([/color][color=#000000]f87203c9[/color][color=#0A246A])
:                  
:                 [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x2c [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]315[/color][color=#0A246A]]:
:                   [/color][color=#008000]; 校验 scopetable 完整性(1)
[/color][color=#0A246A]:                   [/color][color=#000000]f87203bc  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]]
:                   [/color][color=#000000]f87203bf  [/color][color=#0A246A]add     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]:                   [/color][color=#000000]f87203c1  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]]
:                   [/color][color=#000000]f87203c4  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
:                 
:                 [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x39 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]315[/color][color=#0A246A]]:
:                   [/color][color=#008000]; 校验 scopetable 完整性(2)
[/color][color=#0A246A]>                  [/color][color=#000000]f87203c9  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]
                   [/color][color=#000000]f87203cc  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
                   [/color][color=#000000]f87203cf  [/color][color=#0A246A]add     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi
                   [/color][color=#000000]f87203d1  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]]
                   [/color][color=#000000]f87203d4  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
                    [/color][color=#008000]; 安全工作处理完毕,开始进入异常处理流程
                   [/color][color=#000000]f87203d9  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]     [/color][color=#008000]; eax = pExceptionRecord
                   [/color][color=#000000]f87203dc  [/color][color=#0A246A]test    byte ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]66h      [/color][color=#008000]; pExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND,判断是异常处理过程还是展开过程
[/color][color=#0A246A]<                  [/color][color=#000000]f87203e0  [/color][color=#0A246A]jne     [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x138 [/color][color=#0A246A]([/color][color=#000000]f87204c8[/color][color=#0A246A])
:                 
:                 [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x56 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]331[/color][color=#0A246A]]:
:                   [/color][color=#008000]; 异常处理过程
[/color][color=#0A246A]:                   [/color][color=#000000]f87203e6  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]]   [/color][color=#008000]; ecx = pContext
[/color][color=#0A246A]:                   [/color][color=#000000]f87203e9  [/color][color=#0A246A]lea     [/color][color=#FF8000]edx[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]14h[/color][color=#0A246A]]
:                   [/color][color=#000000]f87203ec  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]edx     [/color][color=#008000]; ebx-4 是创建 EXCEPTION_REGISTRATION 时候预留的 xpointers 的空间,这里给它赋值
[/color][color=#0A246A]:                   [/color][color=#000000]f87203ef  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]   [/color][color=#008000]; ebx = pExceptionRegistration->trylevel
[/color][color=#0A246A]:                   [/color][color=#000000]f87203f2  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]14h[/color][color=#0A246A]],[/color][color=#FF8000]eax   [/color][color=#008000]; [ebp-14] = pExceptionRecord,即 xpointers->ExceptionRecord = pExceptionRecord
[/color][color=#0A246A]:                   [/color][color=#000000]f87203f5  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]10h[/color][color=#0A246A]],[/color][color=#FF8000]ecx   [/color][color=#008000]; [ebp-10] = pContext,即 xpointers->ContextRecord = pContext
[/color][color=#0A246A]:                   [/color][color=#000000]f87203f8  [/color][color=#0A246A]cmp     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh            [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_INVALID
[/color][color=#0A246A]: <                 [/color][color=#000000]f87203fb  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A]([/color][color=#000000]f872045c[/color][color=#0A246A])
: :               
: :               [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x6d [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]341[/color][color=#0A246A]]:
: :                 [/color][color=#000000]f87203fd  [/color][color=#0A246A]lea     [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]ecx[/color][color=#0A246A]]
: :               
: :               [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x70 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]343[/color][color=#0A246A]]:
: :       >         [/color][color=#000000]f8720400  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]ebx[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]] [/color][color=#008000]; 这里 *3,下面紧接着 *4,即 *12,实际上是为了跳过 x 个 scopetable_entry (大小为12个字节)
[/color][color=#0A246A]: :       :         [/color][color=#000000]f8720403  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]eax[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; ecx = scopetable[i].lpfnFilter, 这里14h是为了跳过10h大小的坑
[/color][color=#0A246A]: :       :         [/color][color=#000000]f8720407  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]eax[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; eax = &scopetable[i]
[/color][color=#0A246A]: :       :         [/color][color=#000000]f872040b  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; ebp-0Ch 存放的是 pCurrentScopeTableEntry
[/color][color=#0A246A]: :       :         [/color][color=#000000]f872040e  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]] [/color][color=#008000]; eax = scopetable[i].previousTryLevel
[/color][color=#0A246A]: :       :         [/color][color=#000000]f8720410  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; 这里是将 ebp+8 当作局部变量使用, [ebp+8] = scopetable[i].previousTryLevel
[/color][color=#0A246A]: :       :         [/color][color=#000000]f8720413  [/color][color=#0A246A]test    [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#008000]; 判断 scopetable[i].lpfnFilter 是否为 NULL
[/color][color=#0A246A]: : <     :         [/color][color=#000000]f8720415  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x9b [/color][color=#0A246A]([/color][color=#000000]f872042b[/color][color=#0A246A])
: : :     :       
: : :     :       [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x87 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]355[/color][color=#0A246A]]:
: : :     :         [/color][color=#008000]; scopetable[i].lpfnFilter 不为 NULL,调用它
[/color][color=#0A246A]: : :     :         [/color][color=#000000]f8720417  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#008000]; edx = pExceptionRegistration->_ebp
[/color][color=#0A246A]: : :     :         [/color][color=#000000]f8720419  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_EH4_CallFilterFunc [/color][color=#0A246A]([/color][color=#000000]f87205d1[/color][color=#0A246A])
: : :     :         [/color][color=#000000]f872041e  [/color][color=#0A246A]mov     byte ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]1[/color][color=#0A246A]],[/color][color=#800080]1 [/color][color=#008000]; [ebp-1] 表示是否执行过 lpfnFilter,它是个 BOOLEAN 值
[/color][color=#0A246A]: : :     :         [/color][color=#000000]f8720422  [/color][color=#0A246A]test    [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
[/color][color=#0A246A]: : : <   :         [/color][color=#000000]f8720424  [/color][color=#0A246A]jl      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xd6 [/color][color=#0A246A]([/color][color=#000000]f8720466[/color][color=#0A246A]) [/color][color=#008000]; 如果是 EXCEPTION_CONTINUE_EXECUTION (-1) 就跳
[/color][color=#0A246A]: : : :   :       
: : : :   :       [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x96 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]370[/color][color=#0A246A]]:
: : : : < :         [/color][color=#000000]f8720426  [/color][color=#0A246A]jg      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xdf [/color][color=#0A246A]([/color][color=#000000]f872046f[/color][color=#0A246A]) [/color][color=#008000]; 如果是 EXCEPTION_EXECUTE_HANDLER (1) 就跳
[/color][color=#0A246A]: : : : : :       
: : : : : :       [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x98 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]370[/color][color=#0A246A]]:
: : : : : :         [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_CONTINUE_SEARCH
[/color][color=#0A246A]: : : : : :         [/color][color=#000000]f8720428  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = scopetable[i].previousTryLevel 
[/color][color=#0A246A]: : : : : :       
: : : : : :       [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x9b [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]341[/color][color=#0A246A]]:
: : > : : :         [/color][color=#000000]f872042b  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]eax
[/color][color=#0A246A]: :   : : :         [/color][color=#000000]f872042d  [/color][color=#0A246A]cmp     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp scopetable[i].previousTryLevel, TRYLEVEL_INVALID
[/color][color=#0A246A]: :   : : <         [/color][color=#000000]f8720430  [/color][color=#0A246A]jne     [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x70 [/color][color=#0A246A]([/color][color=#000000]f8720400[/color][color=#0A246A])
: :   : :         
: :   : :         [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]478[/color][color=#0A246A]]:
: :   : :           [/color][color=#000000]f8720432  [/color][color=#0A246A]cmp     byte ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]1[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; 没有执行过 lpfnFilter,无需进行安全检查
[/color][color=#0A246A]: : < : :           [/color][color=#000000]f8720436  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A]([/color][color=#000000]f872045c[/color][color=#0A246A])
: : : : :         
: : : : :         [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa8 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]486[/color][color=#0A246A]]:
: : : : :           [/color][color=#008000]; 执行过 lpfnFilter,需要校验完整性
[/color][color=#0A246A]: : : : :   >   >   [/color][color=#000000]f8720438  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]] 
: : : : :   :   :   [/color][color=#000000]f872043a  [/color][color=#0A246A]cmp     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; 根据 scopetable 坑的第一个 DWORD 值判断是否需要做进一步的安全检查
[/color][color=#0A246A]: : : : : < :   :   [/color][color=#000000]f872043d  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xbc [/color][color=#0A246A]([/color][color=#000000]f872044c[/color][color=#0A246A])
: : : : : : :   : 
: : : : : : :   : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xaf [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]486[/color][color=#0A246A]]:
: : : : : : :   :   [/color][color=#008000]; 校验 scopetable 完整性(1)
[/color][color=#0A246A]: : : : : : :   :   [/color][color=#000000]f872043f  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]]
: : : : : : :   :   [/color][color=#000000]f8720442  [/color][color=#0A246A]add     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]: : : : : : :   :   [/color][color=#000000]f8720444  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]]
: : : : : : :   :   [/color][color=#000000]f8720447  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
: : : : : : :   : 
: : : : : : :   : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xbc [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]486[/color][color=#0A246A]]:
: : : : : : :   :   [/color][color=#008000]; 校验 scopetable 完整性(2)
[/color][color=#0A246A]: : : : : > :   :   [/color][color=#000000]f872044c  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]
: : : : :   :   :   [/color][color=#000000]f872044f  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
: : : : :   :   :   [/color][color=#000000]f8720452  [/color][color=#0A246A]add     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]: : : : :   :   :   [/color][color=#000000]f8720454  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]] [/color][color=#008000]; 正常情况下 [edx+edi] 保存的是 __security_cookie 的值
[/color][color=#0A246A]: : : : :   :   :   [/color][color=#000000]f8720457  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
: : : : :   :   : 
: : : : :   :   : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]495[/color][color=#0A246A]]:
: > > : :   : > :   [/color][color=#000000]f872045c  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]]
:     : :   : : :   [/color][color=#000000]f872045f  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
[/color][color=#0A246A]:     : :   : : :   [/color][color=#000000]f8720460  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
[/color][color=#0A246A]:     : :   : : :   [/color][color=#000000]f8720461  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
[/color][color=#0A246A]:     : :   : : :   [/color][color=#000000]f8720462  [/color][color=#0A246A]mov     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp
[/color][color=#0A246A]:     : :   : : :   [/color][color=#000000]f8720464  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
[/color][color=#0A246A]:     : :   : : :   [/color][color=#000000]f8720465  [/color][color=#0A246A]ret
:     : :   : : : 
:     : :   : : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xd6 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]367[/color][color=#0A246A]]:
:     : :   : : :   [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_CONTINUE_EXECUTION
[/color][color=#0A246A]:     > :   : : :   [/color][color=#000000]f8720466  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; [ebp-8] = ExceptionContinueExecution (0)
[/color][color=#0A246A]:       :   < : :   [/color][color=#000000]f872046d  [/color][color=#0A246A]jmp     [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa8 [/color][color=#0A246A]([/color][color=#000000]f8720438[/color][color=#0A246A])
:       :     : : 
:       :     : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xdf [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]396[/color][color=#0A246A]]:
:       :     : :   [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER
[/color][color=#0A246A]:       >     : :   [/color][color=#000000]f872046f  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRegistration
[/color][color=#0A246A]:             : :   [/color][color=#000000]f8720472  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_EH4_GlobalUnwind [/color][color=#0A246A]([/color][color=#000000]f87205fa[/color][color=#0A246A])
:             : :   [/color][color=#000000]f8720477  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration
[/color][color=#0A246A]:             : :   [/color][color=#000000]f872047a  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ebx [/color][color=#008000]; cmp pExceptionRegistration->trylevel
[/color][color=#0A246A]: <           : :   [/color][color=#000000]f872047d  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x101 [/color][color=#0A246A]([/color][color=#000000]f8720491[/color][color=#0A246A])
: :           : : 
: :           : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xef [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]408[/color][color=#0A246A]]:
: :           : :   [/color][color=#000000]f872047f  [/color][color=#0A246A]push    offset [/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A])
: :           : :   [/color][color=#000000]f8720484  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
[/color][color=#0A246A]: :           : :   [/color][color=#000000]f8720485  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]ebx
[/color][color=#0A246A]: :           : :   [/color][color=#000000]f8720487  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; ecx = pExceptionRegistration
[/color][color=#0A246A]: :           : :   [/color][color=#000000]f8720489  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_EH4_LocalUnwind [/color][color=#0A246A]([/color][color=#000000]f8720614[/color][color=#0A246A])
: :           : :   [/color][color=#000000]f872048e  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]
: :           : : 
: :           : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x101 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]417[/color][color=#0A246A]]:
: >           : :   [/color][color=#000000]f8720491  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; ecx = scopetable[i].previousTryLevel 
[/color][color=#0A246A]:             : :   [/color][color=#000000]f8720494  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration->trylevel = scopetable[i].previousTryLevel 
[/color][color=#0A246A]:             : :   [/color][color=#000000]f8720497  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]]
:             : :   [/color][color=#000000]f8720499  [/color][color=#0A246A]cmp     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh
[/color][color=#0A246A]: <           : :   [/color][color=#000000]f872049c  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x11b [/color][color=#0A246A]([/color][color=#000000]f87204ab[/color][color=#0A246A])
: :           : : 
: :           : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x10e [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]431[/color][color=#0A246A]]:
: :           : :   [/color][color=#008000]; 校验 scopetable 完整性(1)
[/color][color=#0A246A]: :           : :   [/color][color=#000000]f872049e  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]]
: :           : :   [/color][color=#000000]f87204a1  [/color][color=#0A246A]add     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]: :           : :   [/color][color=#000000]f87204a3  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]]
: :           : :   [/color][color=#000000]f87204a6  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
: :           : : 
: :           : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x11b [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]431[/color][color=#0A246A]]:
: :           : :   [/color][color=#008000]; 校验 scopetable 完整性(2)
[/color][color=#0A246A]: >           : :   [/color][color=#000000]f87204ab  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]
:             : :   [/color][color=#000000]f87204ae  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
:             : :   [/color][color=#000000]f87204b1  [/color][color=#0A246A]add     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]:             : :   [/color][color=#000000]f87204b3  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]+[/color][color=#FF8000]edi[/color][color=#0A246A]]
:             : :   [/color][color=#000000]f87204b6  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
:             : :   [/color][color=#008000]; 调用 lpfnHandler
[/color][color=#0A246A]:             : :   [/color][color=#000000]f87204bb  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = l_pCurrentScopeTableEntry
[/color][color=#0A246A]:             : :   [/color][color=#000000]f87204be  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; ecx = l_pCurrentScopeTableEntry->lpfnHandler
[/color][color=#0A246A]:             : :   [/color][color=#000000]f87204c1  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edi                 [/color][color=#008000]; edx = pExceptionRegistration->_ebp
[/color][color=#0A246A]:             : :   [/color][color=#000000]f87204c3  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_EH4_TransferToHandler [/color][color=#0A246A]([/color][color=#000000]f87205e8[/color][color=#0A246A]) [/color][color=#008000]; 这里不会返回!!
[/color][color=#0A246A]:             : : 
:             : : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x138 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]456[/color][color=#0A246A]]:
>             : :   [/color][color=#000000]f87204c8  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh
              [/color][color=#0A246A]: :   [/color][color=#000000]f87204cd  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]edx [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_INVALID
              [/color][color=#0A246A]< :   [/color][color=#000000]f87204d0  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xcc [/color][color=#0A246A]([/color][color=#000000]f872045c[/color][color=#0A246A])
                : 
                : [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0x142 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\chandler4.c @ [/color][color=#800080]467[/color][color=#0A246A]]:
                :   [/color][color=#008000]; pExceptionRegistration->trylevel 不等于 TRYLEVEL_INVALID,开始局部展开
                [/color][color=#0A246A]:   [/color][color=#000000]f87204d2  [/color][color=#0A246A]push    offset [/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A])
                :   [/color][color=#000000]f87204d7  [/color][color=#0A246A]push    [/color][color=#FF8000]edi      [/color][color=#008000]; pExceptionRegistration->_ebp
                [/color][color=#0A246A]:   [/color][color=#000000]f87204d8  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ebx  [/color][color=#008000]; ecx = pExceptionRegistration
                [/color][color=#0A246A]:   [/color][color=#000000]f87204da  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_EH4_LocalUnwind [/color][color=#0A246A]([/color][color=#000000]f8720614[/color][color=#0A246A])
                <   [/color][color=#000000]f87204df  [/color][color=#0A246A]jmp     [/color][color=#000000]PassThrough!_except_handler4[/color][color=#0A246A]+[/color][color=#800080]0xa8 [/color][color=#0A246A]([/color][color=#000000]f8720438[/color][color=#0A246A])
[/color][/font]


        这个函数代码不长。主要分为两个大分支,一个分支处理异常,一个分支处理展开(参考地址 f87203dc 处的 test 指令)。
        处理异常的代码负责遍历 scopetable,依次调用 scopetable_entry::lpfnFilter(参考 f8720419 处代码),并针对不同的返回值做出不同的处理:
        1. 返回 EXCEPTION_CONTINUE_EXECUTION,则说明异常已经被刚刚调用的 lpfnFilter 修复。返回 ExceptionContinueExecution。
        2. 返回 EXCEPTION_CONTINUE_SEARCH,则继续遍历下一个 scopetable_entry。
        3. 返回 EXCEPTION_EXECUTE_HANDLER,则说明当前 scopetable_entry::lpfnHandler 负责处理该异常。于是调用它。
        对于展开的代码,则直接开始局部展开,即对 scopetable 进行展开。
        更具体的信息,请参考上面反汇编代码中我附的注释。

        有几个小点需要说一下:
        1. 该函数多处使用 scopetable 中坑内的数据进行安全检查。这些操作对理解该函数流程没有帮助,可以忽略。如果觉得上面代码不纯净,可以参考我后续的附录1《Ntfs!_except_handler3 的反汇编代码》,这个函数流程更清晰简单。
        2. 一旦有某 scopetable_entry::lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER,就会进行全局展开和局部展开。展开结束后会调用该 scopetable_entry::lpfnHandler,该函数即为 _except 处理域,该函数形式是一个函数,实际上只是一段不返回的代码。即这段代码中没有 ret 指令。执行完整个 _except 处理域后,会接着执行其后的指令,并不会返回 _except_handler4。
        3. 该函数既启动展开,又负责展开,于是会出现类似于“重入”的现象。理解的过程中容易扰乱思路。

        PassThrough!_except_handler4 在执行过程中可能会调用这几个函数:
        PassThrough!_EH4_CallFilterFunc、
        PassThrough!_EH4_TransferToHandler、
        PassThrough!_EH4_GlobalUnwind、
        PassThrough!_EH4_LocalUnwind
        这几个函数名很明白的说明了它们的功能:
        PassThrough!_EH4_CallFilterFunc 负责调用 scopetable_entry::lpfnFilter;
        PassThrough!_EH4_TransferToHandler 负责调用 scopetable_entry::lpfnFilter;
        PassThrough!_EH4_GlobalUnwind 负责全局展开;
        PassThrough!_EH4_LocalUnwind 负责局部展开。

        来看看 _EH4_CallFilterFunc 和 _EH4_TransferToHandler 的反汇编代码,都很短。剩余两个展开相关的函数稍后咱们再来分析。

[font=Consolas][color=#000000]    kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_CallFilterFunc
        PassThrough!_EH4_CallFilterFunc [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]408[/color][color=#0A246A]]:
          [/color][color=#000000]f87205d1  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
          [/color][color=#000000]f87205d2  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
          [/color][color=#000000]f87205d3  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
          [/color][color=#000000]f87205d4  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
          [/color][color=#000000]f87205d5  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]edx
          [/color][color=#000000]f87205d7  [/color][color=#0A246A]xor     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
          [/color][color=#000000]f87205d9  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx
          [/color][color=#000000]f87205db  [/color][color=#0A246A]xor     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx
          [/color][color=#000000]f87205dd  [/color][color=#0A246A]xor     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi
          [/color][color=#000000]f87205df  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
          [/color][color=#000000]f87205e1  [/color][color=#0A246A]call    [/color][color=#FF8000]ecx [/color][color=#008000]; lpfnFilter();
          [/color][color=#000000]f87205e3  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
          [/color][color=#000000]f87205e4  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
          [/color][color=#000000]f87205e5  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
          [/color][color=#000000]f87205e6  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
          [/color][color=#000000]f87205e7  [/color][color=#0A246A]ret

    [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_TransferToHandler
        PassThrough!_EH4_TransferToHandler [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]450[/color][color=#0A246A]]:
          [/color][color=#000000]f87205e8  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]edx
          [/color][color=#000000]f87205ea  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#008000]; esi = lpfnHandler
          [/color][color=#000000]f87205ec  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]ecx
          [/color][color=#000000]f87205ee  [/color][color=#0A246A]xor     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
          [/color][color=#000000]f87205f0  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx
          [/color][color=#000000]f87205f2  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx
          [/color][color=#000000]f87205f4  [/color][color=#0A246A]xor     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx
          [/color][color=#000000]f87205f6  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
          [/color][color=#000000]f87205f8  [/color][color=#0A246A]jmp     [/color][color=#FF8000]esi     [/color][color=#008000]; jmp lpfnHandler
[/color][/font]


        到这里,咱们就以 PassThrough!_except_handler4 为例分析完了 MSC 提供的 EXCEPTION_REGISTRATION::handler 函数。这个过程中多次接触到一个名为“展开”的概念,这就是咱们要讲的第三个部分。
2011-10-5 12:55
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
三、展开 (unwind)
        为了说明这个概念,需要先回顾下异常发生后的处理流程。

        我们假设一系列使用 SEH 的函数调用流程:
        func1 -> func2 -> func3。在 func3 执行的过程中触发了异常。

        看看分发异常流程 RtlRaiseException -> RtlDispatchException -> RtlpExecuteHandlerForException
        RtlDispatchException 会遍历异常链表,对每个 EXCEPTION_REGISTRATION 都调用 RtlpExecuteHandlerForException。
        RtlpExecuteHandlerForException 会调用 EXCEPTION_REGISTRATION::handler,也就是 PassThrough!_except_handler4。如咱们上面分析,该函数内部遍历 EXCEPTION_REGISTRATION::scopetable,如果遇到有 scopetable_entry::lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER,那么 scopetable_entry::lpfnHandler 就会被调用,来处理该异常。
        因为 lpfnHandler 不会返回到 PassThrough!_except_handler4,于是执行完 lpfnHandler 后,就会从 lpfnHandler 之后的代码继续执行下去。也就是说,假设 func3 中触发了一个异常,该异常被 func1 中的 __except 处理块处理了,那 __except 处理块执行完毕后,就从其后的指令继续执行下去,即异常处理完毕后,接着执行的就是 func1 的代码。不会再回到 func2 或者 func3,这样就有个问题,func2 和 func3 中占用的资源怎么办?这些资源比如申请的内存是不会自动释放的,岂不是会有资源泄漏问题?

        这就需要用到“展开”了。
        说白了,所谓“展开”就是进行清理。(注:这里的清理主要包含动态分配的资源的清理,栈空间是由 func1 的“mov esp,ebp” 这类操作顺手清理的。当时我被“谁来清理栈空间”这个问题困扰了很久……)
       
        那这个展开工作由谁来完成呢?由 func1 来完成肯定不合适,毕竟 func2 和 func3 有没有申请资源、申请了哪些资源,func1 无从得知。于是这个展开工作还得要交给 func2 和 func3 自己来完成。

        展开分为两种:“全局展开”和“局部展开”。
        全局展开是指针对异常链表中的某一段,局部展开针对指定 EXCEPTION_REGISTRATION。用上面的例子来讲,局部展开就是针对 func3 或 func2 (某一个函数)内部进行清理,全局展开就是 func2 和 func3 的局部清理的总和。再归纳一下,局部展开是指具体某一函数内部的清理,而全局展开是指,从异常触发点(func3)到异常处理点(func1)之间所有函数(包含异常触发点 func3)的局部清理的总和。

        来看反汇编代码:
[font=Consolas][color=#000000]    kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_GlobalUnwind
        PassThrough!_EH4_GlobalUnwind [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]485[/color][color=#0A246A]]:
          [/color][color=#000000]f87205fa   [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
          [/color][color=#000000]f87205fb   [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp
          [/color][color=#000000]f87205fd   [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
          [/color][color=#000000]f87205fe   [/color][color=#0A246A]push    [/color][color=#FF8000]esi
          [/color][color=#000000]f87205ff   [/color][color=#0A246A]push    [/color][color=#FF8000]edi
          [/color][color=#000000]f8720600   [/color][color=#0A246A]push    [/color][color=#800080]0   [/color][color=#008000]; pReturnValue
          [/color][color=#000000]f8720602   [/color][color=#0A246A]push    [/color][color=#800080]0   [/color][color=#008000]; pExceptionRecord
          [/color][color=#000000]f8720604   [/color][color=#0A246A]push    offset [/color][color=#000000]PassThrough!_EH4_GlobalUnwind[/color][color=#0A246A]+[/color][color=#800080]0x15 [/color][color=#0A246A]([/color][color=#000000]f872060f[/color][color=#0A246A]) [/color][color=#008000]; pReturnEip
          [/color][color=#000000]f8720609   [/color][color=#0A246A]push    [/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration
          [/color][color=#000000]f872060a   [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!RtlUnwind [/color][color=#0A246A]([/color][color=#000000]f8720678[/color][color=#0A246A])
          [/color][color=#000000]f872060f   [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
          [/color][color=#000000]f8720610   [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
          [/color][color=#000000]f8720611   [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
          [/color][color=#000000]f8720612   [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
          [/color][color=#000000]f8720613   [/color][color=#0A246A]ret
[/color][/font]


        RtlUnwind 的原型:
        VOID RtlUnwind(
            PEXCEPTION_REGISTRATION pExceptionRegistration
            PVOID pReturnEip
            PEXCEPTION_RECORD pExceptionRecord,
            PVOID pReturnValue
        );

[font=Consolas][color=#000000]    kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!RtlUnwind [/color][color=#008000]; 提示:此函数 wrk 提供了实现源码
                  [/color][color=#000000]nt!RtlUnwind [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]423[/color][color=#0A246A]]:
                    [/color][color=#800080]80867358  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
                    [/color][color=#800080]80867359  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp
                    [/color][color=#800080]8086735b  [/color][color=#0A246A]sub     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]37Ch
                    80867361  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#000000]nt!__security_cookie [/color][color=#0A246A]([/color][color=#800080]80895388[/color][color=#0A246A])]
                    [/color][color=#800080]80867366  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
                    [/color][color=#800080]80867367  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRecord
                    [/color][color=#800080]8086736a  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]eax
                    [/color][color=#800080]8086736d  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
                    [/color][color=#800080]8086736e  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D8h[/color][color=#0A246A]] [/color][color=#008000]; [ebp-2D8h] = l_pHighLimit
                    [/color][color=#800080]80867374  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
                    [/color][color=#800080]80867375  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D4h[/color][color=#0A246A]] [/color][color=#008000]; [ebp-2D4h] = l_pLowLimit
                    [/color][color=#800080]8086737b  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
                    [/color][color=#800080]8086737c  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlpGetStackLimits [/color][color=#0A246A]([/color][color=#800080]80887cdc[/color][color=#0A246A])
                    [/color][color=#800080]80867381  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
                    [/color][color=#800080]80867383  [/color][color=#0A246A]cmp     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]edi [/color][color=#008000]; pExceptionRecord 是否为 NULL
[/color][color=#0A246A]<                   [/color][color=#800080]80867385  [/color][color=#0A246A]jne     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x5a [/color][color=#0A246A]([/color][color=#800080]808673b2[/color][color=#0A246A])
:                 
:                 [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x2f [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]452[/color][color=#0A246A]]:
:                   [/color][color=#800080]80867387  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]]
:                   [/color][color=#800080]8086738a  [/color][color=#0A246A]lea     [/color][color=#FF8000]esi[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]37Ch[/color][color=#0A246A]] [/color][color=#008000]; ebp-37Ch 是局部变量 l_ExceptionRecord
[/color][color=#0A246A]:                   [/color][color=#800080]80867390  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]37Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000027h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_UNWIND
[/color][color=#0A246A]:                   [/color][color=#800080]8086739a  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]378h[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = 0
[/color][color=#0A246A]:                   [/color][color=#800080]808673a0  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]374h[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = NULL
[/color][color=#0A246A]:                   [/color][color=#800080]808673a6  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]370h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; l_ExceptionRecord.ExceptionAddress = ret_addr (PassThrough!RtlUnwind 执行完毕后的返回地址)
[/color][color=#0A246A]:                   [/color][color=#800080]808673ac  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]36Ch[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; l_ExceptionRecord.ExceptionInformation[0] = 0;
[/color][color=#0A246A]:                 
:                 [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x5a [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]462[/color][color=#0A246A]]:
>                   [/color][color=#800080]808673b2  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; pExceptionRegistration 是否为 NULL
 [/color][color=#0A246A]<                  [/color][color=#800080]808673b5  [/color][color=#0A246A]je      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x65 [/color][color=#0A246A]([/color][color=#800080]808673bd[/color][color=#0A246A])
 :                
 :                [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x5f [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]463[/color][color=#0A246A]]:
 :                  [/color][color=#800080]808673b7  [/color][color=#0A246A]or      dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]2 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING (0x2)
 [/color][color=#0A246A]:<                 [/color][color=#800080]808673bb  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x69 [/color][color=#0A246A]([/color][color=#800080]808673c1[/color][color=#0A246A])
 ::               
 ::               [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x65 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]466[/color][color=#0A246A]]:
 >:                 [/color][color=#800080]808673bd  [/color][color=#0A246A]or      dword ptr [[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6 [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND (0x2 | 0x4)
  [/color][color=#0A246A]:               
  :               [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x69 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]466[/color][color=#0A246A]]:
  >                 [/color][color=#800080]808673c1  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
                    [/color][color=#800080]808673c2  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; ebp-2D0 是局部变量 l_Context
                    [/color][color=#800080]808673c8  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
                    [/color][color=#800080]808673c9  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]],[/color][color=#800080]10007h [/color][color=#008000]; lContext.ContextFlags = CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS (0x10000 | 0x1 | 0x2 | 0x3)

                    [/color][color=#800080]808673d3  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlpCaptureContext [/color][color=#0A246A]([/color][color=#800080]80887c50[/color][color=#0A246A])
                    [/color][color=#800080]808673d8  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; eax = ReturnValue
                    [/color][color=#800080]808673db  [/color][color=#0A246A]add     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]20Ch[/color][color=#0A246A]],[/color][color=#800080]10h [/color][color=#008000]; -20C = -2D0+C4, lContext.Esp += 0x10
                    [/color][color=#800080]808673e2  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]220h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; -220 = -2D0+B0, lContext.Eax = ReturnValue
                    [/color][color=#800080]808673e8  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlpGetRegistrationHead [/color][color=#0A246A]([/color][color=#800080]80887d04[/color][color=#0A246A])
                    [/color][color=#800080]808673ed  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; ebx = 异常链表头,这里暂命名为 l_pExceptionRegistration
[/color][color=#0A246A]<                   [/color][color=#800080]808673ef  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1d1 [/color][color=#0A246A]([/color][color=#800080]80867529[/color][color=#0A246A])
:                 
:                 [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x9c [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]500[/color][color=#0A246A]]:
:              >    [/color][color=#800080]808673f4  [/color][color=#0A246A]cmp     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; cmp l_pExceptionRegistration,pExceptionRegistration 
[/color][color=#0A246A]:<             :    [/color][color=#800080]808673f7  [/color][color=#0A246A]jne     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xb0 [/color][color=#0A246A]([/color][color=#800080]80867408[/color][color=#0A246A])
::             :  
::             :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xa1 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]501[/color][color=#0A246A]]:
::             :    [/color][color=#008000]; pExceptionRegistration 等于 l_pExceptionRegistration,说明展开完毕
[/color][color=#0A246A]::             :    [/color][color=#800080]808673f9  [/color][color=#0A246A]push    [/color][color=#FF8000]edi [/color][color=#008000]; TestAlert = FALSE
[/color][color=#0A246A]::             :    [/color][color=#800080]808673fa  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_Context
[/color][color=#0A246A]::             :    [/color][color=#800080]80867400  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
[/color][color=#0A246A]::             :    [/color][color=#800080]80867401  [/color][color=#0A246A]call    [/color][color=#000000]nt!ZwContinue [/color][color=#0A246A]([/color][color=#800080]8082c0b8[/color][color=#0A246A]) [/color][color=#008000];  这里不会返回
[/color][color=#0A246A]::<            :    [/color][color=#800080]80867406  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A]([/color][color=#800080]8086743e[/color][color=#0A246A])
:::            :  
:::            :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xb0 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]509[/color][color=#0A246A]]:
:>:            :    [/color][color=#800080]80867408  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]edi [/color][color=#008000]; cmp pExceptionRegistration, NULL
[/color][color=#0A246A]: :<           :    [/color][color=#800080]8086740b  [/color][color=#0A246A]je      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A]([/color][color=#800080]8086743e[/color][color=#0A246A])
: ::           :  
: ::           :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xb5 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]509[/color][color=#0A246A]]:
: ::           :    [/color][color=#800080]8086740d  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]ebx [/color][color=#008000]; cmp pExceptionRegistration,l_pExceptionRegistration
[/color][color=#0A246A]: ::<          :    [/color][color=#800080]80867410  [/color][color=#0A246A]jae     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A]([/color][color=#800080]8086743e[/color][color=#0A246A])
: :::          :  
: :::          :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xba [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]514[/color][color=#0A246A]]:
: :::          :    [/color][color=#008000]; pExceptionRegistration 在 l_pExceptionRegistration 之下,即 pExceptionRegistration 超出了异常链表的栈范围
[/color][color=#0A246A]: :::          :    [/color][color=#800080]80867412  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]] [/color][color=#008000]; ebp-32Ch 是局部变量 l_ExceptionRecord
[/color][color=#0A246A]: :::          :    [/color][color=#800080]80867418  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
[/color][color=#0A246A]: :::          :    [/color][color=#800080]80867419  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000029h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_INVALID_UNWIND_TARGET
[/color][color=#0A246A]: :::          :    [/color][color=#800080]80867423  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]328h[/color][color=#0A246A]],[/color][color=#800080]1          [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE (1)
[/color][color=#0A246A]: :::          :    [/color][color=#800080]8086742d  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]324h[/color][color=#0A246A]],[/color][color=#FF8000]esi        [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = &l_ExceptionRecord
[/color][color=#0A246A]: :::          :    [/color][color=#800080]80867433  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]31Ch[/color][color=#0A246A]],[/color][color=#FF8000]edi        [/color][color=#008000]; l_ExceptionRecord.NumberParameters = 0
[/color][color=#0A246A]: :::          :    [/color][color=#800080]80867439  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlRaiseException [/color][color=#0A246A]([/color][color=#800080]80887a94[/color][color=#0A246A])
: :::          :  
: :::          :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xe6 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]530[/color][color=#0A246A]]:
: >>>          :    [/color][color=#800080]8086743e  [/color][color=#0A246A]cmp     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D4h[/color][color=#0A246A]] [/color][color=#008000]; cmp l_pExceptionRegistration, l_pLowLimit
[/color][color=#0A246A]:              :    [/color][color=#800080]80867444  [/color][color=#0A246A]lea     [/color][color=#FF8000]edi[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; edi = l_pExceptionRegistration->scopetable_entry
[/color][color=#0A246A]:    <         :    [/color][color=#800080]80867447  [/color][color=#0A246A]jb      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x162 [/color][color=#0A246A]([/color][color=#800080]808674ba[/color][color=#0A246A]) [/color][color=#008000]; l_pExceptionRegistration 低于线程栈底,跳到错误处理
[/color][color=#0A246A]:    :         :  
:    :         :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xf1 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]530[/color][color=#0A246A]]:
:    :         :    [/color][color=#800080]80867449  [/color][color=#0A246A]cmp     [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D8h[/color][color=#0A246A]] [/color][color=#008000]; cmp l_pExceptionRegistration->scopetable_entry,l_pHighLimit
[/color][color=#0A246A]:    :<        :    [/color][color=#800080]8086744f  [/color][color=#0A246A]ja      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x162 [/color][color=#0A246A]([/color][color=#800080]808674ba[/color][color=#0A246A]) [/color][color=#008000]; l_pExceptionRegistration 高于线程栈顶,跳到错误处理
[/color][color=#0A246A]:    ::        :  
:    ::        :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0xf9 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]530[/color][color=#0A246A]]:
:    ::        :    [/color][color=#008000]; l_pExceptionRegistration 处于合法栈中,检查它是否正确对齐
[/color][color=#0A246A]:    ::        :    [/color][color=#800080]80867451  [/color][color=#0A246A]test    [/color][color=#FF8000]bl[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; 检查 l_pExceptionRegistration 是否4字节对齐
[/color][color=#0A246A]:    ::<       :    [/color][color=#800080]80867454  [/color][color=#0A246A]jne     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 没对齐,跳到错误处理
[/color][color=#0A246A]:    :::       :  
:    :::       :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x102 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]580[/color][color=#0A246A]]:
:    :::       :    [/color][color=#008000]; 进行局部展开
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]8086745a  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; l_pExceptionRegistration->Handler
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]8086745d  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2DCh[/color][color=#0A246A]] [/color][color=#008000]; 这里是局部变量 l_DispatchContext
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]80867463  [/color][color=#0A246A]push    [/color][color=#FF8000]eax [/color][color=#008000];
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]80867464  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_Context
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]8086746a  [/color][color=#0A246A]push    [/color][color=#FF8000]eax [/color][color=#008000]; l_Context
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]8086746b  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx [/color][color=#008000]; l_pExceptionRegistration
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]8086746c  [/color][color=#0A246A]push    [/color][color=#FF8000]esi [/color][color=#008000]; &l_ExceptionRecord
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]8086746d  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlpExecuteHandlerForUnwind [/color][color=#0A246A]([/color][color=#800080]80887b54[/color][color=#0A246A]) [/color][color=#008000]; 内部调用 l_pExceptionRegistration->Handler
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]80867472  [/color][color=#0A246A]dec     [/color][color=#FF8000]eax
[/color][color=#0A246A]:    :::<      :    [/color][color=#800080]80867473  [/color][color=#0A246A]je      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x156 [/color][color=#0A246A]([/color][color=#800080]808674ae[/color][color=#0A246A]) [/color][color=#008000]; 如果返回 ExceptionContinueSearch 则跳转
[/color][color=#0A246A]:    ::::      :  
:    ::::      :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x11d [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]586[/color][color=#0A246A]]:
:    ::::      :    [/color][color=#800080]80867475  [/color][color=#0A246A]dec     [/color][color=#FF8000]eax
[/color][color=#0A246A]:    ::::      :    [/color][color=#800080]80867476  [/color][color=#0A246A]dec     [/color][color=#FF8000]eax
[/color][color=#0A246A]:    :::: <    :    [/color][color=#800080]80867477  [/color][color=#0A246A]je      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x150 [/color][color=#0A246A]([/color][color=#800080]808674a8[/color][color=#0A246A]) [/color][color=#008000]; 如果返回 ExceptionCollidedUnwind 则跳转
[/color][color=#0A246A]:    :::: :    :  
:    :::: :    :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x121 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]621[/color][color=#0A246A]]:
:    :::: :    :    [/color][color=#008000]; 返回 ExceptionContinueSearch 和 ExceptionCollidedUnwind 之外的非法值
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]80867479  [/color][color=#0A246A]and     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]31Ch[/color][color=#0A246A]],[/color][color=#800080]0          [/color][color=#008000]; l_ExceptionRecord.NumberParameters = 0
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]80867480  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_ExceptionRecord
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]80867486  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]80867487  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000026h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_INVALID_DISPOSITION
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]80867491  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]328h[/color][color=#0A246A]],[/color][color=#800080]1          [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE (1)
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]8086749b  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]324h[/color][color=#0A246A]],[/color][color=#FF8000]esi        [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = &l_ExceptionRecord
[/color][color=#0A246A]:    :::: :    :    [/color][color=#800080]808674a1  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlRaiseException [/color][color=#0A246A]([/color][color=#800080]80887a94[/color][color=#0A246A])
:    ::::<:    :    [/color][color=#800080]808674a6  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x156 [/color][color=#0A246A]([/color][color=#800080]808674ae[/color][color=#0A246A])
:    ::::::    :  
:    ::::::    :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x150 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]608[/color][color=#0A246A]]:
:    ::::::    :    [/color][color=#008000]; RtlpExecuteHandlerForUnwind 返回 ExceptionCollidedUnwind,从 l_DispatchContext.RegistrationPointer 继续处理
[/color][color=#0A246A]:    :::::>    :    [/color][color=#800080]808674a8  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2DCh[/color][color=#0A246A]] [/color][color=#008000]; l_pExceptionRegistration = l_DispatchContext.RegistrationPointer
[/color][color=#0A246A]:    :::::     :  
:    :::::     :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x156 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]630[/color][color=#0A246A]]:
:    :::::     :    [/color][color=#008000]; 局部展开完毕,从异常链表中摘除 l_pExceptionRegistration
[/color][color=#0A246A]:    :::>>     :    [/color][color=#800080]808674ae  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]ebx [/color][color=#008000]; eax = l_pExceptionRegistration
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]808674b0  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]] [/color][color=#008000]; l_pExceptionRegistration = l_pExceptionRegistration.prev
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]808674b2  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
[/color][color=#0A246A]:    :::       :    [/color][color=#800080]808674b3  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlpUnlinkHandler [/color][color=#0A246A]([/color][color=#800080]80887c10[/color][color=#0A246A]) [/color][color=#008000]; 摘除
[/color][color=#0A246A]:    :::<      :    [/color][color=#800080]808674b8  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1cf [/color][color=#0A246A]([/color][color=#800080]80867527[/color][color=#0A246A])
:    ::::      :  
:    ::::      :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x162 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]540[/color][color=#0A246A]]:
:    ::::      :    [/color][color=#008000]; l_pExceptionRegistration 并不处在当前线程栈中,这种情况不一定是出错,有可能当前正在执行 DPC。
[/color][color=#0A246A]:    ::::      :    [/color][color=#008000]; 当时还需要检查是否对齐,不对齐就一定是出错
[/color][color=#0A246A]:    >>::      :    [/color][color=#800080]808674ba  [/color][color=#0A246A]test    [/color][color=#FF8000]bl[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; 检查 l_pExceptionRegistration 是否4字节对齐
[/color][color=#0A246A]:      ::<     :    [/color][color=#800080]808674bd  [/color][color=#0A246A]jne     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A])
:      :::     :  
:      :::     :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x167 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]540[/color][color=#0A246A]]:
:      :::     :    [/color][color=#008000]; 如果当前正在执行 DPC,那 IRQL 一定不得低于 DISPATCH_LEVEL(难道不是应该一定等于 DISPATCH_LEVEL ?)
[/color][color=#0A246A]:      :::     :    [/color][color=#800080]808674bf  [/color][color=#0A246A]call    dword ptr [[/color][color=#000000]nt!_imp__KeGetCurrentIrql [/color][color=#0A246A]([/color][color=#800080]8080102c[/color][color=#0A246A])]
:      :::     :    [/color][color=#800080]808674c5  [/color][color=#0A246A]cmp     [/color][color=#FF8000]al[/color][color=#0A246A],[/color][color=#800080]2 [/color][color=#008000]; DISPATCH_LEVEL (2)
[/color][color=#0A246A]:      :::<    :    [/color][color=#800080]808674c7  [/color][color=#0A246A]jb      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 低于 DISPATCH_LEVEL,跳到错误处理点
[/color][color=#0A246A]:      ::::    :  
:      ::::    :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x171 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]542[/color][color=#0A246A]]:
:      ::::    :    [/color][color=#800080]808674c9  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]00000020h[/color][color=#0A246A]] [/color][color=#008000]; eax = 当前 CPU 的 KPCR::Prcb
[/color][color=#0A246A]:      ::::    :    [/color][color=#800080]808674cf  [/color][color=#0A246A]cmp     byte ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]95Ah[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; KPCR::Prcb->DpcRoutineActive (BOOLEAN 类型)
[/color][color=#0A246A]:      ::::    :    [/color][color=#800080]808674d6  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]948h[/color][color=#0A246A]] [/color][color=#008000]; ecx = KPCR::Prcb->DpcStack
[/color][color=#0A246A]:      ::::<   :    [/color][color=#800080]808674dc  [/color][color=#0A246A]je      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 当前不是在执行 DPC,跳到错误处理点
[/color][color=#0A246A]:      :::::   :  
:      :::::   :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x186 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]547[/color][color=#0A246A]]:
:      :::::   :    [/color][color=#008000]; KPCR::Prcb->DpcRoutineActive 为 TRUE,当前异常是由 DpcRoutine 触发
[/color][color=#0A246A]:      :::::   :    [/color][color=#800080]808674de  [/color][color=#0A246A]cmp     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]ecx [/color][color=#008000]; 比较 l_pExceptionRegistration->scopetable_entry 和 DPC 栈顶
[/color][color=#0A246A]:      :::::<  :    [/color][color=#800080]808674e0  [/color][color=#0A246A]ja      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 高出 DPC 栈顶,跳到错误处理点
[/color][color=#0A246A]:      ::::::  :  
:      ::::::  :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x18a [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]547[/color][color=#0A246A]]:
:      ::::::  :    [/color][color=#800080]808674e2  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ecx[/color][color=#0A246A]-[/color][color=#800080]3000h[/color][color=#0A246A]] [/color][color=#008000]; eax = KPCR::Prcb->DpcStack - KERNEL_STACK_SIZE, 即 DPC 栈底
[/color][color=#0A246A]:      ::::::  :    [/color][color=#800080]808674e8  [/color][color=#0A246A]cmp     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; 比较 l_pExceptionRegistration 和 DPC 栈底
[/color][color=#0A246A]:      ::::::< :    [/color][color=#800080]808674ea  [/color][color=#0A246A]jb      [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A]([/color][color=#800080]808674fa[/color][color=#0A246A]) [/color][color=#008000]; 低于 DPC 栈底,跳到错误处理点
[/color][color=#0A246A]:      ::::::: :  
:      ::::::: :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x194 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]555[/color][color=#0A246A]]:
:      ::::::: :    [/color][color=#800080]808674ec  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D8h[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; l_pHighLimit = DPC 栈顶
[/color][color=#0A246A]:      ::::::: :    [/color][color=#800080]808674f2  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D4h[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; l_pLowLimit = DPC 栈底
[/color][color=#0A246A]:      :::::::<:    [/color][color=#800080]808674f8  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1cf [/color][color=#0A246A]([/color][color=#800080]80867527[/color][color=#0A246A])
:      :::::::::  
:      :::::::::  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1a2 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]564[/color][color=#0A246A]]:
:      :::::::::    [/color][color=#008000]; 栈错误
[/color][color=#0A246A]:      >:>>>>>::    [/color][color=#800080]808674fa  [/color][color=#0A246A]and     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]31Ch[/color][color=#0A246A]],[/color][color=#800080]0
[/color][color=#0A246A]:       :     ::    [/color][color=#800080]80867501  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]]   [/color][color=#008000]; eax = &l_ExceptionRecord
[/color][color=#0A246A]:       :     ::    [/color][color=#800080]80867507  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
[/color][color=#0A246A]:       :     ::    [/color][color=#800080]80867508  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]32Ch[/color][color=#0A246A]],[/color][color=#800080]0C0000028h [/color][color=#008000]; l_ExceptionRecord.ExceptionCode = STATUS_BAD_STACK
[/color][color=#0A246A]:       :     ::    [/color][color=#800080]80867512  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]328h[/color][color=#0A246A]],[/color][color=#800080]1          [/color][color=#008000]; l_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE (1)
[/color][color=#0A246A]:       :     ::    [/color][color=#800080]8086751c  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]324h[/color][color=#0A246A]],[/color][color=#FF8000]esi        [/color][color=#008000]; l_ExceptionRecord.ExceptionRecord = &l_ExceptionRecord
[/color][color=#0A246A]:       :     ::    [/color][color=#800080]80867522  [/color][color=#0A246A]call    [/color][color=#000000]nt!RtlRaiseException [/color][color=#0A246A]([/color][color=#800080]80887a94[/color][color=#0A246A])
:       :     ::  
:       :     ::  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1cf [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]493[/color][color=#0A246A]]:
:       >     >:    [/color][color=#800080]80867527  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]:              :  
:              :  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1d1 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]493[/color][color=#0A246A]]:
>              :    [/color][color=#800080]80867529  [/color][color=#0A246A]cmp     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFFh [/color][color=#008000]; cmp l_pExceptionRegistration, EXCEPTION_CHAIN_END
               [/color][color=#0A246A]<    [/color][color=#800080]8086752c  [/color][color=#0A246A]jne     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x9c [/color][color=#0A246A]([/color][color=#800080]808673f4[/color][color=#0A246A])
                  
                  [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1da [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]647[/color][color=#0A246A]]:
                    [/color][color=#800080]80867532  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#800080]0FFFFFFFFh [/color][color=#008000]; cmp pExceptionRegistration, EXCEPTION_CHAIN_END
                    [/color][color=#800080]80867536  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
                    [/color][color=#800080]80867537  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]2D0h[/color][color=#0A246A]] [/color][color=#008000]; eax = &l_Context
                    [/color][color=#800080]8086753d  [/color][color=#0A246A]push    [/color][color=#FF8000]edi [/color][color=#008000]; bTestAlert = FALSE 或 bFirstChance = FALSE
                    [/color][color=#800080]8086753e  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
[/color][color=#0A246A]<                   [/color][color=#800080]8086753f  [/color][color=#0A246A]jne     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f0 [/color][color=#0A246A]([/color][color=#800080]80867548[/color][color=#0A246A])
:                 
:                 [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1e9 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]656[/color][color=#0A246A]]:
:                   [/color][color=#008000]; 展开整个异常链表
[/color][color=#0A246A]:                   [/color][color=#800080]80867541  [/color][color=#0A246A]call    [/color][color=#000000]nt!ZwContinue [/color][color=#0A246A]([/color][color=#800080]8082c0b8[/color][color=#0A246A])
:<                  [/color][color=#800080]80867546  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f6 [/color][color=#0A246A]([/color][color=#800080]8086754e[/color][color=#0A246A])
::                
::                [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f0 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]667[/color][color=#0A246A]]:
::                  [/color][color=#008000]; pExceptionRegistration 等于 EXCEPTION_CHAIN_END。
[/color][color=#0A246A]::                  [/color][color=#008000]; 没有理解这里触发异常是为什么,但是不妨碍分析异常处理流程。
[/color][color=#0A246A]>:                  [/color][color=#800080]80867548  [/color][color=#0A246A]push    [/color][color=#FF8000]esi [/color][color=#008000]; &l_ExceptionRecord
 [/color][color=#0A246A]:                  [/color][color=#800080]80867549  [/color][color=#0A246A]call    [/color][color=#000000]nt!ZwRaiseException [/color][color=#0A246A]([/color][color=#800080]8082ccd4[/color][color=#0A246A])
 :                
 :                [/color][color=#000000]nt!RtlUnwind[/color][color=#0A246A]+[/color][color=#800080]0x1f6 [/color][color=#0A246A][c:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\exdsptch.c @ [/color][color=#800080]671[/color][color=#0A246A]]:
 >                  [/color][color=#800080]8086754e  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]]
                    [/color][color=#800080]80867551  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
                    [/color][color=#800080]80867552  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
                    [/color][color=#800080]80867553  [/color][color=#0A246A]call    [/color][color=#000000]nt!__security_check_cookie [/color][color=#0A246A]([/color][color=#800080]80874e87[/color][color=#0A246A])
                    [/color][color=#800080]80867558  [/color][color=#0A246A]leave
                    [/color][color=#800080]80867559  [/color][color=#0A246A]ret     [/color][color=#800080]10h

        [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf [/color][color=#800080]80887be9 [/color][color=#008000]; RtlpExecuteHandlerForUnwind 的异常处理函数 
        [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x61 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]329[/color][color=#0A246A]]:
          [/color][color=#800080]80887be9  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRecord
          [/color][color=#800080]80887bed  [/color][color=#0A246A]test    dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6   [/color][color=#008000]; test pExceptionRecord->ExceptionFlags, EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND
          [/color][color=#800080]80887bf4  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch
          [/color][color=#800080]80887bf9  [/color][color=#0A246A]je      [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x85 [/color][color=#0A246A]([/color][color=#800080]80887c0d[/color][color=#0A246A])

        [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x73 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]341[/color][color=#0A246A]]:
          [/color][color=#008000]; 展开过程中 Handler 触发异常
          [/color][color=#800080]80887bfb  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; ecx = pExceptionRegistration
          [/color][color=#800080]80887bff  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edx = pDispatcherContext
          [/color][color=#800080]80887c03  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; eax = pExceptionRegistration->prev
          [/color][color=#800080]80887c06  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]],[/color][color=#FF8000]eax     [/color][color=#008000]; pDispatcherContext->RegistrationPointer = pExceptionRegistration->prev,
                                                    ; 然后 pDispatcherContext->RegistrationPointer 就是展开过程中正在被展开的
                                                    ; 那个 EXCEPTION_REGISTRATION_RECORD
          [/color][color=#800080]80887c08  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; eax = ExceptionCollidedUnwind

        [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x85 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]349[/color][color=#0A246A]]:
          [/color][color=#800080]80887c0d  [/color][color=#0A246A]ret     [/color][color=#800080]10h


    [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf RtlpExecuteHandlerForUnwind
        nt!RtlpExecuteHandlerForUnwind [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]142[/color][color=#0A246A]]:
          [/color][color=#800080]80887b54  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],offset [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x61 [/color][color=#0A246A]([/color][color=#800080]80887be9[/color][color=#0A246A])
          [/color][color=#800080]80887b59  [/color][color=#0A246A]lea     [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]ecx[/color][color=#0A246A]]
          [/color][color=#800080]80887b5c  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
          [/color][color=#800080]80887b5d  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
          [/color][color=#800080]80887b5e  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
          [/color][color=#800080]80887b5f  [/color][color=#0A246A]xor     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
          [/color][color=#800080]80887b61  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx
          [/color][color=#800080]80887b63  [/color][color=#0A246A]xor     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi
          [/color][color=#800080]80887b65  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
          [/color][color=#800080]80887b67  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRoutine
          [/color][color=#800080]80887b6b  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pDispatcherContext
          [/color][color=#800080]80887b6f  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pContext
          [/color][color=#800080]80887b73  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration
          [/color][color=#800080]80887b77  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRecord
          [/color][color=#800080]80887b7b  [/color][color=#0A246A]call    [/color][color=#000000]nt!ExecuteHandler2 [/color][color=#0A246A]([/color][color=#800080]80887b88[/color][color=#0A246A])
          [/color][color=#800080]80887b80  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
          [/color][color=#800080]80887b81  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
          [/color][color=#800080]80887b82  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
          [/color][color=#800080]80887b83  [/color][color=#0A246A]ret     [/color][color=#800080]14h

    [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf nt!ExecuteHandler2
        nt!ExecuteHandler2 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]188[/color][color=#0A246A]]:
          [/color][color=#800080]80887b88  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
          [/color][color=#800080]80887b89  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp
          [/color][color=#800080]80887b8b  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration
          [/color][color=#800080]80887b8e  [/color][color=#0A246A]push    [/color][color=#FF8000]edx                 [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::Handler (nt!ExecuteHandler2+0x61 (80887be9))
          [/color][color=#800080]80887b8f  [/color][color=#0A246A]push    dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]    [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::Next
          [/color][color=#800080]80887b96  [/color][color=#0A246A]mov     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp[/color][color=#008000]; 注意:这里使用的是原始版本的异常处理
          [/color][color=#800080]80887b9d  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; pDispatcherContext
          [/color][color=#800080]80887ba0  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; pContext
          [/color][color=#800080]80887ba3  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration
          [/color][color=#800080]80887ba6  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; pExceptionRecord
          [/color][color=#800080]80887ba9  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRoutine
          [/color][color=#800080]80887bac  [/color][color=#0A246A]call    [/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRoutine(...),即 pExceptionRegistration->handler(...)
          [/color][color=#800080]80887bae  [/color][color=#0A246A]mov     [/color][color=#FF8000]esp[/color][color=#0A246A],dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
          [/color][color=#800080]80887bb5  [/color][color=#0A246A]pop     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]    [/color][color=#008000]; 摘掉当前 _EXCEPTION_REGISTRATION_RECORD
          [/color][color=#800080]80887bbc  [/color][color=#0A246A]mov     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp
          [/color][color=#800080]80887bbe  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
          [/color][color=#800080]80887bbf  [/color][color=#0A246A]ret     [/color][color=#800080]14h[/color][/font]


        代码不长,主要功能也不复杂:从异常链表头开始遍历,一直遍历到指定 EXCEPTION_REGISTRATION_RECORD,对每个遍历到的 EXCEPTION_REGISTRATION_RECORD,执行 RtlpExecuteHandlerForUnwind 进行局部展开。
        这段代码里有一个细节我没想明白,或者我想复杂了。在 nt!RtlUnwind 地址 80867401 处,当展开到指定 EXCEPTION_REGISTRATION 后,RtlUnwind 通过 ZwContinue 返回,而不是使用 ret 指令。通过静态分析和动态分析我都没有找到用 ZwContinue 的好处,或者不可替代的原因。如果有朋友有不同的结论,请分享一下。
        在分析全局展开时发生一件很囧的事,我反汇编完成,梳理流程的时候,总感觉“这个逻辑怎么这么熟悉,貌似在哪见过~ 难道 wrk 里有源码?”,翻开 wrk,果然有…… 不过话说回来,在反汇编分析过程让我对一些细节理解的更深刻了(也只能这么安慰自己了……)。

        下面我们来看看局部展开。
        在前面讲 PassThrough!_except_handler4 时,有提到该函数既负责处理异常也负责局部展开。其区分功能的标志就是判断 EXCEPTION_RECORD::ExceptionFlags 是否包含 EXCEPTION_UNWIND 标志位。可以参考 PassThrough!_except_handler4 中地址为 f87203dc 的指令:
        f87203dc  test    byte ptr [eax+4],66h      ; pExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND,判断是异常处理过程还是展开过程
       
        该标志是在 RtlUnwind 中被设置的,可以参考 RtlUnwind 中地址为 808673b7 和 808673bd 出的指令:
        808673b7  or      dword ptr [esi+4],2 ; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING (0x2)
        808673bd  or      dword ptr [esi+4],6 ; l_ExceptionRecord.ExceptionFlags |= EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND (0x2 | 0x4)

        反汇编代码:

        首先是我整理的 _EH4_LocalUnwind 的原型:
       VOID fastcall _EH4_LocalUnwind(
            PEXCEPTION_REGISTRATION pExceptionRegistartion,
            ULONG ulUntilTryLevel
            )

[font=Consolas][color=#000000]    kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_EH4_LocalUnwind
        PassThrough!_EH4_LocalUnwind [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]529[/color][color=#0A246A]]:
          [/color][color=#000000]f8720614  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
          [/color][color=#000000]f8720615  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ebp = pExceptionRegistartion->_ebp
          [/color][color=#000000]f8720619  [/color][color=#0A246A]push    [/color][color=#FF8000]edx [/color][color=#008000]; ulUntilTryLevel
          [/color][color=#000000]f872061a  [/color][color=#0A246A]push    [/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistartion
          [/color][color=#000000]f872061b  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; push __security_cookie
          [/color][color=#000000]f872061f  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_local_unwind4 [/color][color=#0A246A]([/color][color=#000000]f87204ec[/color][color=#0A246A])
          [/color][color=#000000]f8720624  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]0Ch
          [/color][color=#000000]f8720627  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
          [/color][color=#000000]f8720628  [/color][color=#0A246A]ret     [/color][color=#800080]8

    [/color][color=#000000]PassThrough!_EH4_LocalUnwind 的原型:
       VOID local_unwind4[/color][color=#0A246A](
           [/color][color=#000000]PEXCEPTION_REGSTRATION pExceptionRegstration[/color][color=#0A246A],
           [/color][color=#000000]ULONG ulUntilTryLevel
           [/color][color=#0A246A])

    [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_local_unwind4
      PassThrough!_local_unwind4 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]177[/color][color=#0A246A]]:
        [/color][color=#000000]f87204ec  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
        [/color][color=#000000]f87204ed  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
        [/color][color=#000000]f87204ee  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
        [/color][color=#000000]f87204ef  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edx = __security_cookie
        [/color][color=#000000]f87204f3  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistartion
        [/color][color=#000000]f87204f7  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#008000]; ecx = ulUntilTryLevel
        [/color][color=#000000]f87204fb  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
        [/color][color=#000000]f87204fc  [/color][color=#0A246A]push    [/color][color=#FF8000]edx [/color][color=#008000]; __security_cookie
        [/color][color=#000000]f87204fd  [/color][color=#0A246A]push    [/color][color=#FF8000]eax [/color][color=#008000]; pExceptionRegistartion
        [/color][color=#000000]f87204fe  [/color][color=#0A246A]push    [/color][color=#FF8000]ecx [/color][color=#008000]; ulUntilTryLevel
        [/color][color=#000000]f87204ff  [/color][color=#0A246A]push    [/color][color=#FF8000]ecx [/color][color=#008000]; 这里压入的值后续被 f8720513 处的指令修改
        [/color][color=#000000]f8720500  [/color][color=#0A246A]push    offset [/color][color=#000000]PassThrough!_unwind_handler4 [/color][color=#0A246A]([/color][color=#000000]f872056f[/color][color=#0A246A]) [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::handler
        [/color][color=#000000]f8720505  [/color][color=#0A246A]push    dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]  [/color][color=#008000]; _EXCEPTION_REGISTRATION_RECORD::prev, 注意这里使用的是原始版本
        [/color][color=#000000]f872050c  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#000000]PassThrough!__security_cookie [/color][color=#0A246A]([/color][color=#000000]f87220b0[/color][color=#0A246A])]
        [/color][color=#000000]f8720511  [/color][color=#0A246A]xor     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]esp [/color][color=#008000]; 这里是用 esp 来异或,而 esp 此时指向新 _EXCEPTION_REGISTRATION_RECORD
        [/color][color=#000000]f8720513  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]eax [/color][color=#008000]; [esp+8] 被赋予加密后的 __security_cookie
        [/color][color=#000000]f8720517  [/color][color=#0A246A]mov     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp
      
      [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x32 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]209[/color][color=#0A246A]]:
   >>   [/color][color=#000000]f872051e  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]30h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistartion
   [/color][color=#0A246A]::   [/color][color=#000000]f8720522  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; ebx = pExceptionRegistration->scopetable, 将 ebx 假称为 l_pCurScopeEntry
   [/color][color=#0A246A]::   [/color][color=#000000]f8720525  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]2Ch[/color][color=#0A246A]] [/color][color=#008000]; ecx = &__security_cookie
   [/color][color=#0A246A]::   [/color][color=#000000]f8720529  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]]     [/color][color=#008000]; 解密 scopetable
   [/color][color=#0A246A]::   [/color][color=#000000]f872052b  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->trylevel
   [/color][color=#0A246A]::   [/color][color=#000000]f872052e  [/color][color=#0A246A]cmp     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp pExceptionRegistration->trylevel,TRYLEVEL_NONE
[/color][color=#0A246A]<  ::   [/color][color=#000000]f8720531  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x75 [/color][color=#0A246A]([/color][color=#000000]f8720561[/color][color=#0A246A]) [/color][color=#008000]; pExceptionRegistration->trylevel 等于 TRYLEVEL_NONE,无需遍历,返回
[/color][color=#0A246A]:  :: 
:  :: [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x47 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]216[/color][color=#0A246A]]:
:  ::   [/color][color=#000000]f8720533  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]34h[/color][color=#0A246A]] [/color][color=#008000]; edx = ulUntilTryLevel
[/color][color=#0A246A]:  ::   [/color][color=#000000]f8720537  [/color][color=#0A246A]cmp     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFEh [/color][color=#008000]; cmp ulUntilTryLevel, TRYLEVEL_NONE
[/color][color=#0A246A]:< ::   [/color][color=#000000]f872053a  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x54 [/color][color=#0A246A]([/color][color=#000000]f8720540[/color][color=#0A246A])
:: :: 
:: :: [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x50 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]219[/color][color=#0A246A]]:
:: ::   [/color][color=#000000]f872053c  [/color][color=#0A246A]cmp     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]edx [/color][color=#008000]; cmp pExceptionRegistration->trylevel, ulUntilTryLevel
[/color][color=#0A246A]::<::   [/color][color=#000000]f872053e  [/color][color=#0A246A]jbe     [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x75 [/color][color=#0A246A]([/color][color=#000000]f8720561[/color][color=#0A246A]) [/color][color=#008000]; 已经遍历到指定 scopetable_entry 了,返回
[/color][color=#0A246A]::::: 
::::: [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x54 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]221[/color][color=#0A246A]]:
:>:::   [/color][color=#000000]f8720540  [/color][color=#0A246A]lea     [/color][color=#FF8000]esi[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]]
: :::   [/color][color=#000000]f8720543  [/color][color=#0A246A]lea     [/color][color=#FF8000]ebx[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ebx - pExceptionRegistration->scopetable[pExceptionRegistration->trylevel]
[/color][color=#0A246A]: :::   [/color][color=#000000]f8720547  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]] [/color][color=#008000]; ecx = l_pCurScopeEntry->previousTryLevel
[/color][color=#0A246A]: :::   [/color][color=#000000]f8720549  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ecx [/color][color=#008000]; pExceptionRegistration->trylevel = ebx->l_pCurScopeEntry->previousTryLevel
[/color][color=#0A246A]: :::   [/color][color=#000000]f872054c  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]0 [/color][color=#008000]; cmp pExceptionRegistration->lpfnFilter,NULL
[/color][color=#0A246A]: :<:   [/color][color=#000000]f8720550  [/color][color=#0A246A]jne     [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x32 [/color][color=#0A246A]([/color][color=#000000]f872051e[/color][color=#0A246A])
: : : 
: : : [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x66 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]240[/color][color=#0A246A]]:
: : :   [/color][color=#000000]f8720552  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#800080]1
[/color][color=#0A246A]: : :   [/color][color=#000000]f8720557  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration->lpfnHandler
[/color][color=#0A246A]: : :   [/color][color=#000000]f872055a  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_NLG_Call [/color][color=#0A246A]([/color][color=#000000]f8720630[/color][color=#0A246A]) [/color][color=#008000]; 调用 pExceptionRegistration->lpfnHandler
[/color][color=#0A246A]: : <   [/color][color=#000000]f872055f  [/color][color=#0A246A]jmp     [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x32 [/color][color=#0A246A]([/color][color=#000000]f872051e[/color][color=#0A246A])
: :   
: :   [/color][color=#000000]PassThrough!_local_unwind4[/color][color=#0A246A]+[/color][color=#800080]0x75 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]248[/color][color=#0A246A]]:
> >     [/color][color=#000000]f8720561  [/color][color=#0A246A]pop     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
        [/color][color=#000000]f8720568  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]18h
        [/color][color=#000000]f872056b  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
        [/color][color=#000000]f872056c  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
        [/color][color=#000000]f872056d  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
        [/color][color=#000000]f872056e  [/color][color=#0A246A]ret
      
        [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_NLG_Call
        PassThrough!_NLG_Call [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\nlgsupp.asm @ [/color][color=#800080]120[/color][color=#0A246A]]:
          [/color][color=#000000]f8720630  [/color][color=#0A246A]call    [/color][color=#FF8000]eax
          [/color][color=#000000]f8720632  [/color][color=#0A246A]ret
[/color][/font]


        PassThrough!_EH4_LocalUnwind 中 f8720500 处的指令用到的异常处理函数 PassThrough!_unwind_handler4 的反汇编代码:

[font=Consolas][color=#000000]    kd[/color][color=#0A246A]> [/color][color=#000000]uf PassThrough!_unwind_handler4
        PassThrough!_unwind_handler4 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]294[/color][color=#0A246A]]:
          [/color][color=#000000]f872056f  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]] [/color][color=#008000]; ecx = pExceptionRecord
          [/color][color=#000000]f8720573  [/color][color=#0A246A]test    dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6   [/color][color=#008000]; test pExceptionRecord->ExceptionFlags, EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND
          [/color][color=#000000]f872057a  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch (1)
          [/color][color=#000000]f872057f  [/color][color=#0A246A]je      [/color][color=#000000]PassThrough!_unwind_handler4[/color][color=#0A246A]+[/color][color=#800080]0x45 [/color][color=#0A246A]([/color][color=#000000]f87205b4[/color][color=#0A246A])

        [/color][color=#000000]PassThrough!_unwind_handler4[/color][color=#0A246A]+[/color][color=#800080]0x12 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]307[/color][color=#0A246A]]:
          [/color][color=#008000]; 在展开过程中又触发了异常,那么处理该新异常(实际操作只是做展开,即清理掉该异常占用的资源,并没有真正处理该异常)
          [/color][color=#000000]f8720581  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration
          [/color][color=#000000]f8720585  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; ecx = __security_cookie, 注意这里不是 __pExceptionRegistration->scopetable
          [/color][color=#000000]f8720588  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]eax [/color][color=#008000]; 这里用 pExceptionRegistration 解密,PassThrough!_local_unwind4 中也正是用它进行加密的
                                    ; 参考 f8720511 处的指令
          [/color][color=#000000]f872058a  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!__security_check_cookie [/color][color=#0A246A]([/color][color=#000000]f8720638[/color][color=#0A246A])
          [/color][color=#000000]f872058f  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
          [/color][color=#000000]f8720590  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]] [/color][color=#008000]; eax+18h 是被 PassThrough!_local_unwind4 压入栈的 ebp,
                                                    ; 参考 f87204fb 处的指令
          [/color][color=#000000]f8720593  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; push ulUntilTryLevel
          [/color][color=#000000]f8720596  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistartion
          [/color][color=#000000]f8720599  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]] [/color][color=#008000]; __security_cookie
          [/color][color=#000000]f872059c  [/color][color=#0A246A]call    [/color][color=#000000]PassThrough!_local_unwind4 [/color][color=#0A246A]([/color][color=#000000]f87204ec[/color][color=#0A246A])
          [/color][color=#000000]f87205a1  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]0Ch
          [/color][color=#000000]f87205a4  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
          [/color][color=#000000]f87205a5  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration
          [/color][color=#000000]f87205a9  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; edx = pDispatcherContext (调整 pDispatcherContext,改变遍历顺序)
          [/color][color=#000000]f87205ad  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]],[/color][color=#FF8000]eax   [/color][color=#008000]; pDispatcherContext->RegistrationPointer = pExceptionRegistration
          [/color][color=#000000]f87205af  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]3 [/color][color=#008000]; eax = ExceptionCollidedUnwind (3)

        [/color][color=#000000]PassThrough!_unwind_handler4[/color][color=#0A246A]+[/color][color=#800080]0x45 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\[/color][color=#800080]5359[/color][color=#000000]\minkernel\crts\crtw32\misc\i386\exsup4.asm @ [/color][color=#800080]336[/color][color=#0A246A]]:
          [/color][color=#000000]f87205b4  [/color][color=#0A246A]ret
[/color][/font]


        到这里概要流程就讲完了。在处理异常和展开过程中多处涉及到遍历操作,咱们来总结一下这些遍历操作。
        1. 在异常处理过程中,每个被"卷入是非"的异常都至少会遍历异常链表两次(如果发生嵌套异常,比如在展开过程中
EXCEPTION_REGISTRATION_RECORD::Handler 又触发异常,则会遍历更多次。不过这也可以算作是一个新异常了。看如何理解。)。
        一次是在 RtlDispatchException 中,遍历的目的是找到愿意处理该异常的 _EXCEPTION_REGISTRATION_RECORD。
        另一次是在展开过程中、RtlUnwind 函数内,遍历的目录是为了对每个遍历到的 EXCEPTION_REGISTRATION_RECORD 进行局部展开。
        2. 同样的,每个被"卷入是非"的异常的 scopetable 也会被遍历至少两次,
        一次是在 modulename!_except_handler? 中,遍历目的也是找到愿意处理该异常的 scopetable_entry。
        另一次是在展开过程中、_local_unwind4 函数内,遍历的目的是找到所有指定范围内的 scopetable_entry::lpfnFilter 为 NULL 的 scopetable_entry,调用它们的 lpfnHandler (即 __finally 处理块)。

        在展开过程中,__finally 代码块会被执行,在执行过程中有可能触发新的异常,增强版通过返回 ExceptionCollidedUnwind (3) 来标识这种情况(参考 PassThrough!_unwind_handler4 中 f87205af 处的指令)。咱来回顾下这类返回值:

[font=Consolas][color=#000000]    [/color][color=#0A246A]typedef [/color][color=#000000]enum _EXCEPTION_DISPOSITION {
        ExceptionContinueExecution[/color][color=#0A246A],
        [/color][color=#000000]ExceptionContinueSearch[/color][color=#0A246A],
        [/color][color=#000000]ExceptionNestedException[/color][color=#0A246A],
        [/color][color=#000000]ExceptionCollidedUnwind
    } EXCEPTION_DISPOSITION[/color][color=#008000];
[/color][/font]


        前面的代码中已经展示了上述4中的三种:
        ExceptionContinueExecution 表示继续执行(异常已经被修复);
        ExceptionContinueSearch 表示继续搜索(当前搜索到的异常注册信息不处理);
        ExceptionCollidedUnwind 表示在展开过程中再次触发异常。
        ExceptionNestedException 呢?到目前咱们还没有遇到过,什么情况会用到它?
       
        从字面上看 ExceptionNestedException 大概意思是“嵌套的异常”,是不是可以理解为“处理异常过程中再次触发的异常”?比如类似于 ExceptionCollidedUnwind,只不过 ExceptionCollidedUnwind 是在展开过程。而 ExceptionNestedException 是在处理异常过程中?
        咱们顺着这个思路去寻找,首先来看 PassThrough!_except_handler4,它是异常处理的入口了。处理和展开都是它负责的。可是翻遍了它和它的工具函数的反汇编码也没有找到它直接返回或者通过注册异常处理信息来间接返回。于是我决定继续向上层即调用者方向搜寻,于是找到了如下汇编码:

[font=Consolas][color=#000000]        kd[/color][color=#0A246A]> [/color][color=#000000]uf RtlpExecuteHandlerForException
        nt!RtlpExecuteHandlerForException [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]87[/color][color=#0A246A]]:
          [/color][color=#800080]80887b4c  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],offset [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A]([/color][color=#800080]80887bc2[/color][color=#0A246A])
          [/color][color=#800080]80887b51  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!ExecuteHandler [/color][color=#0A246A]([/color][color=#800080]80887b5c[/color][color=#0A246A])

        [/color][color=#000000]nt!ExecuteHandler [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]160[/color][color=#0A246A]]:
          [/color][color=#800080]80887b5c  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
          [/color][color=#800080]80887b5d  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
          [/color][color=#800080]80887b5e  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
          [/color][color=#800080]80887b5f  [/color][color=#0A246A]xor     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
          [/color][color=#800080]80887b61  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx
          [/color][color=#800080]80887b63  [/color][color=#0A246A]xor     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi
          [/color][color=#800080]80887b65  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
          [/color][color=#800080]80887b67  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]]
          [/color][color=#800080]80887b6b  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]]
          [/color][color=#800080]80887b6f  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]]
          [/color][color=#800080]80887b73  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]]
          [/color][color=#800080]80887b77  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]20h[/color][color=#0A246A]]
          [/color][color=#800080]80887b7b  [/color][color=#0A246A]call    [/color][color=#000000]nt!ExecuteHandler2 [/color][color=#0A246A]([/color][color=#800080]80887b88[/color][color=#0A246A])
          [/color][color=#800080]80887b80  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
          [/color][color=#800080]80887b81  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
          [/color][color=#800080]80887b82  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
          [/color][color=#800080]80887b83  [/color][color=#0A246A]ret     [/color][color=#800080]14h

        [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf ExecuteHandler2
        nt!ExecuteHandler2 [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]188[/color][color=#0A246A]]:
          [/color][color=#800080]80887b88  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
          [/color][color=#800080]80887b89  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp
          [/color][color=#800080]80887b8b  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]
          [/color][color=#800080]80887b8e  [/color][color=#0A246A]push    [/color][color=#FF8000]edx
          [/color][color=#800080]80887b8f  [/color][color=#0A246A]push    dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
          [/color][color=#800080]80887b96  [/color][color=#0A246A]mov     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp [/color][color=#008000]; 注册新的异常处理结构
          [/color][color=#800080]80887b9d  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]14h[/color][color=#0A246A]]
          [/color][color=#800080]80887ba0  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]]
          [/color][color=#800080]80887ba3  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]]
          [/color][color=#800080]80887ba6  [/color][color=#0A246A]push    dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
          [/color][color=#800080]80887ba9  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]18h[/color][color=#0A246A]]
          [/color][color=#800080]80887bac  [/color][color=#0A246A]call    [/color][color=#FF8000]ecx
          [/color][color=#800080]80887bae  [/color][color=#0A246A]mov     [/color][color=#FF8000]esp[/color][color=#0A246A],dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
          [/color][color=#800080]80887bb5  [/color][color=#0A246A]pop     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
          [/color][color=#800080]80887bbc  [/color][color=#0A246A]mov     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp
          [/color][color=#800080]80887bbe  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
          [/color][color=#800080]80887bbf  [/color][color=#0A246A]ret     [/color][color=#800080]14h

        [/color][color=#000000]kd[/color][color=#0A246A]> [/color][color=#000000]uf [/color][color=#800080]80887bc2 [/color][color=#008000]; ExecuteHandler2 使用的异常处理函数
        [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]268[/color][color=#0A246A]]:
          [/color][color=#800080]80887bc2  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]]
          [/color][color=#800080]80887bc6  [/color][color=#0A246A]test    dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6
          80887bcd  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch (1)
          [/color][color=#800080]80887bd2  [/color][color=#0A246A]jne     [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x5e [/color][color=#0A246A]([/color][color=#800080]80887be6[/color][color=#0A246A])

        [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x4c [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]279[/color][color=#0A246A]]:
          [/color][color=#800080]80887bd4  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
          [/color][color=#800080]80887bd8  [/color][color=#0A246A]mov     [/color][color=#FF8000]edx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]]
          [/color][color=#800080]80887bdc  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ecx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
          [/color][color=#800080]80887bdf  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]edx[/color][color=#0A246A]],[/color][color=#FF8000]eax
          [/color][color=#800080]80887be1  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]2 [/color][color=#008000]; eax = ExceptionNestedException (2)

        [/color][color=#000000]nt!ExecuteHandler2[/color][color=#0A246A]+[/color][color=#800080]0x5e [/color][color=#0A246A][C:[/color][color=#000000]\wrk\wrk[/color][color=#0A246A]-[/color][color=#000000]v1.2\base\ntos\rtl\i386\xcptmisc.asm @ [/color][color=#800080]287[/color][color=#0A246A]]:
          [/color][color=#800080]80887be6  [/color][color=#0A246A]ret     [/color][color=#800080]10h
[/color][/font]


        RtlpExecuteHandlerForException 函数是在 RtlDispatchException 中被调用。RtlDispatchException 在遍历异常链过程中并不直接调用 EXCEPTION_REGISTRATION_RECORD::Handler,而是通过 RtlpExecuteHandlerForException 来间接调用。RtlpExecuteHandlerForException 通过 ExecuteHandler2 建立一个异常处理块。
        PassThrough!_except_handler4 处理异常的过程中,如果再次触发异常,则会由地址为 80887bc2 的异常处理函数返回 ExceptionNestedException。因为这几个函数都很简单,而且跟之前分析的函数很类似,不再赘述。

        分析完这些,我有个疑问还是没有解开,我个人一直很奇怪增强版的使用方式为何不能这样:
        __try
        {
        }
        __except()
        {
        }
        __finally
        {
        }
        其中 __except 过滤块和处理块可以省略。
        但是很遗憾,MSC 中 __except 和 __finally 只能选其一。(当然,咱们可以用双层 __try 来实现同样的效果,但是总感觉不太爽,特别是会导致代码块被迫缩进两次)
        在分析的过程中我也发现我希望的这种方式更合理一些,__except 负责处理异常,在处理异常代码中被执行。如果没有处理异常,那么在展开过程中 __finally 代码块被执行,做一些清理操作。这样两者都存在,各负责各的,不是更好吗?不知道是不是什么历史原因。

        还有一个地方我也觉得不太完美。我们分析原始版本的时候发现,原始版本自身并没有直接使用展开,RtlDispatchException 等异常处理函数并没有直接调用 RtlUnwind。后者实际上是在增强版中才用到。我个人感觉这种模型并不完美,原始版本并没有自成体系,而是与增强版纠结在一起,没有很好的分层。

        另外,在实际应用中 SEH 机制可能会导致很难分析的内存泄漏。我们来看一个例子,
        调用流程:func1 -> func2
        其中,func1 的代码如下:
        VOID Func1()
        {
            __try
            {
                Func2();
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                // 一些善后处理
            }
        }
       
        Func2 没有应用 SEH,它申请了一块内存,对这块内存进行操作,然后释放该内存。但是在操作内存时候触发异常,异常被 Func1 处理了,但是因为 Func2 没有 __finally 处理块,于是展开过程中 Func2 并没有机会去释放这块内存。结果就是:程序依然“正常”的在运行,但是实际上已经造成内存泄漏。随着程序执行,泄漏的资源可能越来越多。最后导致严重的系统故障。
       遇到这种问题,程序猿通过静态分析是很难找到泄漏的原因的。

        到这里差不多就啰嗦完了。最后,来一段总结。

        本文只是我分析 x86 下 windows 异常处理机制过程的一些笔记的集合。因为兴趣的原因,我只分析了内核部分,应用层 SEH 我没有琢磨。感兴趣的朋友可以参考《软件调试》中的相关内容,貌似挺详细的。
        后续我会抽时间再琢磨琢磨 x64 下 windows 的异常处理机制,前段时间查阅 x64 资料的时候看到其异常处理机制调整了很多,比如 EXCEPTION_REGISTRATION 不在是放在栈上,而是做成表。如果内部实现改变的较多,我会再写一份笔记来分享。sinister 师傅有过这么一段话,我很认同:
        “交流都是建立在平等的基础上,在抱怨氛围和环境不好的同时应该先想一想自己究竟付出了多少?只知索取不愿付出的人也就不用抱怨了,要怪也只能怪自己。发自己心得的人无非是两种目的,一是引发一些讨论,好纠正自己错误的认识,以便从中获取更多的知识使自己进步的更快。二是做一份备忘,当自己遗忘的时候能够马上找到相关资料。”
        其中提到的两种目的我都有 :-)
        还是那句老话,FIXME。
2011-10-5 12:58
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
附录1 《Ntfs!_except_handler3 的反汇编代码》

[font=Consolas][color=#000000]         kd[/color][color=#0A246A]> [/color][color=#000000]uf Ntfs!_except_handler3
         [/color][color=#008000];nt!_except_handler3 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 172]:
           [/color][color=#800080]80872c00  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
           [/color][color=#800080]80872c01  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebp[/color][color=#0A246A],[/color][color=#FF8000]esp
           [/color][color=#800080]80872c03  [/color][color=#0A246A]sub     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]8
           80872c06  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
           [/color][color=#800080]80872c07  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
           [/color][color=#800080]80872c08  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
           [/color][color=#800080]80872c09  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
           [/color][color=#800080]80872c0a  [/color][color=#0A246A]cld
           [/color][color=#800080]80872c0b  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; pExceptionRegistration
           [/color][color=#800080]80872c0e  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; pExceptionRecord
           [/color][color=#800080]80872c11  [/color][color=#0A246A]test    dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]6     [/color][color=#008000]; test pExceptionRecord->ExceptionFlags, (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
[/color][color=#0A246A]<          [/color][color=#800080]80872c18  [/color][color=#0A246A]jne     [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xc9 [/color][color=#0A246A]([/color][color=#800080]80872cc9[/color][color=#0A246A])
:        
:        [/color][color=#008000];nt!_except_handler3+0x1e [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 202]:
[/color][color=#0A246A]:          [/color][color=#008000]; ebp-8 和 ebp-4 是一个类型为 PEXCEPTION_POINTERS 的结构体,称之为 l_ExceptionPointers
[/color][color=#0A246A]:          [/color][color=#800080]80872c1e  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]eax   [/color][color=#008000]; l_ExceptionPointers->ExceptionRecord = pExceptionRecord
[/color][color=#0A246A]:          [/color][color=#800080]80872c21  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; eax = pContext
[/color][color=#0A246A]:          [/color][color=#800080]80872c24  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]eax   [/color][color=#008000]; l_ExceptionPointers->ContextRecord = pContext
[/color][color=#0A246A]:          [/color][color=#800080]80872c27  [/color][color=#0A246A]lea     [/color][color=#FF8000]eax[/color][color=#0A246A],[[/color][color=#FF8000]ebp[/color][color=#0A246A]-[/color][color=#800080]8[/color][color=#0A246A]]             [/color][color=#008000]; eax = lException
[/color][color=#0A246A]:          [/color][color=#800080]80872c2a  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]-[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#FF8000]eax   [/color][color=#008000]; ebx-4 指向 pExceptionRegistration 所在栈上类型为 PEXCEPTION_POINTERS 的变量
[/color][color=#0A246A]:                            [/color][color=#008000]; 具体栈的构造形式请参考当时建立 pExceptionRegistration 的代码
[/color][color=#0A246A]:                            [/color][color=#008000]; 这里是赋值给该 PEXCEPTION_POINTERS 变量,以提供给 GetExceptionInformation 和 GetExceptionCode 使用
[/color][color=#0A246A]:          [/color][color=#800080]80872c2d  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->trylevel
[/color][color=#0A246A]:          [/color][color=#800080]80872c30  [/color][color=#0A246A]mov     [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; edi = pExceptionRegistration->scopetable
[/color][color=#0A246A]:          [/color][color=#800080]80872c33  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
[/color][color=#0A246A]:          [/color][color=#800080]80872c34  [/color][color=#0A246A]call    [/color][color=#000000]nt!_ValidateEH3RN [/color][color=#0A246A]([/color][color=#800080]8087cde8[/color][color=#0A246A])
:          [/color][color=#800080]80872c39  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]4
[/color][color=#0A246A]:          [/color][color=#800080]80872c3c  [/color][color=#0A246A]or      [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
[/color][color=#0A246A]:<         [/color][color=#800080]80872c3e  [/color][color=#0A246A]je      [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xbb [/color][color=#0A246A]([/color][color=#800080]80872cbb[/color][color=#0A246A])
::       
::       [/color][color=#008000];nt!_except_handler3+0x40 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 218]:
[/color][color=#0A246A]::    >    [/color][color=#800080]80872c40  [/color][color=#0A246A]cmp     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFFh  [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_NONE
[/color][color=#0A246A]::<   :    [/color][color=#800080]80872c43  [/color][color=#0A246A]je      [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xc2 [/color][color=#0A246A]([/color][color=#800080]80872cc2[/color][color=#0A246A])
:::   :  
:::   :  [/color][color=#008000];nt!_except_handler3+0x45 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 220]:
[/color][color=#0A246A]:::   :    [/color][color=#800080]80872c45  [/color][color=#0A246A]lea     [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]]              [/color][color=#008000]; esi *= 3; 下面要将 eis*4,总共 esi*12,这是因为 scopetable_entry 大小是12
[/color][color=#0A246A]:::   :    [/color][color=#800080]80872c48  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]]  [/color][color=#008000]; eax = pExceptionRegistration->scopetable[i].lpfnFilter
[/color][color=#0A246A]:::   :    [/color][color=#800080]80872c4c  [/color][color=#0A246A]or      [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
[/color][color=#0A246A]:::<  :    [/color][color=#800080]80872c4e  [/color][color=#0A246A]je      [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xa9 [/color][color=#0A246A]([/color][color=#800080]80872ca9[/color][color=#0A246A]) [/color][color=#008000]; lpfnFilter 为 NULL 则跳转
[/color][color=#0A246A]::::  :  
::::  :  [/color][color=#008000];nt!_except_handler3+0x50 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 226]:
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c50  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c51  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c52  [/color][color=#0A246A]lea     [/color][color=#FF8000]ebp[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ebp = pExceptionRegistration->_ebp
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c55  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c57  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c59  [/color][color=#0A246A]xor     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c5b  [/color][color=#0A246A]xor     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c5d  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c5f  [/color][color=#0A246A]call    [/color][color=#FF8000]eax           [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnFilter()
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c61  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c62  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c63  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; ebx = pExceptionRegistration
[/color][color=#0A246A]::::  :    [/color][color=#800080]80872c66  [/color][color=#0A246A]or      [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#FF8000]eax
[/color][color=#0A246A]::::< :    [/color][color=#800080]80872c68  [/color][color=#0A246A]je      [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xa9 [/color][color=#0A246A]([/color][color=#800080]80872ca9[/color][color=#0A246A]) [/color][color=#008000]; EXCEPTION_CONTINUE_SEARCH
[/color][color=#0A246A]::::: :  
::::: :  [/color][color=#008000];nt!_except_handler3+0x6a [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 245]:
[/color][color=#0A246A]::::: :    [/color][color=#008000]; 如果 lpfnFilter 返回 EXCEPTION_CONTINUE_EXECUTION,跳过下面的展开操作
[/color][color=#0A246A]:::::<:    [/color][color=#800080]80872c6a  [/color][color=#0A246A]js      [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xb4 [/color][color=#0A246A]([/color][color=#800080]80872cb4[/color][color=#0A246A]) [/color][color=#008000]; EXCEPTION_CONTINUE_EXECUTION
[/color][color=#0A246A]:::::::  
:::::::  [/color][color=#008000];nt!_except_handler3+0x6c [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 249]:
[/color][color=#0A246A]:::::::    [/color][color=#008000]; lpfnFilter 返回 EXCEPTION_EXECUTE_HANDLER,开始展开
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c6c  [/color][color=#0A246A]mov     [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]] [/color][color=#008000]; edi = pExceptionRegistration->scopetable
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c6f  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c70  [/color][color=#0A246A]call    [/color][color=#000000]nt!__global_unwind2 [/color][color=#0A246A]([/color][color=#800080]80872520[/color][color=#0A246A])
:::::::    [/color][color=#800080]80872c75  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]4
[/color][color=#0A246A]:::::::
:::::::    [/color][color=#800080]80872c78  [/color][color=#0A246A]lea     [/color][color=#FF8000]ebp[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; ebp = pExceptionRegistration->_ebp
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c7b  [/color][color=#0A246A]push    [/color][color=#FF8000]esi [/color][color=#008000]; 展开到当前 trylevel 为止(不包含本 scopetable_entry)
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c7c  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c7d  [/color][color=#0A246A]call    [/color][color=#000000]nt!__local_unwind2 [/color][color=#0A246A]([/color][color=#800080]8087257b[/color][color=#0A246A])
:::::::    [/color][color=#800080]80872c82  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]8
[/color][color=#0A246A]:::::::
:::::::    [/color][color=#800080]80872c85  [/color][color=#0A246A]lea     [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]]
:::::::    [/color][color=#800080]80872c88  [/color][color=#0A246A]push    [/color][color=#800080]1
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c8a  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]  [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnHandler
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c8e  [/color][color=#0A246A]call    [/color][color=#000000]nt!_NLG_Notify [/color][color=#0A246A]([/color][color=#800080]80872617[/color][color=#0A246A])
:::::::    [/color][color=#800080]80872c93  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]]  [/color][color=#008000]; 
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c96  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]eax      [/color][color=#008000]; pExceptionRegistration->trylevel = RegistrationPointer->scopetable[i].previousTryLevel
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c99  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]  [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnHandler 
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c9d  [/color][color=#0A246A]xor     [/color][color=#FF8000]ebx[/color][color=#0A246A],[/color][color=#FF8000]ebx
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872c9f  [/color][color=#0A246A]xor     [/color][color=#FF8000]ecx[/color][color=#0A246A],[/color][color=#FF8000]ecx
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872ca1  [/color][color=#0A246A]xor     [/color][color=#FF8000]edx[/color][color=#0A246A],[/color][color=#FF8000]edx
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872ca3  [/color][color=#0A246A]xor     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#FF8000]esi
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872ca5  [/color][color=#0A246A]xor     [/color][color=#FF8000]edi[/color][color=#0A246A],[/color][color=#FF8000]edi
[/color][color=#0A246A]:::::::    [/color][color=#800080]80872ca7  [/color][color=#0A246A]call    [/color][color=#FF8000]eax [/color][color=#008000]; pExceptionRegistration->scopetable[i].lpfnHandler(); 这里不会返回的!!
[/color][color=#0A246A]:::::::  
:::::::  [/color][color=#008000];nt!_except_handler3+0xa9 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 285]:
[/color][color=#0A246A]:::::::    [/color][color=#008000]; 找到 scopetable 中的下一个 scopetable_entry,继续循环
[/color][color=#0A246A]:::>>::    [/color][color=#800080]80872ca9  [/color][color=#0A246A]mov     [/color][color=#FF8000]edi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
:::  ::    [/color][color=#800080]80872cac  [/color][color=#0A246A]lea     [/color][color=#FF8000]ecx[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]]
:::  ::    [/color][color=#800080]80872caf  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]edi[/color][color=#0A246A]+[/color][color=#FF8000]ecx[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]] 
:::  :<    [/color][color=#800080]80872cb2  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0x40 [/color][color=#0A246A]([/color][color=#800080]80872c40[/color][color=#0A246A])
:::  :   
:::  :   [/color][color=#008000];nt!_except_handler3+0xb4 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 291]:
[/color][color=#0A246A]:::  >     [/color][color=#800080]80872cb4  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]0 [/color][color=#008000]; eax = ExceptionContinueExecution (0)
[/color][color=#0A246A]:::   <    [/color][color=#800080]80872cb9  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xde [/color][color=#0A246A]([/color][color=#800080]80872cde[/color][color=#0A246A])
:::   :  
:::   :  [/color][color=#008000];nt!_except_handler3+0xbb [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 295]:
[/color][color=#0A246A]:>:   :    [/color][color=#800080]80872cbb  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
: :   :    [/color][color=#800080]80872cbe  [/color][color=#0A246A]or      dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]8
[/color][color=#0A246A]: :   :  
: :   :  [/color][color=#008000];nt!_except_handler3+0xc2 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 298]:
[/color][color=#0A246A]: >   :    [/color][color=#800080]80872cc2  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#008000]; eax = ExceptionContinueSearch (1)
[/color][color=#0A246A]:     :<   [/color][color=#800080]80872cc7  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!_except_handler3[/color][color=#0A246A]+[/color][color=#800080]0xde [/color][color=#0A246A]([/color][color=#800080]80872cde[/color][color=#0A246A])
:     ::  
>     :: [/color][color=#008000];nt!_except_handler3+0xc9 [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 302]:
      [/color][color=#0A246A]::   [/color][color=#008000]; 设置了(EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND),开始展开
      [/color][color=#0A246A]::   [/color][color=#800080]80872cc9  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
      [/color][color=#0A246A]::   [/color][color=#800080]80872cca  [/color][color=#0A246A]lea     [/color][color=#FF8000]ebp[/color][color=#0A246A],[[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000];ebp = pExceptionRegistration->_ebp
      [/color][color=#0A246A]::   [/color][color=#800080]80872ccd  [/color][color=#0A246A]push    [/color][color=#800080]0FFFFFFFFh
      [/color][color=#0A246A]::   [/color][color=#800080]80872ccf  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
      [/color][color=#0A246A]::   [/color][color=#800080]80872cd0  [/color][color=#0A246A]call    [/color][color=#000000]nt!__local_unwind2 [/color][color=#0A246A]([/color][color=#800080]8087257b[/color][color=#0A246A])
      ::   [/color][color=#800080]80872cd5  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]8
      [/color][color=#0A246A]::   [/color][color=#800080]80872cd8  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
      [/color][color=#0A246A]::   [/color][color=#800080]80872cd9  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],[/color][color=#800080]1 [/color][color=#FF8000]eax [/color][color=#0A246A]= [/color][color=#000000]ExceptionContinueSearch [/color][color=#0A246A]([/color][color=#800080]1[/color][color=#0A246A])
      ::
      :: [/color][color=#008000];nt!_except_handler3+0xde [d:\dnsrv\base\crts\crtw32\misc\i386\exsup3.asm @ 313]:
      [/color][color=#0A246A]>>   [/color][color=#800080]80872cde  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
           [/color][color=#800080]80872cdf  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
           [/color][color=#800080]80872ce0  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
           [/color][color=#800080]80872ce1  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
           [/color][color=#800080]80872ce2  [/color][color=#0A246A]mov     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#FF8000]ebp
           [/color][color=#800080]80872ce4  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebp
           [/color][color=#800080]80872ce5  [/color][color=#0A246A]ret[/color][/font]
2011-10-5 12:59
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
附录2 《nt!__local_unwind2 的反汇编代码》

[font=Consolas][color=#000000]      kd[/color][color=#0A246A]> [/color][color=#000000]uf __local_unwind2
      nt!__local_unwind2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]205[/color][color=#0A246A]]:
        [/color][color=#800080]8087257b  [/color][color=#0A246A]push    [/color][color=#FF8000]ebx
        [/color][color=#800080]8087257c  [/color][color=#0A246A]push    [/color][color=#FF8000]esi
        [/color][color=#800080]8087257d  [/color][color=#0A246A]push    [/color][color=#FF8000]edi
        [/color][color=#800080]8087257e  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]10h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration
        [/color][color=#800080]80872582  [/color][color=#0A246A]push    [/color][color=#FF8000]ebp
        [/color][color=#800080]80872583  [/color][color=#0A246A]push    [/color][color=#FF8000]eax
        [/color][color=#800080]80872584  [/color][color=#0A246A]push    [/color][color=#800080]0FFFFFFFEh
        80872586  [/color][color=#0A246A]push    offset [/color][color=#000000]nt!__unwind_handler [/color][color=#0A246A]([/color][color=#800080]80872540[/color][color=#0A246A])
        [/color][color=#800080]8087258b  [/color][color=#0A246A]push    dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
        [/color][color=#800080]80872592  [/color][color=#0A246A]mov     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]],[/color][color=#FF8000]esp [/color][color=#008000]; __local_unwind2 自身也会构建 _EXCEPTION_REGISTRATION

      [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x1e [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]222[/color][color=#0A246A]]:
>       [/color][color=#800080]80872599  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]24h[/color][color=#0A246A]] [/color][color=#008000]; eax = pExceptionRegistration
[/color][color=#0A246A]:       [/color][color=#800080]8087259d  [/color][color=#0A246A]mov     [/color][color=#FF8000]ebx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]   [/color][color=#008000]; ebx = pExceptionRegistration->scopetable
[/color][color=#0A246A]:       [/color][color=#800080]808725a0  [/color][color=#0A246A]mov     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]] [/color][color=#008000]; esi = pExceptionRegistration->trylevel
[/color][color=#0A246A]:       [/color][color=#800080]808725a3  [/color][color=#0A246A]cmp     [/color][color=#FF8000]esi[/color][color=#0A246A],[/color][color=#800080]0FFFFFFFFh          [/color][color=#008000]; cmp pExceptionRegistration->trylevel, TRYLEVEL_NONE
[/color][color=#0A246A]:<      [/color][color=#800080]808725a6  [/color][color=#0A246A]je      [/color][color=#000000]nt!_NLG_Return2[/color][color=#0A246A]+[/color][color=#800080]0x2 [/color][color=#0A246A]([/color][color=#800080]808725dd[/color][color=#0A246A])
::      
::    [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x2d [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]228[/color][color=#0A246A]]:
::      [/color][color=#800080]808725a8  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]28h[/color][color=#0A246A]],[/color][color=#800080]0FFFFFFFFh
[/color][color=#0A246A]::<     [/color][color=#800080]808725ad  [/color][color=#0A246A]je      [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A]([/color][color=#800080]808725b5[/color][color=#0A246A])
:::   
:::   [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x34 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]230[/color][color=#0A246A]]:
:::     [/color][color=#800080]808725af  [/color][color=#0A246A]cmp     [/color][color=#FF8000]esi[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]28h[/color][color=#0A246A]]
:::<    [/color][color=#800080]808725b3  [/color][color=#0A246A]jbe     [/color][color=#000000]nt!_NLG_Return2[/color][color=#0A246A]+[/color][color=#800080]0x2 [/color][color=#0A246A]([/color][color=#800080]808725dd[/color][color=#0A246A])
::::  
::::  [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x3a [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]234[/color][color=#0A246A]]:
::>:    [/color][color=#800080]808725b5  [/color][color=#0A246A]lea     [/color][color=#FF8000]esi[/color][color=#0A246A],[[/color][color=#FF8000]esi[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]2[/color][color=#0A246A]]
:: :    [/color][color=#800080]808725b8  [/color][color=#0A246A]mov     [/color][color=#FF8000]ecx[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]]  [/color][color=#008000]; move ecx, [pExceptionRegistration->scopetable[i].previousTryLevel]
[/color][color=#0A246A]:: :    [/color][color=#800080]808725bb  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]esp[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]],[/color][color=#FF8000]ecx      [/color][color=#008000]; 这个 esp+8 只写没读,什么情况?
[/color][color=#0A246A]:: :    [/color][color=#800080]808725bf  [/color][color=#0A246A]mov     dword ptr [[/color][color=#FF8000]eax[/color][color=#0A246A]+[/color][color=#800080]0Ch[/color][color=#0A246A]],[/color][color=#FF8000]ecx    [/color][color=#008000]; pExceptionRegistration->trylevel = ecx
[/color][color=#0A246A]:: :    [/color][color=#800080]808725c2  [/color][color=#0A246A]cmp     dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]4[/color][color=#0A246A]],[/color][color=#800080]0  [/color][color=#008000]; cmp pExceptionRegistration->scopetable->lpfnFilter, NULL
[/color][color=#0A246A]:: :<   [/color][color=#800080]808725c7  [/color][color=#0A246A]jne     [/color][color=#000000]nt!_NLG_Return2 [/color][color=#0A246A]([/color][color=#800080]808725db[/color][color=#0A246A])
:: :: 
:: :: [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x4e [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]243[/color][color=#0A246A]]:
:: ::   [/color][color=#008000]; RegistrationPointer->scopetable->lpfnFilter 等于 NULL,即这里是 __try & __finally 的组合
[/color][color=#0A246A]:: ::   [/color][color=#800080]808725c9  [/color][color=#0A246A]push    [/color][color=#800080]101h
[/color][color=#0A246A]:: ::   [/color][color=#800080]808725ce  [/color][color=#0A246A]mov     [/color][color=#FF8000]eax[/color][color=#0A246A],dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]
:: ::   [/color][color=#800080]808725d2  [/color][color=#0A246A]call    [/color][color=#000000]nt!_NLG_Notify [/color][color=#0A246A]([/color][color=#800080]80872617[/color][color=#0A246A])  [/color][color=#008000]; 这个函数对理解 SEH 不重要,可以暂时忽略
[/color][color=#0A246A]:: ::   [/color][color=#800080]808725d7  [/color][color=#0A246A]call    dword ptr [[/color][color=#FF8000]ebx[/color][color=#0A246A]+[/color][color=#FF8000]esi[/color][color=#0A246A]*[/color][color=#800080]4[/color][color=#0A246A]+[/color][color=#800080]8[/color][color=#0A246A]]    [/color][color=#008000]; pExceptionRegistration->scopetable->lpfnHandler()
[/color][color=#0A246A]:: :: 
:: :: [/color][color=#000000]nt!_NLG_Return2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]251[/color][color=#0A246A]]:
<: :>   [/color][color=#800080]808725db  [/color][color=#0A246A]jmp     [/color][color=#000000]nt!__local_unwind2[/color][color=#0A246A]+[/color][color=#800080]0x1e [/color][color=#0A246A]([/color][color=#800080]80872599[/color][color=#0A246A]) [/color][color=#008000]; 循环
 [/color][color=#0A246A]: :
 : :  [/color][color=#000000]nt!_NLG_Return2[/color][color=#0A246A]+[/color][color=#800080]0x2 [/color][color=#0A246A][[/color][color=#000000]d[/color][color=#0A246A]:[/color][color=#000000]\dnsrv\base\crts\crtw32\misc\i386\exsup.asm @ [/color][color=#800080]253[/color][color=#0A246A]]:
 > >    [/color][color=#800080]808725dd  [/color][color=#0A246A]pop     dword ptr [/color][color=#FF8000]fs[/color][color=#0A246A]:[[/color][color=#800080]0[/color][color=#0A246A]]
        [/color][color=#800080]808725e4  [/color][color=#0A246A]add     [/color][color=#FF8000]esp[/color][color=#0A246A],[/color][color=#800080]10h
        808725e7  [/color][color=#0A246A]pop     [/color][color=#FF8000]edi
        [/color][color=#800080]808725e8  [/color][color=#0A246A]pop     [/color][color=#FF8000]esi
        [/color][color=#800080]808725e9  [/color][color=#0A246A]pop     [/color][color=#FF8000]ebx
        [/color][color=#800080]808725ea  [/color][color=#0A246A]ret
[/color][/font]
2011-10-5 13:00
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
参考资料:
        [1] wrk 源码
        [2] A Crash Course on the Depths of Win32? Structured Exception Handling, Matt Pietrek
        [3] 《Windows 内核原理与实现》潘爱民
        [4] 《软件调试》张银奎
2011-10-5 13:01
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
附件是原始稿,htm 格式( SEH分析笔记(x86篇)_v1.0.2.7z)。
喜欢看离线版的朋友(比如我自己~)可以下载。
上传的附件:
2011-10-5 13:07
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不错,收藏起来慢慢看。
ps. LZ代码用的什么字体,看着挺舒服的?
2011-10-5 13:16
0
雪    币: 1489
活跃值: (1078)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
好文,建议加精。
2011-10-5 13:49
0
雪    币: 263
活跃值: (71)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
多谢分享心得,好文
2011-10-5 14:09
0
雪    币: 342
活跃值: (199)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
12
consolas :-)
2011-10-5 18:32
0
雪    币: 2325
活跃值: (2215)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
13
花了大概一个小时时间细细品读了一下LZ文章,感觉LZ对SEH的理解相当透彻啊,膜拜膜拜~
2011-10-6 16:11
0
雪    币: 1685
活跃值: (709)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
花了心血的,好资料,学习并感谢
2011-10-6 17:42
0
雪    币: 135
活跃值: (719)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
好详细,一定要仔细读读!
2011-10-6 19:46
0
雪    币: 316
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
辛苦,很详细
2011-10-6 20:27
0
雪    币: 693
活跃值: (108)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
17
多谢楼主的分享,楼主是花了大功夫的,大家顶起来!
2011-10-7 07:17
0
雪    币: 437
活跃值: (110)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
18
多谢楼主,慢慢学习
2011-10-7 08:53
0
雪    币: 7115
活跃值: (639)
能力值: (RANK:1290 )
在线值:
发帖
回帖
粉丝
19
为了你这种认真的态度,都要发帖支持你一下。。。
2011-10-7 09:47
0
雪    币: 473
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
花了心血的,好资料,学习并感谢
2011-10-7 12:18
0
雪    币: 8839
活跃值: (18505)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
21
膜拜,研究得真仔细!
2011-10-7 19:05
0
雪    币: 94
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
学习一下,lz研究的确实很深入。。。
2011-10-8 10:52
0
雪    币: 238
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
收藏学习,谢谢
2011-10-8 12:22
0
雪    币: 270
活跃值: (97)
能力值: ( LV8,RANK:140 )
在线值:
发帖
回帖
粉丝
24
太牛了,写这么多,慢慢看
2011-10-8 12:33
0
雪    币: 88
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
好贴 MARK
2011-10-8 18:18
0
游客
登录 | 注册 方可回帖
返回
//