2015-09-04 284 views
7

当我编译我的驱动程序时,我定位到Windows 8.1时发生了一些非常奇怪的事情。Windows驱动程序中的__security_init_cookie导致错误检查KERNEL_SECURITY_CHECK_FAILURE

一旦它加载,就会通过错误检查KERNEL_SECURITY_CHECK_FAILURE(第一个参数6,意思是“The stack cookie security cookie was not properly initialized by the loader”)崩溃。

这可能是由于构建驱动程序仅在Windows 8上运行并尝试将驱动程序映像加载到早期版本的Windows上所致。为避免此问题,您必须构建驱动程序以在早期版本的Windows上运行“当我定位到Windows 7时,不会发生此错误。

我能够准确找到发生此错误的位置。是发生在__security_init_cookie功能是由GsDriverEntry调用。

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,因此中断不应该被调用,但不知何故。

+0

您是否手动声明了'__security_cookie'?如果'__security_cookie == 2B992DDFA232h'这个代码**会失败**(调用'RtlFastFail'),因为这意味着cookie保留其默认值(不安全)。有其他代码(查找KeTickCount)应该计算一个新的随机安全cookie。 – nneonneo

+0

啊是的,你是正确的@nneonneo,我没有解释错误的控制流程。要回答你的问题,不,我没有手动声明__security_cookie。我查看了Windows 7二进制文件,它确实使用KeTickCount计算了一个新的cookie,但是在Windows 8.1二进制文件中完全没有相同的代码。 – InvokeStatic

+0

我假设你在Windows 8.1系统上测试驱动程序?这个问题没有说。 –

回答

3

Windows 8+能够为加载的可执行映像生成安全cookie。安全性cookie的位置存储在数据目录中的PE标题中,以便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. 该平台在Driver Settings - General中指定。您可以在其中指定目标操作系统版本 - Windows 7,目标平台 - 桌面。只有这一个。如果您指定Windows 8或Windows 8.1,它仍然会在安全Cookie检查代码中崩溃。

p.s.驱动程序仍将与Windows 10,8.1和8兼容。