Inchoerence of the PTE_BASE address

Hi,

I am developing a kernel driver as part of a research project to measure the amount of bytes a process writes in memory.
I am facing an issue quite peculiar. It arises whenever I convert a particular virtual address to a physical address.

Let me explain my test case:

I am using a test process which simply writes a string in a virtual allocated memory area, and it outputs its address.
Then, with windbg, I enter the context of that process (.process /p), and convert the virtual address of the allocated area in a physical one by means of vtop. The command I use is: !vtop dirbase (first 20 bits) virtual_address.

Now if I dump the two addresses so obtained, the resulting dumps match. That’s good as it should be.

What is driving me crazy is when I perform the same thing with the address of the PTE_BASE (0xC000000).
After getting the physical address by means of vtop

lkd> !vtop 15c56 c0000000
X86VtoP: Virt c0000000, pagedir 15c56000
X86VtoP: PDE 15c56c00 - 15c56063
X86VtoP: PTE 15c56000 - 1607e067
X86VtoP: Mapped phys 1607e000
Virtual address c0000000 translates to physical address 1607e000.

the dumps (of the virtual and physicial memory) do not match at all).

lkd> dc c0000000
c0000000 00000000 00000000 00000000 00000000 …
c0000010 00000000 00000000 00000000 00000000 …
c0000020 00000000 00000000 00000000 00000000 …
c0000030 00000000 00000000 00000000 00000000 …
c0000040 2225f067 00000000 00000000 00000000 g.%"…
c0000050 00000000 00000000 00000000 00000000 …
c0000060 00000000 00000000 00000000 00000000 …
c0000070 00000000 00000000 00000000 00000000 …

lkd> dc /p 1607e000
1607e000 00000000 00000000 00000000 00000000 …
1607e010 00000000 00000000 00000000 00000000 …
1607e020 00000000 00000000 00000000 00000000 …
1607e030 00000000 00000000 00000000 00000000 …
1607e040 15fff067 00000000 00000000 00000000 g…
1607e050 00000000 00000000 00000000 00000000 …
1607e060 00000000 00000000 00000000 00000000 …
1607e070 00000000 00000000 00000000 00000000 …

Any idea?

Stefano Ortolani wrote:

I am developing a kernel driver as part of a research project to measure the amount of bytes a process writes in memory.
I am facing an issue quite peculiar. It arises whenever I convert a particular virtual address to a physical address.

What is driving me crazy is when I perform the same thing with the address of the PTE_BASE (0xC000000).
After getting the physical address by means of vtop

lkd> !vtop 15c56 c0000000
X86VtoP: Virt c0000000, pagedir 15c56000
X86VtoP: PDE 15c56c00 - 15c56063
X86VtoP: PTE 15c56000 - 1607e067
X86VtoP: Mapped phys 1607e000
Virtual address c0000000 translates to physical address 1607e000.

the dumps (of the virtual and physicial memory) do not match at all).

This happens because you’re doing local kernel debugging. With local
kernel debugging, the debugger cannot freeze the system (obviously, I
hope), so process switches continue to go on, and the physical memory
map (which is incredibly dynamic) changes. Each of these commands is
seeing a snapshot at a different point in time.

If you were using windbg over a physical cable to a second system, the
other system would be frozen, and the information would match.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Try using .process /P (note the capital P) or .cache forcedecodeptes.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Stefano Ortolani
Sent: Tuesday, December 07, 2010 3:01 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Inchoerence of the PTE_BASE address

Hi,

I am developing a kernel driver as part of a research project to measure the amount of bytes a process writes in memory.
I am facing an issue quite peculiar. It arises whenever I convert a particular virtual address to a physical address.

Let me explain my test case:

I am using a test process which simply writes a string in a virtual allocated memory area, and it outputs its address.
Then, with windbg, I enter the context of that process (.process /p), and convert the virtual address of the allocated area in a physical one by means of vtop. The command I use is: !vtop dirbase (first 20 bits) virtual_address.

Now if I dump the two addresses so obtained, the resulting dumps match. That’s good as it should be.

What is driving me crazy is when I perform the same thing with the address of the PTE_BASE (0xC000000).
After getting the physical address by means of vtop

lkd> !vtop 15c56 c0000000
X86VtoP: Virt c0000000, pagedir 15c56000
X86VtoP: PDE 15c56c00 - 15c56063
X86VtoP: PTE 15c56000 - 1607e067
X86VtoP: Mapped phys 1607e000
Virtual address c0000000 translates to physical address 1607e000.

the dumps (of the virtual and physicial memory) do not match at all).

lkd> dc c0000000
c0000000 00000000 00000000 00000000 00000000 …
c0000010 00000000 00000000 00000000 00000000 …
c0000020 00000000 00000000 00000000 00000000 …
c0000030 00000000 00000000 00000000 00000000 …
c0000040 2225f067 00000000 00000000 00000000 g.%"…
c0000050 00000000 00000000 00000000 00000000 …
c0000060 00000000 00000000 00000000 00000000 …
c0000070 00000000 00000000 00000000 00000000 …

lkd> dc /p 1607e000
1607e000 00000000 00000000 00000000 00000000 …
1607e010 00000000 00000000 00000000 00000000 …
1607e020 00000000 00000000 00000000 00000000 …
1607e030 00000000 00000000 00000000 00000000 …
1607e040 15fff067 00000000 00000000 00000000 g…
1607e050 00000000 00000000 00000000 00000000 …
1607e060 00000000 00000000 00000000 00000000 …
1607e070 00000000 00000000 00000000 00000000 …

I was going to update my post (I solved the situation :)) When I saw the two replies. First of all thanks to the both of you :slight_smile:

Basically Pavel Lebedinsky is right. It is just weird the fact that the debugger features some sort of cache by default :slight_smile:

Anyway, using “.process /P” solved the problem. However, I don’t get why I cant’ disable the cache, as all the time I try to issue the command, windbg tells me its use is not allowed in the current sessions (even if it is the newly created one).

Debugger cache is used only for live targets, local kd doesn’t really need it. However, local kd still needs to decide how to translate virtual addresses to physical ones when you switch to a process. This is where the different .process options come into play:

.process: No translation is performed. All memory accesses are performed in the context of debugger’s process. Kernel memory which is valid in any process context (pool, system PTE mappings etc.) will be displayed correctly, everything else (user memory, session space, page tables etc.) will not.

.process /p: User addresses are translated using the page directory of the specified process, so commands like !peb should work correctly. Kernel addresses are not translated, so things like session space and page tables may still be displayed incorrectly.

.process /P: All addresses, user and kernel, are translated. Use this option if you need to look at session space, page tables or other process-specific data in the kernel space.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Tuesday, December 07, 2010 8:17 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Inchoerence of the PTE_BASE address

I was going to update my post (I solved the situation :)) When I saw the two replies. First of all thanks to the both of you :slight_smile:

Basically Pavel Lebedinsky is right. It is just weird the fact that the debugger features some sort of cache by default :slight_smile:

Anyway, using “.process /P” solved the problem. However, I don’t get why I cant’ disable the cache, as all the time I try to issue the command, windbg tells me its use is not allowed in the current sessions (even if it is the newly created one).


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Another observation is that, according to the OP’ data, the virtual address range 0x10000 -0x10fff is actually
valid and can be accessed by the UM code for both reading and writing…

Anton Bassov