










在 cookie 检查中,必定先要取出初始的 cookie 值:
0011392E A1 14 70 11 00 mov eax,dword ptr [___security_cookie (117014h)]
00113933 33 C5 xor eax,ebp
00113935 89 45 FC mov dword ptr [ebp-4],eax
这个 cookie 值是属于用户进程的,在这里是 helloworld.exe 映像
现在我们来看看这个 cookie 值被初始化什么,在哪里初始化?
0:000:x86> uf 0xb21221
helleworld!wWinMainCRTStartup [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 361]:
361 00b22090 8bff mov edi,edi
361 00b22092 55 push ebp
361 00b22093 8bec mov ebp,esp
368 00b22095 e8c5efffff call helleworld!ILT+90(___security_init_cookie) (00b2105f)
370 00b2209a e811000000 call helleworld!__tmainCRTStartup (00b220b0)
371 00b2209f 5d pop ebp
371 00b220a0 c3 ret
helleworld!ILT+540(_wWinMainCRTStartup):
00b21221 e96a0e0000 jmp helleworld!wWinMainCRTStartup (00b22090)
在 helloworld 的 wWinMainCRTStrartup() 启动例程里,首先调用 __security_init_cookie()例程进行 cookie 初始化,然后跳转到 __tmainCRTStartup() 最后流转到用户 wWinMain(),这些例程都是在用户空间,属于用户进程的。它们是 visual c++ 编译器为用户程序安插的启动例程,并且它们都是有源码提供,在 VC 的运行时库例程里可以找到源码。
下面我们来看看__security_init_cookie()例程是怎样运作的,在我目录是:C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src 下的文件 gs_support.c
#ifdef _WIN64
#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232
#else
#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
#endif
extern UINT_PTR __security_cookie;
extern UINT_PTR __security_cookie_complement;
typedef union {
unsigned __int64 ft_scalar;
FILETIME ft_struct;
} FT;
void __cdecl __security_init_cookie(void)
{
UINT_PTR cookie;
FT systime={0};
LARGE_INTEGER perfctr;
if (__security_cookie != DEFAULT_SECURITY_COOKIE
#if defined (_X86_)
&& (__security_cookie & 0xFFFF0000) != 0
#endif
)
{
__security_cookie_complement = ~__security_cookie;
return;
}
GetSystemTimeAsFileTime(&systime.ft_struct);
#if defined (_WIN64)
cookie = systime.ft_scalar;
#else
cookie = systime.ft_struct.dwLowDateTime;
cookie ^= systime.ft_struct.dwHighDateTime;
#endif
cookie ^= GetCurrentProcessId();
cookie ^= GetCurrentThreadId();
cookie ^= GetTickCount();
QueryPerformanceCounter(&perfctr);
#if defined (_WIN64)
cookie ^= perfctr.QuadPart;
#else
cookie ^= perfctr.LowPart;
cookie ^= perfctr.HighPart;
#endif
#if defined (_WIN64)
cookie &= 0x0000FFFFffffFFFFi64;
#endif
if (cookie == DEFAULT_SECURITY_COOKIE)
{
cookie = DEFAULT_SECURITY_COOKIE + 1;
}
#if defined (_X86_)
else if ((cookie & 0xFFFF0000) == 0)
{
cookie |= ( (cookie|0x4711) << 16);
}
#endif
__security_cookie = cookie;
__security_cookie_complement = ~cookie;
}
__security_cookie 在 CRT 库里是全局变量,见于另一个文件 gs_cookie.c
#ifdef _WIN64
#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232
#else
#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
#endif
DECLSPEC_SELECTANY UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;
DECLSPEC_SELECTANY UINT_PTR __security_cookie_complement = ~(DEFAULT_SECURITY_COOKIE);
CRT 库的 __security_cookie 的值就是 DEFAULT_SECURITY_COOKIE,在 Win32 下被定义为 0xBB40E64E,在 Win64 下被定义为 0x00002B992DDFA232
但是用户进程的 __security_cookie 值,需进行下面的设置:
经过一系列异或用户的 __security_cookie 值就出来,我们大概可以猜到 DEFAULT_SECURITY_COOKIE 这个值就是根据这样算出来的,因此如果算出来结果还是等于 DEFAULT_SECURITY_COOKIE 那么就需要加上1
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。