Paging – Virtual to Physical address translation via WinDbg

转自:http://blog.nandaka.io/paging-virtual-to-physical-address-translation-via-windbg/

PAE/Non-PAE参考:

Paging – Virtual to Physical address translation
Paging in PAE-mode – Virtual to Physical Address Translation

We have covered the address translation for PAE and non-PAE mode in x86 in previous articles. In this article we will see the address translation in action. We will first do it manually and then learn ‘!pte’ command in WinDbg which will dump the PDE and PTE for us without much of effort.

I am using Win7 x86 VM and PAE mode is by default enabled so we will go through the 3 levels of translations.

It is strongly recommended that you go through the previous articles on address translation before continuing further.

 

Figure below will help you recall how the virtual address is divided in PAE mode.

 

Here is the memory address translation process in PAE mode:

Image taken from the book, Windows Internals by M Russinovich, D A Solomon, A Ionescu.

Each PTE\PDE entry is 64 bit wide and PFN bits that are used to locate the base of physical page are 24 bits as compared to 20 bits in 32 bit PTE\PDE.

 

Let’s start with the translation. We know that in PAE mode, CR3 CPU register holds the base address of Page Directory Pointer Table(PDPT). Each process running on Windows has its own Directory Base(DirBase) which stores the physical address of PDPT. CR3 CPU register is loaded with this DirBase whenever a context switch happens for the thread which belong to a process different than the current running thread. You can dump the DirectoryTableBase with the following WinDbg command:

 

1: kd> !process 0 0 explorer.exe

PROCESS 84d59030  SessionId: 1  Cid: 045c    Peb: 7ffd5000  ParentCid: 00f0

    DirBase: 3ec331a0  ObjectTable: 8ce0eb20  HandleCount: 641.

    Image: explorer.exe

 

0: kd> dt nt!_KPROCESS 84d59030   -y dir

   +0x018 DirectoryTableBase : 0x3ec331a0

 

Let’s dump CR3 register.

 

0: kd> r cr3

cr3=00185000

 

I just mentioned that DirBase would be same as CR3 register however it is showing different value. The problem is that you are not in context of the process. This is a very common mistake so please make sure you are in the context of the process in WinDbg before you check CR3.

 

1: kd> .process /i 84d59030 

You need to continue execution (press ‘g’ ) for the context

to be switched. When the debugger breaks in again, you will be in

the new process context.

 

1: kd> g

Break instruction exception – code 80000003 (first chance)

nt!RtlpBreakWithStatusInstruction:

8266b394 cc              int     3

 

Now we are in the context of the process ‘explorer.exe’. If you dump CR3 CPU register now you will see the DirBase in CR3.

0: kd> r cr3

cr3=3ec331a0

 

Let’s pick a virtual address to do the translation, say process address itself i.e. 84d59030 

 

84d59030  ——> 10 000100110 101011001 000000110000

 

PDPT Index                                                                   10 = 2

PDT Index                                                                     000100110 = 38 or 0x26

PT Index                                                                        101011001 = 345 or 0x159

Byte Index                                                                    000000110000 = 48 or 0x30

 

CR3 CPU register or DirBase contains the physical address of base of PDPT. There are 4 possible entries in PDPT and virtual address PDPT index is 2. You can dump the physical memory via ‘!d’ WinDbg command as shown below.

 

Let’s dump the PDPT:

0: kd> !dq 3ec331a0 l4

#3ec331a0 00000000`10df0801 00000000`11271801

#3ec331b0 00000000`10e32801 00000000`11173801

 

 

Or you can directly dump the index 2 of PDPT as follow:

0: kd> !dq 3ec331a0 + (2*8) l1

#3ec331b0 00000000`10e32801

 

PDPT Entry  contains  00000000`10e32801

 

Revisit the format of the PDE\PTE in PAE mode. First 12 bits are for various flags and next 24 bits are for PFN. Highlighted in Green is the PFN part of the PDPT Entry in PAE mode.

 

PFN of PDT base is  0`10e32 (24 bits in PAE mode).

 

Physical address of PDT base is 10e32000 (appended by 12 bits)

 

First level of table (PDPT) is translated and we have the base of PDT. Let’s move to the PDE of the virtual address 84d59030.

 

PDT Index from virtual address is decimal 38 or hex 26.

0: kd> ?10e32000+(26*8)

Evaluate expression: 283320624 = 10e32130

 

0: kd> !dq 10e32130 l1

#10e32130 00000000`3fec7863

 

PDE contains 00000000`3fec7863

 

Extract the PFN part:

PFN of base of Page Table(PT) is 3fec7 (24 bit in PAE Mode)

 

Physical address of PT base is 03fec7000 (appended by 12 bits)

 

0: kd> ?03fec7000+(0x159*8)

Evaluate expression: 1072462536 = 3fec7ac8

 

0: kd> !dq 3fec7ac8 l1

#3fec7ac8 00000000`3ef59963

 

PTE contains 00000000`3ef59963

 

PFN of the page where the virtual address resides is 03ef59

 

Base of the page is 03ef59000 (appended by 12 bits)

 

DWORD referred by the virtual address resides at the hex 30 byte offset:

 

0: kd> ?03ef59000+30

Evaluate expression: 1056280624 = 3ef59030

 

0: kd> !dd 3ef59030 l1

#3ef59030 00260003

 

Dump the content of the virtual memory by ‘dd’ command.

0: kd> dd 84d59030 l1

84d59030  00260003

 

Above translation can be easily done via ‘!pte’ WinDbg command as shown below.

 

0: kd> !pte 84d59030 

                    VA 84d59030

PDE at C0602130                           PTE at C0426AC8

contains 000000003FEC7863      contains 000000003EF59963

pfn 3fec7     —DA–KWEV             pfn 3ef59     -G-DA–KWEV

 

 

Or

 

Debugger does not show the PDPT in the output of ‘!pte’ Command but I have dumped it manually during the translation. Flags corresponds to the PDE\PTE flags mentioned above. Physical page where the virtual address points to is given by the PFN of PTE as shown above

 

 

In x64, it is no different except, additional levels of translation. Here is 64 bit PDE\PTE entry and translation process:

 

Image taken from the book, Windows Internals by M Russinovich, D A Solomon, A Ionescu.

 

PROCESS ffffe000ac169080

    SessionId: 1  Cid: 0228    Peb: f7a9cd5000  ParentCid: 01d4

    DirBase: 2ecbd000  ObjectTable: ffffc00134a5b7c0  HandleCount:

    Image: winlogon.exe

 

0: kd> r cr3

cr3=000000002ecbd000

 

Note: Make sure you are in the context of the process

 

Here is the output of ‘!pte’ command for 64 bit OS. I have taken the process address for translation. The offset in page is 80 highlighted in green.

0: kd> !pte ffffe000ac169080

                                              VA ffffe000ac169080

PXE at FFFFF6FB7DBEDE00    PPE at FFFFF6FB7DBC0010    PDE at FFFFF6FB78002B00    PTE at FFFFF6F000560B48

contains 0000000000532863  contains 0000000000331863  contains 0000000034BD9863  contains 8000000030342963

pfn 532       —DA–KWEV  pfn 331       —DA–KWEV  pfn 34bd9     —DA–KWEV  pfn 30342     -G-DA–KW-V

 

Or

 

The base address of the physical page is 30342000 and offset in 4K page is 080. Let’s first get the content via virtual address ffffe000ac169080.

 

0: kd> dq ffffe000ac169080 l1

ffffe000`ac169080  00000000`00b60003

 

Let’s do it via physical address obtained from PTE above and add offset hex 80 to it.

0: kd> !dq 30342000+80 l1

   #30342080 00000000`00b60003

 

 

Alright, so we have covered the address translation successfully. You can follow the manual process on x64 as well but just make sure that you are in the context of the process for which you are translating the virtual address and take caution while using hex and decimal number conversion.







你可能感兴趣的:(调试,器之卷)