Windows保护模式学习笔记(八)—— 页目录表基址/页表基址
前言
一、学习自
滴水编程达人
中级班课程,官网:https://bcdaren.com
二、海东老师牛逼!
要点回顾
在上一节课课后题中我们提到过,如果系统要保证某个线性地址是有效的,那么必须为其填充正确的PDE与PTE
如果我们想填充PDE与PTE,那么必须能够访问PDT与PTT,这样就存在2个问题:
- 一定已经有“人”为我们访问PDT与PTT挂好了PDE与PTE,我们只用找到这个线性地址就可以了
- 这个为我们挂好PDE与PTE的“人”是谁?
注意:
CR3中存储的是物理地址,不能在程序中直接读取的。如果想读取,也要把Cr3的值挂到PDT和PTT中才能访问,那么怎么通过线性地址访问PDT和PTT呢?
注意:以下所有实验的分页方式均为10-10-12分页
一、页目录表基址
页目录表基址 = 线性地址:C0300000
实验:拆分线性地址C0300000,并查看其对应的物理页
第一步:打开一个进程,获得它的Cr3
我这里打开的是notepad.exe
第二步:查看进程的PDT表
注意PDT表中的数据
第三步:拆分线性地址
十六进制:
C0300000
=
二进制:
1100 0000 00
1100 0000 00
0000 0000 0000
=
十六进制:
300
300
000
第四步:查看线性地址对应的物理页
注意:若不知道怎么查找物理页可以翻看前两篇笔记
可以发现 物理页的内容 与 PDT表的内容 完全相同
实验总结
- 线性地址C0300000对应的物理页就是页目录表
- 这个物理页即页目录表本身也是页表
- 这个物理页是一张特殊的页表,每一项PTE指向的不是普通的物理页,而是指向其它的页表
- 访问页目录表的公式:
C0300000 + PDI*4
(I=index)
结构图如下:
二、页表基址
页表基址 = 线性地址:C0000000
实验:拆分线性地址C0000000,并查看其对应的物理页
第一步:打开一个进程,获得它的Cr3
我这里打开的是notepad.exe
第二步:查看进程的PDT表
查看前三个PDE所对应的PTT表
第一张PTT表:
第二张PTT表:
第三张PTT表:
第三步:拆分线性地址
十六进制:
C0300000
=
二进制:
1100 0000 00
0000 0000 00
0000 0000 0000
=
十六进制:
300
000
000
第四步:查看线性地址指向的PDE所对应的PTT表
查看前三个PTE所对应的物理页
第一张物理页:
第二张物理页:
第三张物理页:
可以发现 每一项PTE所指向的物理页的内容 与 每一个PDE所指向的PTT表的内容完全相同
第五步:查看线性地址C0001000对应的PTT表
发现线性地址C0001000指向的PTT表的第一项PTE为线性地址C0000000指向的PTT表的第二项PTE
实验总结
- 页表被映射到了从
0xC0000000~0xC03FFFFF
的4M地址空间 - 在这1024个表中有一张特殊的表:页目录表
- 页目录被映射到了0xC0300000开始处的4K地址空间
- 访问页表的公式:
0xC0000000 + PDI*4096 + PTI*4
(I=index)
结构图如下:
总结
- 有了0xC0300000和0xC0000000能做什么:
掌握了这两个地址,就掌握了一个进程所有的物理内存读写权限 - 公式总结:
访问页目录表的公式:C0300000 + PDI*4
(I=index)
访问页表的公式:0xC0000000 + PDI*4096 + PTI*4
(I=index)