Something very strange is happening when I target Windows 8.1 when I compile my driver.
As soon as it loads, it crashes with bugcheck KERNEL_SECURITY_CHECK_FAILURE
, first parameter 6, which means "The stack cookie security cookie was not properly initialized by the loader
".
This may be caused by building a driver to run only on Windows 8 and attempting to load the driver image on an earlier version of Windows. To avoid this problem, you must build the driver to run on an earlier version of Windows". This error does not occur when I target Windows 7.
I was able to find exactly where this error is occurring. It is happening in the __security_init_cookie
function which is called by 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)
From this disassembly we can see that it performs 2 checks.
The first check checks if rax (__security_cookie) is zero and the
second check compares it to 2B992DDFA232h.
However, __security_cookie
is declared in my binary as 2B992DDFA232h
, and thus the interrupt should never be called, but somehow it is.
Windows 8+ is able to generate security cookie for loaded executable image. Location of security cookie is stored in LoadConfig
data directory in PE
header so that Windows loader can easily replace it.
The reason is that the OS should be able to generate the cookie in safe way (for example using RDRAND
instruction if available and/or other random entropy sources). Also there is no need to copy cookie initialization code to every driver.
If your driver targets Windows 8 (and newer) it expects that OS will initialize the cookie. Therefore it raises BSOD
if cookie wasn't changed.
On the other hand if your driver targets older OS (Windows 7), compiler has to generate code that initializes cookie if it wasn't already initialized by OS. This way the driver is compatible with all Windows versions.
I haven't found any official description of this Windows 8 feature, but here is article that describes it:
Reversing Windows8: Interesting Features of Kernel Security
When loading the kernel driver, Windows 8 calls MiProcessLoadConfigForDriver to generate security cookie, locates old security cookie in PE and replaces it.
New Windows8 kernel drivers will check if their security cookies are already replaced.
For those who build drivers in Visual studio 2015. If you need your driver to be compatible with Windows 7.
p.s. the driver will still be compatible with windows 10, 8.1 and 8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With