在 cookie 检查中,一定先要取出初始的 cookie 值:c++
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
如今咱们来看看这个 cookie 值被初始化什么,在哪里初始化?spa
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 retscala helleworld!ILT+540(_wWinMainCRTStartup): 00b21221 e96a0e0000 jmp helleworld!wWinMainCRTStartup (00b22090)orm |
在 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.cci
#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;it 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 值,需进行下面的设置:
- 得到 system time
- 与 GetCurrentProcessId() 异或
- 与 GetCurrentThreadId() 异或
- 与 GetTickCount() 异或
- 与 QueryPerformanceCounter()异或
通过一系列异或用户的 __security_cookie 值就出来,咱们大概能够猜到 DEFAULT_SECURITY_COOKIE 这个值就是根据这样算出来的,所以若是算出来结果仍是等于 DEFAULT_SECURITY_COOKIE 那么就须要加上1
版权 mik 全部,转载请注明出处