Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Hardware supported NX is dependent on PAE (Windows Internals chapter 9. Memory). But why would that be?
The AMD64 Architecture Programmer's Manual (Volume 2: System Programming) mentions this:
No Execute (NX) Bit. Bit 63. This bit is present in the translation-table entries defined for PAE paging, with the exception that the legacy-mode PDPE does not contain this bit. This bit is not supported by non-PAE paging.
Again from Windows Internals we know that PTEs with PAE enabled are 64 bits long; without PAE they are only 32 bits long. There simply is no bit 63 for non-PAE paging. We can see it in the debugger.
Here is a call stack from the non-PAE crash dump:
0: kd> k
ChildEBP RetAddr
8292dc0c 968a1160 nt!KeBugCheckEx+0x1e
8292dc3c 968a1768 i8042prt!I8xProcessCrashDump+0x251
8292dc88 82840d4d i8042prt!I8042KeyboardInterruptService+0x2ce
8292dc88 8286449a nt!KiInterruptDispatch+0x6d
8292dd24 00000000 nt!KiIdleLoop+0x1a
If we dump out the the ChildEBP for the 2nd frame:
0: kd> !pte 8292dc3c
VA 8292dc3c
PDE at C0300828 PTE at C020A4B4
contains 001BF063 contains 0292D963
pfn 1bf ---DA--KWEV pfn 292d -G-DA—KWEV
You see that the PTE contains a 32 bit value (0292D963).
The same exercise on a PAE enabled system gives us this call stack:
1: kd> k
ChildEBP RetAddr
807e1c0c 928bd160 nt!KeBugCheckEx+0x1e
807e1c3c 928bd768 i8042prt!I8xProcessCrashDump+0x251
807e1c88 828587cd i8042prt!I8042KeyboardInterruptService+0x2ce
807e1c88 8288101a nt!KiInterruptDispatch+0x6d
807e1d24 00000000 nt!KiIdleLoop+0x1a
The PTE here is 64 bit:
1: kd> !pte 807e1c3c
VA 807e1c3c
PDE at C0602018 PTE at C0403F08
contains 000000007A986863 contains 800000002D21F963
pfn 7a986 ---DA--KWEV pfn 2d21f -G-DA--KW-V
We would expect bit 63 on the ChildEBP to be set (EBP is on the stack and we would not want to execute any code from the stack: NX should be 1).
1: kd> .formats 800000002D21F963
Evaluate expression:
Hex: 80000000`2d21f963
Decimal: -9223372036097574557
Octal: 1000000000005510374543
Binary: 10000000 00000000 00000000 00000000 00101101 00100001 11111001 01100011
…
How about the return address of that same frame?
1: kd> !pte 928bd768
VA 928bd768
PDE at C06024A0 PTE at C04945E8
contains 0000000023615863 contains 000000007B9CD121
pfn 23615 ---DA--KWEV pfn 7b9cd -G--A—KREV
There the bit is not set:
1: kd> .formats 000000007B9CD121
Evaluate expression:
Hex: 7b9cd121
Decimal: 2073874721
Octal: 17347150441
Binary: 01111011 10011100 11010001 00100001
…
Note that .formats truncates the preceding 0s.