omega_red
December 13th, 2005, 06:21
By accident
I've found a way to BSOD win2k from usermode pretty reliably:
NtQuerySystemInformation is supposed to return required buffer size if passed too small buffer - though it apparently tries to write something there even if passed size = 0
XP behaves correctly though, even with uninitialized buffer and size=0.

Code:
typedef DWORD (WINAPI *NtQSI) (DWORD, void*, DWORD, DWORD*); // NtQuerySystemInformation
byte* buf;
NtQSI NtQuerySystemInformation = (NtQSI) GetProcAddress(GetModuleHandle("ntdll.dll", "NtQuerySystemInformation"
;
if (NtQuerySystemInformation == 0)
{
printf("Error: could't get NtQuerySystemInformation\n";
return -1;
}
// get required buffer size – BUG, should be (11, buf, 1, &size), buf should hold at least 1 initialized byte
NtQuerySystemInformation(11, buf, 0, &size); // ModuleInformationClass
buf = new byte[size];
// the real call
dwReturn = NtQuerySystemInformation(11, buf, size, &size);
NtQuerySystemInformation is supposed to return required buffer size if passed too small buffer - though it apparently tries to write something there even if passed size = 0

Code:
*** Fatal System Error: 0x00000050
(0xCCCCCCCC,0x00000001,0x8049301B,0x00000000)
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
[…]
BugCheck 50, {cccccccc, 1, 8049301b, 0}
Probably caused by : ntoskrnl.exe ( nt!ExpQueryModuleInformation+c3 )
[…]
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except,
it must be protected by a Probe. Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: cccccccc, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: 8049301b, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 00000000, (reserved)
XP behaves correctly though, even with uninitialized buffer and size=0.