The Windows kernel people may be familiar with a cool built-in "pte" extension that can help you troubleshoot ugly BSODs by checking if some kernel memory address is inaccessible.
0: kd> !pte ffff8d89`cce3efe8
VA ffff8d89cce3efe8
PXE at FFFF91C8E47238D8 PPE at FFFF91C8E471B138 PDE at FFFF91C8E3627338 PTE at FFFF91C6C4E671F0
contains 0A0000021E002863 contains 0A00000002903863 contains 0A0000012845B863 contains 8A0000015AD4F963
pfn 21e002 ---DA--KWEV pfn 2903 ---DA--KWEV pfn 12845b ---DA--KWEV pfn 15ad4f -G-DA--KW-V
0: kd> dt nt!_HARDWARE_PTE FFFF91C6C4E671F0
+0x000 Valid : 0y1
+0x000 Write : 0y1
+0x000 Owner : 0y0
+0x000 WriteThrough : 0y0
+0x000 CacheDisable : 0y0
+0x000 Accessed : 0y1
+0x000 Dirty : 0y1
+0x000 LargePage : 0y0
+0x000 Global : 0y1
+0x000 CopyOnWrite : 0y0
+0x000 Prototype : 0y0
+0x000 reserved0 : 0y1
+0x000 PageFrameNumber : 0y000000000000000101011010110101001111 (0x15ad4f)
+0x000 reserved1 : 0y0000
+0x000 SoftwareWsIndex : 0y00010100000 (0xa0)
+0x000 NoExecute : 0y1
Normally it shows PTE address among with other information, but unfortunately it has been broken for a quite some time (and his colleague vtop - too):
0: kd> !pte fffff807`1f8a7c58
Levels not implemented for this platform
And it doesn't look like MS is going to fix it anytime soon, see:
https://github.com/microsoftfeedback/WinDbg-Feedback/issues/8
It's no problem if you have a single occasional BSOD, but if you really need to use this extension for a number of dumps in a row it's getting annoying.
Sooo, I decided to use my small and nice (and a little bit outdated) code emulator and emulate nt!MiGetPteAddress
instead:
0: kd> .load c:\orthia\orthia.dll;!orthia.profile /f %temp%\test.db; !orthia.vm_vm_def
0: kd> !orthia.vm_vm_call 0 nt!MiGetPteAddress --print rcx=fffff807`1f8a7c58
Diana Error Code: DI_END
rax=fffff6fc038fc538 rbx=fffff8071b881180 rcx=0000007c038fc538
rdx=0000025800000000 rsi=0000000000000001 rdi=000000000000000d
rip=0000000000000000 rsp=fffff8071f8a7c58 rbp=ffff940947d3e040
r8=0000000000000018 r9=ffff9409476e0000 r10=000000000000000b
r11=0000000000009ee6 r12=0000000000000000 r13=fffff8071b881180
r14=0000000000000001 r15=ffffffffffffff00
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000282
Commands count: 6
Modified pages:
Done
0: kd> dt ntkrnlmp!_HARDWARE_PTE fffff6fc038fc538
+0x000 Valid : 0y1
+0x000 Write : 0y1
+0x000 Owner : 0y0
+0x000 WriteThrough : 0y0
+0x000 CacheDisable : 0y0
+0x000 Accessed : 0y1
+0x000 Dirty : 0y1
+0x000 LargePage : 0y0
+0x000 Global : 0y0
+0x000 CopyOnWrite : 0y0
+0x000 Prototype : 0y0
+0x000 reserved0 : 0y1
+0x000 PageFrameNumber : 0y000000000000000000000110110010100111 (0x6ca7)
+0x000 reserved1 : 0y0000
+0x000 SoftwareWsIndex : 0y00010010000 (0x90)
+0x000 NoExecute : 0y1
As you can see there were just 6 assembler instruction to emulate, so it handled them successfully.
The extension is here: https://github.com/ligen-ua/diana-dasm/releases/tag/v1.1-tools
The sources and this case study is there:
https://github.com/ligen-ua/diana-dasm?tab=readme-ov-file#pte-case-study