【问题标题】:__security_init_cookie in Windows driver causes bugcheck KERNEL_SECURITY_CHECK_FAILUREWindows 驱动程序中的 __security_init_cookie 导致错误检查 KERNEL_SECURITY_CHECK_FAILURE
【发布时间】:2015-11-30 03:16:43
【问题描述】:

当我在编译驱动程序时以 Windows 8.1 为目标时,发生了一些非常奇怪的事情。

一旦加载,它就会因错误检查KERNEL_SECURITY_CHECK_FAILURE 而崩溃,第一个参数 6 表示“The stack cookie security cookie was not properly initialized by the loader”。

这可能是由于构建了仅在 Windows 8 上运行的驱动程序并尝试在早期版本的 Windows 上加载驱动程序映像造成的。为避免此问题,您必须构建驱动程序以在早期版本的 Windows 上运行”。当我面向 Windows 7 时不会出现此错误。

我能够准确找到发生此错误的位置。它发生在由GsDriverEntry 调用的__security_init_cookie 函数中。

INIT:000000014000C1B4 __security_init_cookie proc near        ; CODE XREF: GsDriverEntry+10p
INIT:000000014000C1B4                 mov     rax, cs:__security_cookie
INIT:000000014000C1BB                 test    rax, rax
INIT:000000014000C1BE                 jz      short loc_14000C1DA
INIT:000000014000C1C0                 mov     rcx, 2B992DDFA232h
INIT:000000014000C1CA                 cmp     rax, rcx
INIT:000000014000C1CD                 jz      short loc_14000C1DA
INIT:000000014000C1CF                 not     rax
INIT:000000014000C1D2                 mov     cs:__security_cookie_complement, rax
INIT:000000014000C1D9                 retn
INIT:000000014000C1DA ; ---------------------------------------------------------------------------
INIT:000000014000C1DA
INIT:000000014000C1DA loc_14000C1DA:                          ; CODE XREF: __security_init_cookie+Aj
INIT:000000014000C1DA                                         ; __security_init_cookie+19j
INIT:000000014000C1DA                 mov     ecx, 6
INIT:000000014000C1DF                 int     29h             ; Win8: RtlFailFast(ecx)

从这个反汇编中我们可以看到它执行了 2 次检查。

The first check checks if rax (__security_cookie) is zero and the 
second check compares it to 2B992DDFA232h.

但是,__security_cookie 在我的二进制文件中声明为2B992DDFA232h,因此不应调用中断,但不知何故它确实如此。

【问题讨论】:

  • 您是否手动声明了__security_cookie?如果__security_cookie == 2B992DDFA232h,该代码将失败(调用RtlFastFail),因为这意味着cookie 保留在其默认值(不安全)。其他地方的代码(查找KeTickCount)应该计算一个新的随机安全cookie。
  • 啊,是的,你是对的@nneonneo,我确实错误地解释了那个控制流。要回答您的问题,不,我没有手动声明 __security_cookie。我查看了 Windows 7 二进制文件,它确实使用 KeTickCount 计算了一个新的 cookie,但是在 Windows 8.1 二进制文件中完全缺少等效代码。
  • 我假设您正在 Windows 8.1 系统上测试驱动程序?问题没有说。

标签: windows driver wdk


【解决方案1】:

Windows 8+ 能够为加载的可执行映像生成安全 cookie。安全 cookie 的位置存储在 PE 标头中的 LoadConfig 数据目录中,以便 Windows 加载程序可以轻松替换它。
原因是操作系统应该能够以安全的方式生成 cookie(例如使用RDRAND 指令(如果可用)和/或其他随机熵源)。也不需要将cookie初始化代码复制到每个驱动程序。

如果您的驱动程序以 Windows 8(和更新版本)为目标,它预计操作系统会初始化 cookie。因此,如果 cookie 未更改,它会引发 BSOD
另一方面,如果您的驱动程序针对较旧的操作系统(Windows 7),则编译器必须生成初始化 cookie 的代码(如果操作系统尚未对其进行初始化)。这样该驱动程序就兼容所有 Windows 版本。

我没有找到任何关于这个 Windows 8 功能的官方描述,但是这里有一篇描述它的文章:
Reversing Windows8: Interesting Features of Kernel Security

在加载内核驱动时,Windows 8 调用 MiProcessLoadConfigForDriver 来 生成安全cookie,在PE中找到旧的安全cookie并替换它。

新的 Windows8 内核驱动程序将检查其安全 cookie 是否已经存在 更换。

【讨论】:

    【解决方案2】:

    对于那些在 Visual Studio 2015 中构建驱动程序的人。如果您需要您的驱动程序与 Windows 7 兼容。

    1. 您需要 Windows 10 sdk 和匹配的 WDK(修订版必须匹配)。
    2. 在您的驱动程序项目中使用默认目标平台版本,即 10.x.x.x 和默认平台工具集,即 WindowsKernelModeDriver10。不要在这里改变任何东西。并且不要碰 _WIN32_WINNT 的定义。
    3. 平台在驱动程序设置 - 常规中指定。在那里您指定目标操作系统版本 - Windows 7,目标平台 - 桌面。只有这个。如果您指定 Windows 8 或 Windows 8.1,它仍然会在安全 cookie 检查代码中崩溃。

    附言该驱动程序仍将与 Windows 10、8.1 和 8 兼容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-03
      • 1970-01-01
      相关资源
      最近更新 更多