security cookie 機制(2)--- 初始化___security_cookie

在 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 值,需進行下面的設置:

  1. 得到 system time
  2. 與 GetCurrentProcessId() 異或
  3. 與 GetCurrentThreadId() 異或
  4. 與 GetTickCount() 異或
  5. 與 QueryPerformanceCounter()異或

通過一系列異或用戶的 __security_cookie 值就出來,咱們大概能夠猜到 DEFAULT_SECURITY_COOKIE 這個值就是根據這樣算出來的,所以若是算出來結果仍是等於 DEFAULT_SECURITY_COOKIE 那麼就須要加上1


版權 mik 全部,轉載請註明出處

相關文章
相關標籤/搜索