【2021.03.31】页表基址

要点回顾

前文提到了也目标基址,也就是说通过0xC0300000这个线性地址可以访问页目录表(PDT),有了这个地址,就可以任意修改页目录表。

但是,如果要设置某个线性地址PDE和PTE,且还要能够访问PTT,该如何访问呢?

任何一个线性地址是由PDT和PTE决定的。能访问PDT就说明能访问任意一个线性地址的PDE,但如果仅仅能访问PDE的话,还没有办法控制任意一个线性地址。

也就是说还需要访问页表(PTT),那么该怎么访问PTT呢?

如果没有一个线性地址能访问PTT的话,就没有意义,那么操作系统有没有办法访问PTT呢?一定是有的,当我们申请内存的时候,它为什么能够给我们申请的某个线性地址挂上正确的物理页呢?就说明操作系统不但能够访问PDT,也能访问PTT。只有这样,它才能为我们分配的线性地址挂上正确的PDE和PTE。

拆分PTT表

1.寻找目标程序CR3

!process 0 0

2.直接访问CR3值

可以获得页目录表(PDT):

页目录表中的每一项成员,称为PDE,也就是页目录项。

这个表中有多少个PDE呢?1024个,每一个PDE占4个字节,只不过上图中并没有全部列出,因为根本用不了那么多,真正有值的可能就前面几个。

页目录表(PDT)中的每一个成员,也就是PDE(页目录项),都指向一个PTT(页表)。

决定一个线性地址需要一个PDE和PTE,如果想修改线性地址的PDE和PTE,就必须能访问PDT和PTT。

3.查看PDE

1.查看第一个PDE(它对应第一张页表(PTT))

!dd 3e9e8000:因为后面3位是属性,所以记得修改为0后再执行命令。

得到了第一张页表(PTT)。该表有1024个成员,一共有4KB的大小,每个成员占4个字节。

2.查看第二个PDE(它对应第二张页表(PTT))

!dd 1919f000:别忘了后三位是属性,要修改为0。

得到了第二章页表(PTT)。同样的,该表中有1024个成员,一共有4KB的大小,每个成员占4个字节。

3.查看第三个PDE(它对应第三张页表(PTT))

!dd 3ef8e000:同样的,后三位修改为0,不解释。

得到第三张页表(PTT),且其中是空的。

拆分0xC0000000/0xC0001000

已经知道了如何通过一个线性地址访问页目录表(PDT),如果能通过线性地址访问PTT表的话,意味着我们能掌握一个进程的所有内存。

对于一个进程来说,它最重要的就是内存,对于它的内存来说,最重要的就是PDE和PTE。

拆分C0000000

0xC0000000 = 1100 0000 0000 0000 0000 0000 0000 0000

前十位二进制:1100 0000 00 -> 300*4 = C00

再十位二进制:00 0000 0000 -> 0*4 = 0

0000 0000 0000

1.寻找目标程序CR3

!process 0 0

2.寻找PDE

!dd 24450000+C00

3.寻找PTE

!dd 24450000 + 0,因为偏移是0,所以可以直接 !dd 24450000

4.查看物理页

!dd 3e9e8000

可以发现和找到的第一个PTT是一样的。

C0000000找到的就是第一个页表(PTT)。

拆分C0001000

可以发现线性地址:0xC0001000和线性地址:0xC0000000相差1000,也就是说这两个线性地址中间刚好相差一个页,也就是4KB。

0xC0001000 = 1100 0000 0000 0000 0001 0000 0000 0000

前十位二进制:1100 0000 00 -> 300*4 = C00

再十位二进制:00 0000 0001 -> 1*4 = 4

0000 0000 0000

1.寻找目标程序CR3

!process 0 0

2.寻找PDE

!dd 24450000+C00

3.寻找PTE

!dd 24450000+4

4.查看物理页

!dd 1919f000

C0000000对应的刚好是第一个PTT,C0001000对应的刚好是第二个PTT。

总结

  1. 页表被映射到了从0xC0000000到0xC03FFFFF的4MB地址空间,因为一个PTT是4KB,有1024个PTT,所以它占用的内存空间是4MB。
  2. 在这1024个表中有一张特殊的表:0xC0300000页目录表(PDT),它既是PDT,也是PTT,也是物理页。
  3. 页目录被映射到了0xC0300000开始处的4KB地址空间。

也就是说,前文中为了便于理解,先列出了一个页目录表(PDT),该表中每一个成员对应一个PTT,有1024个PTT。

但是到目前为止,可以发现根本不存在PDT这张表,它的整个表的结构变成了如下这样:

也就是该表中的0xC0300000访问PDT表,0xC0000000访问的是第一个PTT表。

有了0xC0300000和0xC0000000,可以做什么?

掌握了这两个地址,就掌握了一个进程所有的物理内存读写权限。

公式总结

  • 1.什么是PDI与PTI?

PDE称为页目录表项,PTE称为页表项。PDI与PTI中的I就是index,索引。

也就是说,pdi = 页目录表索引,pti = 页表索引。

一个线性地址可以分为10-10-12,三个部分,第一个10就是PDI,第二个10就是PTI,第三个12是物理页的页内偏移。

  • 2.访问某个线性地址的页目录表(PDE)的公式

0xC0300000 + PDI * 4

  • 3.访问某个线性地址的页表(PTE)的公式

0xC0000000 + PDI * 4096 + PTI *4

猜你喜欢

转载自blog.csdn.net/qq_18120361/article/details/115360272