昨天在看周哥讲x64内核的时候,得知了windows10的某个版本开始,页表基址不再固定了。
今天晚上突然有了个思路,就动手把他敲出来了,这种思路是不是已经烂大街了我也不确定,就当发出来学习交流吧。
这里用x86的10-10-12分页举例吧,比较好理解,理解了x64的也差不多的
启用了保护模式和分页机制后,咱就不能直接访问物理地址了,都会被cpu当作虚拟地址进行转换。
但是cr3存的又是物理地址,不能直接操作页表了,那咋办呢?
聪明的前辈们,选择在页目录表中选择一项(共1024项,每一项4字节),使其存储的物理地址与页目录表的基址(cr3)相同,这样子就可以构造一个访问页表的虚拟地址了,大概就是让cpu在地址转换的过程中绕圈圈。
理解有限,如有错误,还请指正
PVOID GetPXTBase() {
UINT64 cr3
=
__readcr3();
KdPrint((
"yuyu:cr3:%p\n"
, cr3));
for
(UINT64 i
=
0
; i <
512
; i
+
+
) {
/
/
构造虚拟地址
PVOID pxtBase
=
(PVOID)(
0xffff000000000000
| (i <<
12
) | (i <<
21
) | (i <<
30
) | (i <<
39
));
PHYSICAL_ADDRESS physical
=
MmGetPhysicalAddress(pxtBase);
KdPrint((
"yuyu:i:%d 物理:%p 虚拟:%p\n"
, i, physical.QuadPart, pxtBase));
if
(cr3
=
=
physical.QuadPart) {
return
pxtBase;
}
}
return
NULL;
}
PVOID GetPXTBase() {
UINT64 cr3
=
__readcr3();
KdPrint((
"yuyu:cr3:%p\n"
, cr3));
for
(UINT64 i
=
0
; i <
512
; i
+
+
) {
/
/
构造虚拟地址
PVOID pxtBase
=
(PVOID)(
0xffff000000000000
| (i <<
12
) | (i <<
21
) | (i <<
30
) | (i <<
39
));
PHYSICAL_ADDRESS physical
=
MmGetPhysicalAddress(pxtBase);
KdPrint((
"yuyu:i:%d 物理:%p 虚拟:%p\n"
, i, physical.QuadPart, pxtBase));
if
(cr3
=
=
physical.QuadPart) {
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-12-18 12:30
被yuyuaqwq编辑
,原因: