BSOD using CreateFile

Hi, I’m studying CPU virtualization and I tried to fiddle with this simple code

https://github.com/SinaKarvandi/Hypervisor-From-Scratch/tree/master/Part%205%20-%20Setting%20up%20VMCS%20%26%20Running%20Guest%20Code

It’s only purpose is show how to set some VMCS fields, launch the guest and exit from VMX operation immediately after the very first vm exit so it’s a bit contrived but that’s not the problem. It runs well.
I simply tried to move the try block from DriverEntry to DrvrCreate in order to use a client (you can compile and use the one in the Part 6 folder). Below you can see the result.
In the instruction

nt!IopCreateFile+0x594:
fffff8014e216214 488901 mov qword ptr [rcx],rax ds:0000000a52f3f7a8=cccccccccccccccc

sometimes rcx get a very low value. Why?
Drivers in other folders use a client as well but they work well. The only thing that came to my mind was thread affinity but I’m not sure that’s the problem.
I’m not interested in making it works with a client. I’d just like to know why you get those values in rcx.
Thanks.

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 0000000a52f3f7a8, memory referenced
Arg2: 00000000000000ff, IRQL
Arg3: 00000000000000cd, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: fffff8014e216214, address which referenced memory

Debugging Details:

KEY_VALUES_STRING: 1

Key  : Analysis.CPU.mSec
Value: 2796

Key  : Analysis.DebugAnalysisManager
Value: Create

Key  : Analysis.Elapsed.mSec
Value: 4337

Key  : Analysis.Init.CPU.mSec
Value: 6578

Key  : Analysis.Init.Elapsed.mSec
Value: 232279

Key  : Analysis.Memory.CommitPeak.Mb
Value: 171

Key  : WER.OS.Branch
Value: vb_release

Key  : WER.OS.Timestamp
Value: 2019-12-06T14:06:00Z

Key  : WER.OS.Version
Value: 10.0.19041.1

BUGCHECK_CODE: a

BUGCHECK_P1: a52f3f7a8

BUGCHECK_P2: ff

BUGCHECK_P3: cd

BUGCHECK_P4: fffff8014e216214

WRITE_ADDRESS: 0000000a52f3f7a8

PROCESS_NAME: ClientApp.exe

TRAP_FRAME: ffff800714f417d0 – (.trap 0xffff800714f417d0)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=00000000000000bc rbx=0000000000000000 rcx=0000000a52f3f7a8
rdx=ffffe50ddfc61820 rsi=0000000000000000 rdi=0000000000000000
rip=fffff8014e216214 rsp=ffff800714f41960 rbp=ffff800714f41b80
r8=ffffe50ddfc61820 r9=ffffd3084df2a7b0 r10=ffffe50dd6c8bcc0
r11=ffffe50dde0d7270 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up di pl nz na pe nc
nt!IopCreateFile+0x594:
fffff8014e216214 488901 mov qword ptr [rcx],rax ds:0000000a52f3f7a8=cccccccccccccccc
Resetting default scope

STACK_TEXT:
ffff800714f40ed8 fffff8014e112b12 : ffff800714f41040 fffff8014df7d200 0000000000000000 0000000000000000 : nt!DbgBreakPointWithStatus
ffff800714f40ee0 fffff8014e1120f6 : 0000000000000003 ffff800714f41040 fffff8014e00c0c0 000000000000000a : nt!KiBugCheckDebugBreak+0x12
ffff800714f40f40 fffff8014dff72b7 : 0000000000000000 fffff8014e1f24a7 00000000beaa0251 0000000000000000 : nt!KeBugCheck2+0x946
ffff800714f41650 fffff8014e009169 : 000000000000000a 0000000a52f3f7a8 00000000000000ff 00000000000000cd : nt!KeBugCheckEx+0x107
ffff800714f41690 fffff8014e005469 : ffff97c094a8d09c 0000000000000000 0000000000000000 0000000000000000 : nt!KiBugCheckDispatch+0x69
ffff800714f417d0 fffff8014e216214 : 0000000000000000 0000000a52f3f7e8 0000000000000000 0000000000000001 : nt!KiPageFault+0x469
ffff800714f41960 fffff8014e215c69 : 0000000a52f3f7a8 0000000000000000 0000000a52f3f7e8 0000000a52f3f7b0 : nt!IopCreateFile+0x594
ffff800714f41a00 fffff8014e008bb5 : 0000000000000000 0000000000000000 0000000000000000 0000000a52f3e7d8 : nt!NtCreateFile+0x79
ffff800714f41a90 00007ff830aed814 : 00007ff82e67a030 0000000000000000 0000000000000003 0000000100000001 : nt!KiSystemServiceCopyEnd+0x25
0000000a52f3f728 00007ff82e67a030 : 0000000000000000 0000000000000003 0000000100000001 0000000000000000 : ntdll!NtCreateFile+0x14
0000000a52f3f730 00007ff82e679d56 : 800093f540b53458 00007ffffa3b8750 00007ff6c2c6200c 0000000000000000 : KERNELBASE!CreateFileInternal+0x2c0
0000000a52f3f890 00007ff6c2c51ab5 : 00007ff6c2c6200f 00007ffffa4c4870 00007ffffa4c4868 00007ff830aa07b0 : KERNELBASE!CreateFileW+0x66
0000000a52f3f8f0 00007ff6c2c524f9 : 0000188700000001 00007ffffa3d4299 0000000000000000 00007ff6c2c53bcd : ClientApp+0x11ab5
0000000a52f3fa30 00007ff6c2c5239e : 00007ff6c2c5a000 00007ff6c2c5a220 0000000000000000 0000000000000000 : ClientApp+0x124f9
0000000a52f3fa80 00007ff6c2c5225e : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : ClientApp+0x1239e
0000000a52f3faf0 00007ff6c2c5258e : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : ClientApp+0x1225e
0000000a52f3fb20 00007ff82fe87034 : 0000000a53040000 0000000000000000 0000000000000000 0000000000000000 : ClientApp+0x1258e
0000000a52f3fb50 00007ff830aa2651 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : KERNEL32!BaseThreadInitThunk+0x14
0000000a52f3fb80 0000000000000000 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : ntdll!RtlUserThreadStart+0x21

SYMBOL_NAME: nt!IopCreateFile+594

MODULE_NAME: nt

IMAGE_NAME: ntkrnlmp.exe

STACK_COMMAND: .thread ; .cxr ; kb

BUCKET_ID_FUNC_OFFSET: 594

FAILURE_BUCKET_ID: AV_nt!IopCreateFile

OS_VERSION: 10.0.19041.1

BUILDLAB_STR: vb_release

OSPLATFORM_TYPE: x64

OSNAME: Windows 10

There are an incredible number of sharp-edges and ill-defined operations in the driver. Are you sure you’re up to this?

You should be able to see that the address it is trying to access is in the user-mode stack – one of the stack variables in CreateFileW. The IRQL is set to 0xff, which is beyond the valid range of an IRQL and implies that either something got overwritten, or your code has left things in a state where you cannot just return to user mode.

You can’t just arbitrarily move that block into the create handler, especially when it’s mucking with such deeply entrenched data structures. Remember that the create handler is called in the context of the user-mode process that called CreateFile. DriverEntry is guaranteed to run in the system process, and that may be required.

1 Like

Hi Tim, thank you for your reply.
I see the point. Maybe investigate further is way out of my league at the moment.
The only thing I can’t really understand is why we can execute similar code in Part 6 and it works. What’s the difference between the two drivers?
In the driver of Part 5 we manipulate the stack to return in DrvCreate\DriverEntry. Can be that a possible cause of the problem?