由于处理器指令只能使用虚拟地址,而没有办法通过直接指定物理地址来更新一个内存位置的内容。因此访问PML4、PDPT等的唯一方法是将它们也映射到相应的虚拟地址上。虚拟内存管理才能够修改处理器的分页结构。
解决这个问题的方案是以一种非常特殊的方式使用一项PML4e:即Windows无页表随机化以前使用0x1ed处的项存储PML4自身的PFN,我们将这项称为PML4 Auto-Entry. 接下来我们将看到他的作用。
我们知道一个PML4e映射了512GB的虚拟地址空间,那么因为这个特殊项的存在,那么一定有那么一个范围大小的空间为这个特殊目的而保留。
接下来我们就确定一下这个PML4e所对应的地址空间范围。
我们知道PML4的索引被存储到VA的第39-47位,那么索引为0x1ed时,对应的虚拟地址就可以相应的推出来。
虚拟地址的39-47反推为0x1ed,因为47位为1,所以48-63也必须为1. 而0-38位可以从全0到全1. 因此地址范围就可以很快知道
最终推出这个虚拟地址范围为
0xFFFFF68000000000 -- 0xFFFFF6FFFFFFFFFF
如果以范围后的首字节位结束地址那么范围为
0xFFFFF68000000000 -- 0xFFFFF70000000000
这个地址范围的虚拟地址的索引全是0x1ed,PML4e即为PML4 Auto-Entry。本来应该利用这个项的PFN定位PDPT,但是他却指向了PML4自身。在这种情况下,虚拟地址的30-38位索引得到的就是PDPTE,从21-29位索引得到的就是PDE。接着从20-12位索引得到的就是PTE。
PTE的虚拟地址就从0xFFFFF680`00000000开始,也就是我们常说的PTE_BASE。
PTEs是8字节大小,因此下一个PTE的虚拟地址就是0xFFFFF680`000000081
给定一个虚拟地址,那么他的PTE一定在512GB区域的某一个地方。在哪里呢?
求解方法:
给定一个虚拟地址,我们进行如下转化:
就会得到一个新的虚拟地址,即为所求。
得到这个PTE的虚拟地址后,进一步转化:
又得到一个新的虚拟地址,这个值是PTE映射的虚拟页的首地址。
将PML4 index 和 PDPT index域设置成auto-entry index,这样实际上PD index索引的就是PDPT,PT index索引的就是PD,即可看到PDEs。
PDE的范围因此也可以相应的计算出来
PDE开始地址 : 0xFFFFF6FB'40000000 即PDE_BASE
PDE结束地址:0xFFFFF6FB'80000000
可以发现这个地址范围在之前计算出来的PTE里。
也就是说他把实际的PTE范围分成了两个区域,中间的范围是拿给PDE映射的,而不是PTE。
给定一个VA也可以计算出其PDE的虚拟地址。一个PDE映射了512个PTE。
PDPTEs的虚拟地址就是左边填3个auto-entry index项。
PDPTE的起始地址就是 0xFFFFF6FB'7DA00000,即PPE_BASE
PDPTE的结束地址就是 0xFFFFF6FB'7DC00000
给定一个VA也可以计算出其PDPTE的虚拟地址。(移出三个index空位,分别将auto-entry index填入PML4,PDPT,PD)
如果四个索引位都设置成auto-entry index的话,那么会得到一个4kb的范围.
PML4E 起始地址 0xFFFFF6FB'7DBED000,即PXE_BASE
PML4E 结束地址 0xFFFFF6FB'7DBEE000
PML4 auto-entry的index是0x1e8。他的offset=0x1e8 x 8 = 0xf68。那么他的VA就是0xFFFFF6FB'7DBED000 + 0xF68 = 0XFFFFF6FB7DBEDF68。
由此可做如下内存区域区
接下来可以编写代码完成相关功能
测试结果如下
完整代码github:
https://github.com/BeneficialCode/PagingStructuresRegion
bit # 6 4 4 4 4 3 3
3...8 7 4 0 9 6
1...1 1111 0110 1xxx x...x
|___| |___||___||___|
| | | |
FFFF F 6 8-F
bit # 6 4 4 4 4 3 3
3...8 7 4 0 9 6
1...1 1111 0110 1xxx x...x
|___| |___||___||___|
| | | |
FFFF F 6 8-F
1
1110
1101
bit
3.
..
8
7
4
0
9
6
1
09
1.
..
1
1111
0110
1111
1011
01.
.
|___| |___||___||__| |__| |___|
| | | | | |
FFFF F
6
F B
4
-
7
1
1110
1101
bit
3.
..
8
7
4
0
9
6
1
09
1.
..
1
1111
0110
1111
1011
01.
.
|___| |___||___||__| |__| |___|
| | | | | |
FFFF F
6
F B
4
-
7
FFFFF700`00000000 |------------| --------------------------------------
| | |
| PTE High | |
| | |
FFFFF6FB`80000000 |------------| ----------------------------- |
| | | |
| PDE High | | |
| | | |
FFFFF6FB`7D000000 |------------|------------------ | |
| | | | |
| PDPTE High | | | |
FFFFF6FB`7DBEE000 |------------|----- | | |
| PML4E | | 4KB | 2MB | 1GB | 512GB
FFFFF6FB`7DBED000 |------------|----- PXE_BASE | | |
| | | | |
| PDPTE Low | | | |
FFFFF6FB`7DA00000 |------------|------------------ PPE_BASE | |
| | | |
| PDE Low | | |
| | | |
FFFFF6FB`40000000 |------------| ---------------------------- PDE_BASE|
| | |
| PTE Low | |
| | |
FFFFF680`00000000 |------------| -------------------------------------- PTE_BASE
Paging Structures Region
FFFFF700`00000000 |------------| --------------------------------------
| | |
| PTE High | |
| | |
FFFFF6FB`80000000 |------------| ----------------------------- |
| | | |
| PDE High | | |
| | | |
FFFFF6FB`7D000000 |------------|------------------ | |
| | | | |
| PDPTE High | | | |
FFFFF6FB`7DBEE000 |------------|----- | | |
| PML4E | | 4KB | 2MB | 1GB | 512GB
FFFFF6FB`7DBED000 |------------|----- PXE_BASE | | |
| | | | |
| PDPTE Low | | | |
FFFFF6FB`7DA00000 |------------|------------------ PPE_BASE | |
| | | |
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2023-10-19 22:38
被VirtualCC编辑
,原因: 修正代码显示问题