OpenRCE_omega_red
November 24th, 2007, 18:50
Totally forgot about this. Some time ago I've accidentally found an unhandled exception condition in kernel-mode GDI. Microsoft is aware of this but frankly they still didn't fix it. Well, it may be not security issue, but who knows 
Offending function: win32k!NtUserGetDCEx or its user wrapper, GetDCEx.
Crash condition: call it with all 0s before any desktops are created (I'm not 100% sure of this, but it seems to be the case).
Sample scenario: Create a DLL that calls GetDcEx(0,0,0) in DllMain. MessageBox works too (that's how I first stumbled on it). Add the dll to AppInit_DLLs registry key. Reboot. Upon next system start the DLL will be mapped into winlogon's memory and the fatal function called before any windows are present. Boom, BSOD.
Here's the appropriate disassembly:
Interestingly, NtUserGetDC isn't just a wrapper to the ...Ex function. It has different code and isn't vulnerable to this.
https://www.openrce.org/blog/view/966/Null_pointer_dereference_in_win32k

Offending function: win32k!NtUserGetDCEx or its user wrapper, GetDCEx.
Crash condition: call it with all 0s before any desktops are created (I'm not 100% sure of this, but it seems to be the case).
Sample scenario: Create a DLL that calls GetDcEx(0,0,0) in DllMain. MessageBox works too (that's how I first stumbled on it). Add the dll to AppInit_DLLs registry key. Reboot. Upon next system start the DLL will be mapped into winlogon's memory and the fatal function called before any windows are present. Boom, BSOD.
Code:
PROCESS_NAME: winlogon.exe
FAULTING_IP:
win32k!NtUserGetDCEx+29
bf83c00f 8b4904 mov ecx,dword ptr [ecx+4]
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: bf83c00f (win32k!NtUserGetDCEx+0x00000029)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000004
Attempt to read from address 00000004
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".
READ_ADDRESS: 00000004
BUGCHECK_STR: ACCESS_VIOLATION
DEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE
LAST_CONTROL_TRANSFER: from 8053ca28 to bf83c00f
STACK_TEXT:
f88d9d50 8053ca28 00000000 00000000 00000003 win32k!NtUserGetDCEx+0x29
f88d9d50 7c90eb94 00000000 00000000 00000003 nt!KiFastCallEntry+0xf8
0006fb24 7e41e881 7e43a383 00000000 00000000 ntdll!KiFastSystemCallRet
0006fddc 7e43a284 0006ff38 00000005 00000004 USER32!NtUserGetDCEx+0xc
0006ff2c 7e4661d3 0006ff38 00000028 00000000 USER32!MessageBoxWorker+0x2ba
0006ff84 7e4505f3 00000000 1000d9e8 1000b370 USER32!MessageBoxTimeoutW+0x7a
0006ffa4 7e46634f 00000000 1000d9e8 1000b370 USER32!MessageBoxExW+0x1b
0006ffc0 1000105f 00000000 1000d9e8 1000b370 USER32!MessageBoxW+0x45
Here's the appropriate disassembly:
Code:
bf83c003 a138a59abf mov eax,dword ptr [win32k!gptiCurrent (bf9aa538)]
bf83c008 f6404b20 test byte ptr [eax+4Bh],20h
bf83c00c 8b483c mov ecx,dword ptr [eax+3Ch]
bf83c00f 8b4904 mov ecx,dword ptr [ecx+4] ds:0023:00000004=????????
bf83c012 8b7108 mov esi,dword ptr [ecx+8]
Interestingly, NtUserGetDC isn't just a wrapper to the ...Ex function. It has different code and isn't vulnerable to this.
https://www.openrce.org/blog/view/966/Null_pointer_dereference_in_win32k