在 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 全部,轉載請註明出處