Search code examples
debuggingkernelx86-64windbgpage-tables

Problem with !vtop in windbg for converting a virtual address to a physical one, using the page table address from CR3


I study the Windows kernel and windbg ( along the way). And I found the !vtop command on msdn - which translates the virtual address of the current context into a physical one. I wanted to enjoy the performance of this team.

My actions:

  1. I took the CR3 register as a physical pointer to the PML4 table for the current task - 38f9d002
  2. From the current task, I took a virtual address to translate to physical - 7ff61afa0000.
  3. I enter the command: !vtop 38f9d002 7ff61afa0000 in WinDbg. As a result, I get an error of the following description: Virtual address 7ff61afa0000 translation fails, error 0xD0000147.

Full listing from WinDbg:

!vtop 38f9d002 7ff61afa0000
Amd64VtoP: Virt 00007ff61afa0000, pagedir 0000000038f9d002
Amd64VtoP: PML4E 0000000038f9d7fa
Amd64VtoP: pagefile PDPE 0:0000000008a00ec0
Amd64VtoP: PML4E not present, 0xD0000147
Virtual address 7ff61afa0000 translation fails, error 0xD0000147.

Please tell me where I messed up and what the error code means in general - 0xD0000147, also (if possible) please send a link to the source where I can get acquainted with these codes in detail.


Solution

  • I don't know WinDBG, but assuming that virtual address is currently valid, it probably isn't masking off the process-context-ID bits in the bottom of CR3 for you, so zero out the low 3 hex digits yourself.

    The OP reports that 38f9d000 does work as the PML4 address.

    The actual PML4 has to be 4k-aligned, so the low 12 bits of the physical address will be zero; the low 12 bits of CR3 are special and aren't actually address bits, instead they're flags or other fields. (Like PCID if that's enabled in another control register.)
    https://wiki.osdev.org/CPU_Registers_x86-64#CR3 shows the breakdown.