I'm studying about Virtual Address Translation in Windows 10 x64. I also read about PML4,PDP,PDE and PTE and now I'm trying to change the stack's nx-bit in order to execute code in stack by modifying the paging structures.
I saw the following image which describes about nx-bit in PML4E,PDPE,PDE and PTE :
Let's assume we have created a kernel debug Windbg using VMWare and in the guest machine, we are debugging a simple application using xdbg64.
After attaching to the target process using xdbg64, now rsp
points to 00000089F06FF848
.
I change the program flow and execute jmp rsp
and now, rip
points to rsp
but it gives an access_violation exception
because of DEP so I can't execute any code in the stack. (previously I changed the stack with something like xor rax,rax
to have a valid assembly code there).
Now I pause the guest machine using Windbg from the host and to make a valid translation, change the explicit process to the target process using .process /f /i ffffa9841d9952c0
and after pressing g
,now our cr3
is valid for translation.
Then I use the following command in order to get PML4E,PDPE,PDE,PTE physical address :
kd> !vtop 0 00000089F06FF848
Amd64VtoP: Virt 00000089`f06ff848, pagedir 34848000
Amd64VtoP: PML4E 34848008
Amd64VtoP: PDPE 3316e138
Amd64VtoP: PDE 340efc18
Amd64VtoP: PTE 31de77f8
Amd64VtoP: Mapped phys 68a6b848
Virtual address 89f06ff848 translates to physical address 68a6b848.
From the above picture , the 63th bit is for NX-Bit then I get all the entries(PML4E, PDPE, PDE, PTE) to see what is there.
In the case of PML4E, it is :
kd> !db 34848008
#34848008 67 e8 16 33 00 00 00 0a-00 00 00 00 00 00 00 00 g..3............
#34848018 67 88 77 55 00 00 00 0a-00 00 00 00 00 00 00 00 g.wU............
#34848028 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#34848038 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#34848048 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#34848058 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#34848068 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#34848078 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Converting 67 e8 16 33 00 00 00 0a (01100111 11101000 00010110 00110011 00000000 00000000 00000000 00001010)
to
67 e8 16 33 00 00 00 0b (01100111 11101000 00010110 00110011 00000000 00000000 00000000 00001011)
(Please note the bold bit.)
PDPE is :
kd> !db 3316e138
#3316e138 67 f8 0e 34 00 00 00 0a-00 00 00 00 00 00 00 00 g..4............
#3316e148 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#3316e158 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#3316e168 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#3316e178 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#3316e188 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#3316e198 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#3316e1a8 00 00 00 00 00 00 00 00-67 f8 0e 34 00 00 00 0a00 00 00 00 00 00 00 00 ................
Converting 67 f8 0e 34 00 00 00 0a (01100111 11111000 00001110 00110100 00000000 00000000 00000000 00001010)
to
67 f8 0e 34 00 00 00 0b (01100111 11111000 00001110 00110100 00000000 00000000 00000000 00001011)
PDE is :
kd> !db 340efc18
#340efc18 67 78 de 31 00 00 00 0a-00 00 00 00 00 00 00 00 gx.1............
#340efc28 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#340efc38 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#340efc48 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#340efc58 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#340efc68 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#340efc78 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#340efc88 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Converting 67 78 de 31 00 00 00 0a (01100111 01111000 11011110 00110001 00000000 00000000 00000000 00001010)
to
67 78 de 31 00 00 00 0b (01100111 01111000 11011110 00110001 00000000 00000000 00000000 00001011)
And PTE is :
kd> !db 31de77f8
#31de77f8 67 b8 a6 68 00 00 00 81-00 00 00 00 00 00 00 00 g..h............
#31de7808 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#31de7818 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#31de7828 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#31de7838 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#31de7848 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#31de7858 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#31de7868 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
And in this case I didn't modify anything because 67 b8 a6 68 00 00 00 81 is equals 01100111 10111000 10100110 01101000 00000000 00000000 00000000 10000001 since its last bit is 1.
In the last step I run the !vtop
again to see if it still translates to the same physical address and I see that it's correct (Points to the same location.)
Then I press g
in order test it to see if it can execute the stack contents or not but I see it still gives the same error (access_violation) and cannot execute that address (rsp
).
So I have the following questions :
Whats wrong with my modification that doesn't have any affect ?
I heared that GDT also have somthing like NX-Bit that prevents the stack execution, What are diffrences between GDT execution prevention and NX-Bit in paging-level?
Why there are 4-levels that define nx-bit? Is changing just one of the above entries like pml4e affect all the other entries ?