SEH stack 结构探索(4)--- __exception_handler4() 探秘2之 scopetable 结构

SEH stack 结构探索(4)--- __exception_handler4() 探秘2之 scopetable 结构


现在我们来继续分析 __exception_handler4_common() 的代码

我们来看看在 WinDbg 里显示的 __exception_handler4_common() 原型:

0:000:x86> x MSVCR100D!*handler4_comm*
00f72440 MSVCR100D!_except_handler4_common (unsigned int *<function> *, struct _EXCEPTION_RECORD *, struct _EXCEPTION_REGISTRATION_RECORD *, struct _CONTEXT *, void *)

正如前一篇所说的,它的前面两个参数是 __exception_handler4() 传过来的 &__security_check_cookie 和 &__security_cookie 它们是地址值。

  • &__security_cookie 是一个 cookie 值
  • &__security_check_cookie 却是一个函数

我们的注意力就放在这个 security_check_cookie 函数上,接着看代码:

01152465 8b55e0          mov     edx,dword ptr [ebp-20h]
01152468 8b4508          mov     eax,dword ptr [ebp+8]            ; &__security_cookie
0115246b 8b4a10          mov     ecx,dword ptr [edx+10h]          ; get ExceptionFilter
0115246e 3308            xor     ecx,dword ptr [eax]              ; __security_cookie XOR ExceptionFilter
01152470 894dd4          mov     dword ptr [ebp-2Ch],ecx          ; get scopetable

01152473 8b55e8          mov     edx,dword ptr [ebp-18h]          ; ebp
01152476 52              push    edx
01152477 8b45d4          mov     eax,dword ptr [ebp-2Ch]          ; scopetable
0115247a 50              push    eax
0115247b 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]           ; &__security_check_cookie
0115247e 51              push    ecx
0115247f e88c010000      call    MSVCR100D!ValidateLocalCookies (01152610)
01152484 83c40c          add     esp,0Ch

代码中的 [edx+10] 是从 esp 位置加上 10h 获得 SEH stack 中的 ExceptionFilter 位置,然后与取出来 __security_cookie 值进行异域处理后,保存在 [ebp-2Ch] 位置上

__security_cookie 与 ExceptionFilter 异域得到的是一个 scopetable 位置值,也就是 [ebp-2Ch] 存放着 sceopetable 表指针值。

如何见得:得到的是一个 scopetable,看看 MSVCR100D!ValidateLocalCookies() 的原型就知道了:

0:000:x86> x MSVCR100D!ValidateLocalCookies
6d802610 MSVCR100D!ValidateLocalCookies (<function> *, struct _EH4_SCOPETABLE *, char *)

这个函数的第 2 个参数就是 struct _EH4_SCOPETABLE 指针值,传给这个函数的第 2 个参数就是 [ebp-2Ch] 值

现在我们来看看 _EH4_SCOPETABLE 结构是怎样的,WinDbg 下显示:

0:000:x86> dt _EH4_SCOPETABLE 
MSVCR100D!_EH4_SCOPETABLE
   +0x000 GSCookieOffset   : Uint4B
   +0x004 GSCookieXOROffset : Uint4B
   +0x008 EHCookieOffset   : Uint4B
   +0x00c EHCookieXOROffset : Uint4B
   +0x010 ScopeRecord      : [1] _EH4_SCOPETABLE_RECORD

用 C 描述为:

struct _EH4_SCOPETABLE {
 UINT GSCookieOffset;
 UINT GSCookieXOROffset;
 UINT EHCookieOffset;
 UINT EHCookieXOROffset;
 _EH4_SCOPETABLE_RECORD ScopeRecord[1];
};

代码将 FramePointer(ebp),ScopeTable 和 __security_check_cookie 3个参数传给 ValidateLocalCookies() 函数来检测 cookie

ValidateLocalCookies() 的第1个参数是个函数,这个函数用来检测 cookie 值。

下面我们来看看 ValidateLocalCookies() 的代码:

MSVCR100D!ValidateLocalCookies:
6d802610 8bff            mov     edi,edi
6d802612 55              push    ebp
6d802613 8bec            mov     ebp,esp
6d802615 83ec08          sub     esp,8
6d802618 8b450c          mov     eax,dword ptr [ebp+0Ch]                ; scopetable
6d80261b 8338fe          cmp     dword ptr [eax],0FFFFFFFEh             ; GSCookieOffset
6d80261e 7423            je      MSVCR100D!ValidateLocalCookies+0x33 (6d802643)

MSVCR100D!ValidateLocalCookies+0x10:
6d802620 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
6d802623 8b11            mov     edx,dword ptr [ecx]                    ; get GSCookieOffset
6d802625 8b4510          mov     eax,dword ptr [ebp+10h]                ; FramePointer
6d802628 8b0c10          mov     ecx,dword ptr [eax+edx]                ; [FramePointer+GSCookieOffset]
6d80262b 894df8          mov     dword ptr [ebp-8],ecx                  ; [GSCookie]
6d80262e 8b550c          mov     edx,dword ptr [ebp+0Ch]
6d802631 8b4510          mov     eax,dword ptr [ebp+10h]
6d802634 034204          add     eax,dword ptr [edx+4]                  ; FramePointer+GSCookieXOROffset
6d802637 3345f8          xor     eax,dword ptr [ebp-8]
6d80263a 8945f8          mov     dword ptr [ebp-8],eax
6d80263d 8b4df8          mov     ecx,dword ptr [ebp-8]
6d802640 ff5508          call    dword ptr [ebp+8]


MSVCR100D!ValidateLocalCookies+0x33:
6d802643 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]                ; scopetable
6d802646 8b5108          mov     edx,dword ptr [ecx+8]                  ; get EHCookieOffset
6d802649 8b4510          mov     eax,dword ptr [ebp+10h]                ; FramePointer
6d80264c 8b0c10          mov     ecx,dword ptr [eax+edx]                ; [FramePointer+EHCookieOffset]
6d80264f 894dfc          mov     dword ptr [ebp-4],ecx                  ; [EHCookie]
6d802652 8b550c          mov     edx,dword ptr [ebp+0Ch]
6d802655 8b4510          mov     eax,dword ptr [ebp+10h]
6d802658 03420c          add     eax,dword ptr [edx+0Ch]                ; FramePointer+EHCookieXOROffset
6d80265b 3345fc          xor     eax,dword ptr [ebp-4]
6d80265e 8945fc          mov     dword ptr [ebp-4],eax
6d802661 8b4dfc          mov     ecx,dword ptr [ebp-4]
6d802664 ff5508          call    dword ptr [ebp+8]                      ; __security_check_cookie
6d802667 8be5            mov     esp,ebp
6d802669 5d              pop     ebp
6d80266a c3              ret

这个函数很简单,我将它还原 C 描述,大概是这样:

ValidateLocalCookie(void(*FUN_PTR)(unsigned int), struct _EH4_SCOPETABLE *ScopeTable, char *FramePointer)
{
        UINT EHCookie;
        UINT GSCookie;

        if (ScopeTable->GSCookieOffset == 0xFFFFFFFE) {
        /* EHCookie */
                EHCookie = *(UINT*)((UINT)FramePointer + ScopeTable->EHCookieOffset);
                EHCookie ^= FramePointer + ScopeTable->EHCookieXOROffset;
                (*FUN_PTR)(EHCookie);
        } else {
        /* GSCookie */
                GSCookie = *(UINT*)((UINT)FramePointer + ScopeTable->GSCookieOffset);
                GSCookie ^= FramePointer + ScopeTable->GSCookieXOROffset;
                (*FUN_PTR)(GSCookie);
        }
}

代码产生了 cookie 值,将这个 cookie 值传给 __security_check_cookie 函数进行比较,这个 __security_check_cookie 实际上是 VC++ 编译用户程序的安插的:

我的程序名是 seh1,因此在我的测试下,将会是:seh1!__security_check_cookie() 它已经是用户的代码了,而不是运行库代码。

seh1!__security_check_cookie:
   52 00ac1a00 3b0d0070ac00    cmp     ecx,dword ptr [seh1!__security_cookie (00ac7000)]
   56 00ac1a06 7502            jne     seh1!__security_check_cookie+0xa (00ac1a0a)

   57 00ac1a08 f3c3            rep ret

   59 00ac1a0a e973f6ffff      jmp     seh1!ILT+125(___report_gsfailure) (00ac1082)

这个代码很简单,就是比较产生的 cookie 值与用户程序的 cookie 值是否一样,不一样的话,就跳转到 __report_gsfailure 点进行报告错误。

现在回过头来看看这个 seh1!__security_cookie (00ac7000) 是何方神圣?这个 seh1__security_cookie 在用户代码 __try{} 之前构造 SEH 结构时出现过:

00ac1391 a10070ac00      mov     eax,dword ptr [seh1!__security_cookie (00ac7000)]
00ac1396 3145f8          xor     dword ptr [ebp-8],eax
00ac1399 33c5            xor     eax,ebp
00ac139b 50              push    eax
00ac139c 8d45f0          lea     eax,[ebp-10h]
00ac139f 64a300000000    mov     dword ptr fs:[00000000h],eax
00ac13a5 8965e8          mov     dword ptr [ebp-18h],esp

于是我们对 SEH stack 又进一步增加认识了:

 

上一页  目录  下一页


版权 mik 所有,转载请注明出处!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值