Debugging Tools for Windows |
Most debugger commands use virtual addresses, not physical addresses, as their input and output. However, there are times that having the physical address can be useful.
There are two ways to convert a virtual address to a physical address: by using the !vtop extension, and by using the !pte extension.
Suppose you are debugging a target computer on which the MyApp.exe process is running and you want to investigate the virtual address 0x0012F980. Here is the procedure you would use with the !vtop extension to determine the corresponding physical address.
Converting a virtual address to a physical address using !vtop
**** NT ACTIVE PROCESS DUMP ****
....
PROCESS ff779190 SessionId: 0 Cid: 04fc Peb: 7ffdf000 ParentCid: 0394
DirBase: 098fd000 ObjectTable: e1646b30 TableSize: 8.
Image: MyApp.exe
Pdi 0 Pti 12f
0012f980 09de9000 pfn(09de9)
The second number shown on the final line is the physical address of the beginning of the physical page.
You can verify that this computation was done correctly by displaying the memory at each address. The !d* extension displays memory at a specified physical address:
# 9de9980 6d206e49 726f6d65 00120079 0012f9f4 In memory.......
# 9de9990 0012f9f8 77e57119 77e8e618 ffffffff .....q.w...w....
# 9de99a0 77e727e0 77f6f13e 77f747e0 ffffffff .'.w>..w.G.w....
# 9de99b0 .....
The d* (Display Memory) command uses a virtual address as its argument:
0012f980 6d206e49 726f6d65 00120079 0012f9f4 In memory.......
0012f990 0012f9f8 77e57119 77e8e618 ffffffff .....q.w...w....
0012f9a0 77e727e0 77f6f13e 77f747e0 ffffffff .'.w>..w.G.w....
0012f9b0 .....
Because the results are the same, this indicates that the physical address 0x09DE9980 does indeed correspond to the virtual address 0x0012F980.
Again, assume you are investigating the virtual address 0x0012F980 belonging to the MyApp.exe process. Here is the procedure you would use with the !pte extension to determine the corresponding physical address:
Converting a virtual address to a physical address using !pte
**** NT ACTIVE PROCESS DUMP ****
....
PROCESS ff779190 SessionId: 0 Cid: 04fc Peb: 7ffdf000 ParentCid: 0394
DirBase: 098fd000 ObjectTable: e1646b30 TableSize: 8.
Image: MyApp.exe
kd> .process /p ff779190
Implicit process is now ff779190
.cache forcedecodeuser done
VA 0012f980
PDE at C0300000 PTE at C00004BC
contains 0BA58067 contains 09DE9067
pfn ba58 ---DA--UWV pfn 9de9 ---DA--UWV
This is the same result obtained by the earlier method.
Although the !ptov and pte extensions supply the fastest way to convert virtual addresses to physical addresses, this conversion can be done manually as well. A description of this process will shed light on some of the details of the virtual memory architecture.
Memory structures vary in size, depending on the processor and the hardware configuration. This example is taken from an x86 system that does not have Physical Address Extension (PAE) enabled.
Using 0x0012F980 again as the virtual address, you first need to convert it to binary, either by hand or by using the .formats (Show Number Formats) command:
Evaluate expression:
Hex: 0012f980
Decimal: 1243520
Octal: 00004574600
Binary: 00000000 00010010 11111001 10000000
Chars: ....
Time: Thu Jan 15 01:25:20 1970
Float: low 1.74254e-039 high 0
Double: 6.14381e-318
This virtual address is a combination of three fields. Bits 0 to 11 are the byte index. Bits 12 to 21 are the page table index. Bits 22 to 31 are the page directory index. Separating the fields, you have:
This exposes the three parts of the virtual address:
You then need three additional pieces of information for your system.
Using this data, you can compute the address of the PTE itself:
+ (page directory index) * PAGE_SIZE
+ (page table index) * sizeof(MMPTE)
= 0xc0000000
+ 0x0 * 0x1000
+ 0x12F * 4
= 0xC00004BC
This is the address of the PTE. The PTE is a 32-bit DWORD. Examine its contents:
c00004bc 09de9067
This PTE has value 0x09DE9067. It is made of two fields:
The first physical address on the physical page is the PFN multiplied by 0x1000 (shifted left 12 bits). The byte index is the offset on this page. Thus,the physical address you are looking for is 0x09DE9000 + 0x980 = 0x09DE9980. This is the same result obtained by the earlier methods.