zoukankan      html  css  js  c++  java
  • security cookie 机制(2)--- 初始化___security_cookie

    在 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:ddvctoolscrt_bldself_x86crtsrccrtexe.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.0VCcrtsrc 下的文件 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 所有,转载请注明出处

  • 相关阅读:
    project euler 开坑
    hdu 5382 GCD?LCM!
    Leetcode 557. 反转字符串中的单词 III
    Leetcode 344. 反转字符串
    Leetcode 345. 反转字符串中的元音字母
    008.C++类改写模板类
    007.C++构造函数
    006.C++头文件
    02.树的序列化与反序列化(C++)
    Leetcode 94. 二叉树的中序遍历
  • 原文地址:https://www.cnblogs.com/adylee/p/9936954.html
Copyright © 2011-2022 走看看