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 所有,转载请注明出处!