Hey. I have a physical address and I’d like to know 2 things 1. Which process owns it 2. The virtual address it is mapped by I’m trying to understand how it works under the hood, had the look at MmGetVirtualForPhysical, still not entirely sure I’ve read the following description on how to achieve this “ The interesting thing is that in this case, the PTE that is managing this page will belong in the Hardware page tables created for the process which is using this page. That PTE, in turn will also be accessible by a PDE inside that process’s page tables, and so forth. This occurs all the way up to the root of the page table (DTB or CR3) which is its own PTE. Therefore if we keep following the PTE which controls each PTE 4 times we will discover the physical addresses of the DTB, PML4, PDPTE, PDE and PTE belonging to the given physical address. Since a DTB is unique to a process we immediately know which process owns this page. Additionally we can also figure out what is the virtual address by subtracting the table offset of the real PTE from the start of the PTE table at each level of the paging structure, and assigning the relevant bits to that part of the virtual address” I’m struggling to grasp the methodology , could someone elaborate on the following ? * for 1, to get the owning PTE of the physical address is easy. But how can you get the owning PTE of PTE ? (What it suggests I should do to traverse back to CR3) * for 2(getting the VA) , I’m more sure which table base and which offset they are referring to. How do I know them having only the virtual address of the PTE and a physical address A practical example or explanation will be appreciated Thanks!
Physical addresses are not owned by a process. Further, many pages of physical memory are mapped into multiple virtual addresses, and sometimes multiple processes.
For example, if you submit an I/O operation that uses direct I/O, the buffer (which has a virtual address within your process) is mapped into kernel memory, thereby getting a SECOND virtual address that maps to the same set of physical pages. When you load a common DLL into your process, the physical pages of DLL are assigned a virtual address, but those physical pages also have virtual address mappings in all of the other processes that use the DLL.
And you have the lookup process backwards. The page tables are indexed by virtual address, not physical. You start with a virtual address. You use the page tables to drill down to a single PTE for that virtual address, and the contents of the PTE tells you the matching physical address.
The only way to do the conversion the other way (physical to virtual) is to search manually through all of the page tables, remembering that the address might occur multiple times.
Remember that EVERY processor instruction deals with virtual addresses. The ONLY time physical addresses are used are in programming CR3.
Right ! Ignore the mess of that question MmGetVirtualForPhysical still achieves this tho… I know there’s a way to get the virtual address of the PTE from a physical address(using MmPfnDatabase) I also know there’s a function MiGetPteAddress to get PTE virtual address from VA It uses a hard coded value articles are referring to as “PteBase” and a few bit wise operations Do you think the opposite can be done? ( get virtual address from virtual address of PTE?) What’s that PteBase value all about?
MmGetVirtualForPhysical still achieves this tho…
Sort of. MmGetVirtualForPhysical, which I believe is undocumented, does not search the page tables. It relies on the internal implementation detail that the low part of the kernel virtual space is mapped 1:1 into physical space at a known location. All it does is a little masking and arithmetic on the address. It doesn’t use the page tables, and it won’t find any user-mode mappings.
I also know there’s a function MiGetPteAddress to get PTE virtual address from VA
Yes, but again that’s going in the opposite direction – virtual to physical. And again, that API is undocumented.
Do you think the opposite can be done? ( get virtual address from virtual address of PTE?)
If you have something to hand to MiGetPteAddress, then you already KNOW the virtual address. The key point is that there might be OTHER virtual addresses for that physical page. As I told you before, the ONLY way to find that is to exhaustively search the current page directory. That’s what windbg does for the !ptov command, and it’s why that command takes a while.
Why do you want this information? There is nothing useful to be done with this in driver programming.