IT点滴

我不去想是否能够成功 既然选择了远方 便只顾风雨兼程
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

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

Posted on 2018-11-09 20:05  Ady Lee  阅读(2102)  评论(0编辑  收藏  举报

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

  1. 获得 system time
  2. 与 GetCurrentProcessId() 异或
  3. 与 GetCurrentThreadId() 异或
  4. 与 GetTickCount() 异或
  5. 与 QueryPerformanceCounter()异或

经过一系列异或用户的 __security_cookie 值就出来,我们大概可以猜到 DEFAULT_SECURITY_COOKIE 这个值就是根据这样算出来的,因此如果算出来结果还是等于 DEFAULT_SECURITY_COOKIE 那么就需要加上1


版权 mik 所有,转载请注明出处