“Any page that is mapped to a virtual address is bound to have its PTE regardless
of page size - otherwise it would not be accessible to CPU in protected mode
with paging enabled.”
Anton, I totally respect you because I’ve seen you give good answers elsewhere, but I wish you would look at the things I cited in my original long post. If you would have done so you would have said “Hey, the figures you cite don’t exist in the latest Intel manual!”. And indeed, they don’t because I’m using a physical book which is apparently out of date (at least for reference purposes, not content-wise)
I’m sure you have a good understanding of how PAE normally works, that is to say in the kernel/userspace 4KB case. But because I can see that 2MB PAE pages are not addressed in either version 4 or 5 of the windows internals books, and I can’t find good descriptions of how it works through searching, I have to remain skeptical when people describe it, if it doesn’t jive with what I’m seeing.
OK, so here’s the relevant document:
http://www.intel.com/Assets/PDF/manual/253668.pdf
And the page to look at is:
4-18, Figure 4-6. How do I know it’s figure 4-6 and not 4-5? Because per page 4-20, table 4-9, if bit [7] is 1, then it is a 2MB page. Looking at the entry I posted before
kd> !pte 0x80656000
VA 80656000
PDE at 00000000C0602018 PTE at 00000000C04032B0
contains 00000000006009E3 contains 0000000000000000
pfn 600 -GLDA–KWEV LARGE PAGE pfn 656
If we look at the PDE, we see the value is 00000000006009E3. The 7th bit of this value is 1. Therefore, by definition, we are using figure 4-6, and at least in the Intel sense, there is no page table being used. This is why I said there was no PTE (and why the information in the Windows Internals book which says “The PTE is set to invalid” almost certainly doesn’t apply.
Anton, do you agree with my assessment that if the architecture in figure 4-6 is being used, there is no such thing as a PTE in the traditional sense? There is only the PDE, which per the debugger and windows internals, points at a PFN. Indeed, by looking at the above entry, we can see that the “pfn 600” line is derived from the uppermost portion of “6009E3”. This is in conflict which your statement
“Any page that is mapped to a virtual address is bound to have its PTE regardless
of page size - otherwise it would not be accessible to CPU in protected mode
with paging enabled.”
I must also take issue with your statement:
"MmIsAddressValid() just checks Present bit of PTE. "
Here is the relevant trace of assembly for MmIsAddressValid which shows that for the virtual address I am looking at, the *only* value which is being checked is the [7]th bit of the PDE (which I previously called the 0x80 bit.)
nt!MmIsAddressValid:
80512d9e 8bff mov edi,edi
80512da0 55 push ebp
80512da1 8bec mov ebp,esp
80512da3 51 push ecx
80512da4 51 push ecx
80512da5 8b4d08 mov ecx,dword ptr [ebp+8]
ecx now == the virtual address we passed in
80512da8 56 push esi
80512da9 8bc1 mov eax,ecx
80512dab c1e812 shr eax,12h
80512dae bef83f0000 mov esi,3FF8h
80512db3 23c6 and eax,esi
80512db5 2d0000a03f sub eax,3FA00000h
eax now is C0602018 - the page directory offset
80512dba 8b10 mov edx,dword ptr [eax]
edx is now 006009E3 - the PDE
80512dbc 8b4004 mov eax,dword ptr [eax+4]
80512dbf 8945fc mov dword ptr [ebp-4],eax
80512dc2 8bc2 mov eax,edx
80512dc4 57 push edi
80512dc5 83e001 and eax,1
yep, checking the present bit
80512dc8 33ff xor edi,edi
80512dca 0bc7 or eax,edi
80512dcc 7461 je nt!MmIsAddressValid+0x91 (80512e2f)
80512dce bf80000000 mov edi,80h
80512dd3 23d7 and edx,edi
Checking the [7]th bit. Because it’s set, the result is 0x80 in edx.
80512dd5 6a00 push 0
80512dd7 8955f8 mov dword ptr [ebp-8],edx
80512dda 58 pop eax
80512ddb 7404 je nt!MmIsAddressValid+0x43 (80512de1)
80512ddd 85c0 test eax,eax
80512ddf 7452 je nt!MmIsAddressValid+0x95 (80512e33)
It just pushed 0 and then popped it into eax…this jump will always be taken
80512e33 b001 mov al,1
80512e35 5f pop edi
80512e36 5e pop esi
80512e37 c9 leave
80512e38 c20400 ret 4
So there you have it folks, if it’s a 2MB page (0x80 bit set), MmIsAddressValid always returns true.
Now I have no prior experience dealing with PAE, only regular paging as implemented in (you guessed it Peter) my university OS class. The concept of anything except a 4KB page and especiallythe PFN database is quite foreign to me. However, as I previously described, and I’m looking for evidence to the contrary, as far as I can tell, the only way which this 2MB page can be translatable (in the absense of that page table level of indirection), is if Windows just stacks all the PFN entries together when ntkrnlpa.exe is loaded, so that as I said before, to find the PFN for 0x80656000, you first get the PFN for the PDE (which as you can see above is 0x600) and then do PFN_for_PDE+(0x56000/0x1000), which equals PFN 0x656.
So basically, like I said before, my charter is to read and hash the memory, and I don’t really want to give up until I understand why it’s impossible (since hopefully the previous discussions can convince people that I may be a little more capable than those who came before me ;). And in particular, if I’m way off base, I would love it if someone could prove it by just popping open WinDbg, finding the base of the kernel by putting “nt” into an address bar, and then showing the !pte output, and explaining how you correctly translate from virtual address to PFN and/or physical address. 
Thanks
Jack