真正理解windows 页表自映射的原理

我不会教你代码怎么写,但是你将明白这里面的原理:

现在假设一种很客观的情况
对于页表映射,从windbg中 唯一能感知的就是  CR3 寄存器,
在x64的平台下使用4级分页举例:

现在我们只有 CR3寄存器 中的物理地址(也就是PML4所在的那块内存的物理地址).
我(或者说操作系统)如何来操纵这块物理内存呢????(我们不是8086,不能直接操作物理地址).
我需要一个虚拟地址来操作它. 你知道,我们需要经过MMU的4层地址转换,最后才能获得对应的物理地址.

我现在只想要PML4 这张表的起始虚拟地址(base) ,我不想得到其他的什么东西..物理地址就在CR3里面摆着.

现在你知道我们要干什么了.很好!!!!!!!!  我们要构建一个  虚拟地址  找到PML4 这张表的起始虚拟地址(base)

设想一下,假如一个虚拟地址 9 9 9 9 12 分页下.
PML4[9]=CR3的值;

PML4[9]=还等于CR3值;

PML4[9]=还等于CR3的值;

PML4[9]=还等于CR3的值;

物理页内偏移=0;

通过构建符合上面要求的虚拟地址
我们通过CPU的MMU部件的4层转换后,得到的物理地址是不是就是CR3保存的物理地址(也即是PML4的首物理地址)!!!!!!!!
 

(为什么上面一直用PML4来查,不用PDPT PDT PT这样查下来......扭转一下思路....cpu不管你是什么ppp,还是ggg .你给我cr3里放一个物理地址.,我就就按你要求的分页模式,逐级翻译. 对不对是你操作系统的要保证的事)

下面来演示:

  1. windbg中查看一下CR3 的值
  2. 列出所有的PMML4E

为什么要列出所有来,你知道的.我现在在翻译第一级.我需要在PML4表中,找到PML4的物理地址(暂时先忘记cr3吧.cr3保存的不就是PML4表的首物理地址吗?)

找到了,它和cr3的值一样

现在我们来算一下第一个[9]索引  (你知道的)
0x187f68-0x187000=f68 /8=   111101101 
现在我们得到了虚拟地址第一个9位,你知道的.前面还有16位 基于扩高原则

再说一遍.4层地址翻译 过程中 我们实际在PML4表里面转圈.所以接下来我会直接给出虚拟地址了

[9]:111101101 [9]:111101101 [9]:111101101 [9]:111101101 [12]:0(我们不许要页内偏移)
基于虚拟地址的扩高原则 高[16]:1111111111111111

合起来:1111111111111111111101101111101101111101101111101101000000000000
得到一个PML4基址:FFFFF6FB7DBED000



赶紧来看一下对不对:

他妈的简直完美
你说这他妈的有什么用啊.我现在需要的是 我有一个 虚拟地址,我需要修改属性,我需要获得PML4E ,PDPTE,PDE,PTE .我要你这玩意有什么用
举例: 我要获得fffff880`04512070 这个虚拟地址的PXE(windbg的命名 等于PML4E)

拆前9位 得到PML4表中的索引
 Binary:  11111111 11111111 11111000 10000000 00000100 01010001 00100000 01110000
11111000 1=1F1 
FFFFF6FB7DBED000+1F1*8=?

你说哎,他妈的后面不是对不上吗???错了吧哈哈哈哈     你想一个页表只能存512项 就是0x200项
还是从0还是起算.实际索引只能是 0~1FF  (0~19 是不是20个?)..你数一下图里面,最后一个应该是物理地址#  187ff8 处.整张PML4表已经结束了


好了,基于上面的我们来讨论一下第二层表 虚拟bae地址怎么来了....

设想一下,假如一个虚拟地址 9 9 9 9 12 分页下.
PML4[9]=CR3的值;

PML4[9]=还等于CR3值;

PML4[9]=还等于CR3的值;

PML4[9]=第一个PDPT表的物理地址(总共0x200个)
页面索引[12]=0;
 

不知道你理解了吗?可能还是不太清楚.
下面我们试着构建一下虚拟地址


[9]:111101101 [9]:111101101 [9]:111101101 [9]:????????[页内偏移]:0

问号里面到底是什么值呢?   我们暂时先认为是 0 吧  ,总之我们构建了一个这个样的虚拟地址
 

[9]:111101101 [9]:111101101 [9]:111101101 [9]:000000000[页内偏移]:000000000000
1111111111111111111101101111101101111101101000000000000000000000
得到一个虚拟地址:FFFFF6FB7DA00000



举例: 还是刚才的虚拟地址: fffff880`04512070 

拆分这个虚拟地址:
 11111111 11111111 11111000 1 0000000 00 000100 0110001 0010 0000 01110000
得到:
[9]=0X1F1
 [9]=  0X0
[9]= 0X22
[9]=0X112
[9]=0X70

需要明确的是,
刚才我们获得的是第一张 PDPT表的虚拟基址,总共有512张(一个pml4e管理)
现在我们有PDPT的基址 :FFFFF6FB7DA00000  

当务之急是,我需要确定我到底在哪张PDPT表中. 
这很好办, 第一个[9] =1F1 已经给了我们答案  .我们在(从0开始的)第1F1张 PDPT表中
所以我们的虚拟地址 将变成  :
FFFFF6FB7DA00000 +1F1*  0x1000=FFFF F6FB 7DBF 1000

是时候来确定我们是哪个PDPTE 了,利用第二个[9]=0
FFFF F6FB 7DBF 1000+0x8=FFFF F6FB 7DBF 1000

需要说明一下的是: 照目前的情况来看,好像我们是对了,前提是 PDPT表 是连续排列的.
我们还假设 PML4[0]--->PDPT[0]   PML4[n]--->PDPT[n]  

继续 PDT表  

PML4[9]=CR3的值;

PML4[9]=还等于CR3值;

PML4[9]=第一个PDPT表的物理地址(总共0x200个)

PML4[9]=第一个PDT表的物理地址(总共0x200 *0x200个)
页面索引[12]=0;

[9]:111101101 [9]:111101101 [9]:000000000 [9]:000000000[页内偏移]:000000000000
1111111111111111111101101111101101000000000000000000000000000000
得到一个PDT表基址:FFFFF6FB40000000



可以看到  :我们确实找到了PT表的基址.验证一下,
还是这个地址: fffff880`04512070 

 

拆分这个虚拟地址:
 11111111 11111111 11111000 1 0000000 00 000100 0110001 0010 0000 01110000
得到:
[9]=0X1F1
 [9]=  0X0
[9]= 0X22
[9]=0X112
[9]=0X70

先确定一下,1个PML4E 管理512个PDPT表,总共管理 512 * 512 个PDT表
怎么确定我们在哪张PT表中?根据上面可以知道 ,我们在第1F1 张PDPTT表中的[0]张PDT表

FFFFF6FB40000000 + (1F1 * 一张PDPTT表的范围(512*8)+ 0 * 512 ))=FFFF F6FB 7E20 0000
现在我们确定在虚拟地址FFFF F6FB 7E20 0000 对应的PDT表中
具体在表的,在第[0x22 *8]个中
FFFF F6FB 7E20 0000+110=FFFF F6FB 7E20 0110
 


我们看下一得到的基址:

PML4表基址:FFFFF6FB7DBED000
PDPT表基址 :FFFFF6FB7DA00000  
PDT表基址:FFFFF6FB40000000
发现了什么吗?确实没发现什么,但是在构造虚拟地址的时候,
我们有了PML4表基址后 ,接下来的求解过程好像就是 从低[9]开始给清0  了,发现了吗???
PDPT表基址 :FFFFF6FB7DBED000>>21   <<21=FFFFF6FB7DA00000  
PDT表基址:  FFFFF6FB7DA00000  >>30  <<30=FFFFF6FB40000000
最后我们没有求PT表的基址
按照上面的推理   

PT表基址: FFFFF6FB40000000 >>39  <<39=FFFF F680 0000 0000

是时候来验证一下了:

实在是算不过来了.好心人 在评论区补充吧
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值