我正在研究 Windows 10 x64 中的虚拟地址转换。我还阅读了有关 PML4、PDP、PDE 和 PTE 的信息,现在我正在尝试更改堆栈的 nx 位,以便通过修改分页结构来执行堆栈中的代码。
我看到下图描述了 PML4E、PDPE、PDE 和 PTE 中的 nx 位:
假设我们已经使用 VMWare 创建了一个内核调试 Windbg,并且在客户机中,我们正在使用 xdbg64 调试一个简单的应用程序。
使用 xdbg64 附加到目标进程后,现在rsp
指向00000089F06FF848
. 我更改了程序流程并执行jmp rsp
,现在rip
指向rsp
但它给出了一个access_violation exception
因为 DEP,所以我无法执行堆栈中的任何代码。(以前我用类似的东西改变了堆栈,xor rax,rax
在那里有一个有效的汇编代码)。
.process /f /i ffffa9841d9952c0
现在我使用来自主机的 Windbg 暂停来宾机器并进行有效翻译,使用和将显式进程更改为目标进程g
,现在我们cr3
的翻译有效。
然后我使用以下命令来获取 PML4E,PDPE,PDE,PTE 物理地址:
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.
从上图中,第 63 位是 NX-Bit,然后我得到所有条目(PML4E、PDPE、PDE、PTE)来看看那里有什么。
对于 PML4E,它是:
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 ................
转换 67 e8 16 33 00 00 00 0a (01100111 11101000 00010110 00110011 00000000 00000000 00000000 0000101 0 )
至
67 e8 16 33 00 00 00 0b (01100111 11101000 00010110 00110011 00000000 00000000 00000000 0000101 1 )
(请注意粗体部分。)
PDPE是:
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 ................
转换 67 f8 0e 34 00 00 00 0a (01100111 11111000 00001110 00110100 00000000 00000000 00000000 0000101 0 )
至
67 f8 0e 34 00 00 00 0b (01100111 11111000 00001110 00110100 00000000 00000000 00000000 0000101 1 )
PDE 是:
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 ................
转换 67 78 de 31 00 00 00 0a (01100111 01111000 11011110 00110001 00000000 00000000 00000000 0000101 0 )
至
67 78 de 31 00 00 00 0b (01100111 01111000 11011110 00110001 00000000 00000000 00000000 0000101 1 )
PTE是:
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 ................
在这种情况下,我没有修改任何内容,因为 67 b8 a6 68 00 00 00 81 等于 01100111 10111000 10100110 01101000 00000000 00000000 00000000 10000001 因为它的最后一位是 1。
在最后一步中,我!vtop
再次运行以查看它是否仍转换为相同的物理地址,并且我发现它是正确的(指向相同的位置。)
然后我按下g
命令测试它是否可以执行堆栈内容,但我看到它仍然给出相同的错误(access_violation)并且无法执行该地址(rsp
)。
所以我有以下问题:
我的修改有什么问题没有任何影响?
我听说 GDT 也有类似 NX-Bit 的东西来阻止堆栈执行,GDT 执行阻止和 NX-Bit 在分页级别有什么区别?
为什么有定义 nx-bit 的 4 个级别?仅更改上述条目之一(如 pml4e)会影响所有其他条目吗?