0x00 前言
最近在看书补习基础知识,二进制漏洞方面的知识,大部分都是内存的破坏与利。故把自己看CSAPP虚拟内存章节学习的内容写博客记录下来,为了加强印象与分享。
0x01 结构
虽然i7底层的Haswell微体系结构允许完全的64位虚拟和物理地址空间,但现在i7实现支持48位(256TB)虚拟地址空间和52位(4PB)的物理地址空间,还有一个32位兼容模式。
TLB是虚拟寻址的,是四路组相联的。L1、L2、和L3高速缓存是物理寻址的,块大小为64字节。L1和L2是8路组相联的,而L3是16组相联的。页大小可以在启动时被配置为4KB或4MB,Linux使用的是4KB的页。
0x02 翻译过程
怎么翻译,一图以蔽之。
4KB的页,所以VPO=PPO=2^12^byte=4KB,剩下的36位作为VPN,且有4级页表,所以每级页表的VPN=9。TLB有2^4^=16个组,故TLBI=4,其余的32位作为TLBT。L1 d-cache有2^6^=64组,故CI=6,每个块大小为64字节,所以CO也为6,剩下的40位作为CT。
其中CR3控制寄存器指向第一级页表的起始位置,CR3的值是每个进程上下文的一部分,每次切换上下文时,CR3的值都会被恢复。
0x01 TLB命中
CPU把48位的虚拟地址发送给MMU,MMU直接把低12位作为PPO,利用VPN的低4位也就是TLBI确认PPN所在的组,然后再根据TLBT取出PPN与刚才的12位共52位作为PA。
0x02 TLB不命中
这时候,根据CR3(基址)和VPN1(偏移)找到L1 PTE(L2页表的基址),以此类推,第四纪页表存储的便是PPN。每个页表条目的具体作业及含义如下。
第一二三级页表条目格式如下,在Linux中总是P=1。
字段 | 描述 |
P | 子页表在物理内存中(1),不在(0) |
R/W | 对于所有可访问的页,只读或读写访问权限 |
U/S | 对于所有可访问的页,用户或超级用户(内核)访问模式权限 |
WT | 子页表的直写或写回策略 |
CD | 能/不能缓存子页表 |
A | 引用位(由MMU在读和写时设置,由软件清除) |
PS | 页大小为4KB或4MB(只对第一层PTE定义) |
ADDR | 子页表物理基址 |
XD | 能/不能从这个PTE可访问的所有页中取指令 |
第四级页表条目的格式
字段 | 描述 |
P | 子页表在物理内存中(1),不在(0) |
R/W | 对于子页,只读或读写访问权限 |
U/S | 对于子页,用户或超级用户(内核)访问模式权限 |
WT | 子页的直写或写回策略 |
CD | 能/不能缓存 |
A | 引用位(由MMU在读和写时设置,由软件清除) |
D | 修改位(由MMU在读和写时设置,由软件清除) |
G | 全局页(在任务切换时,不从TLB中驱逐出去) |
ADDR | 物理地址的最高40位(PPN) |
XD | 能不能从这个子页中取指令 |
XD(禁止执行)是在64位系统中引入的,可以用来禁止从某些内存取指令,使得操作系统内核降低了缓冲区溢出攻击的危险。
0x03 L1命中
在得到PA之后,就可以根据PA取相应地址上的数据,首先根据CI和CT找到数据位于L1 d-cache的哪一行,然后根据CO取数据,然后送回CPU中。当MMU翻译每一个虚拟地址时它还会更新另外两个两个内核缺页处理程序会用到的位。每次访问一个页时,MMU都会设置A位,称为引用位(reference bit)。内核可以用这个引用位来实现它的页替换算法。每次对一个页进行了写之后,MMU都会设置D位,又称为修改位或脏位(dirty bit),修改位告诉内核在复制替换页时必须写回牺牲页。内核可以通过调用一条特殊的内核模式指令来清除引用位或修改位。
0x04 加速翻译
上述只是描述了一个顺序的两个步骤,虚拟地址经过MMU变成物理地址,然后取L1取数据。但是实际情况下硬件实现使用了一个灵活的技巧,允许这些步骤部分重叠,加速访问。例如上述例子中,4KB的页有一个12位的VPO,PPO。L1是八路组相联,物理寻址的,有64个组和大小为64字节的缓存块。每个物理地址有log(2)64=6个缓存偏移和6个索引位,这12位恰好是VPO部分。当CPU翻译地址时,就把VPN发给MMU,VPO发给高速L1缓存。当MMU向TLB请求页表条目时,L1正利用VPO位查找相应的组,并读出组里的8个标记和相应的字,当MMU得到PPN(CT)时,缓存直接准备好试着把这个PPN与8个标记位中的一个进行匹配了。当然前提是L1命中。
0x04Others
这里知识简单描述了取某一地址数据的过程,实际上取指令类似,相关的结构为,L1 i-cache,i-TLB(上面使用的时d-TLB,而且忽略了一二级TLB),也没有描述L1不命中,取下一级取数据的过程,所以说是简化,但总的来说,这些过程都是大同小异。
0x03 扩展
我记得以前看到一篇文章,是阿里安全的一篇安卓内核读写的漏洞,从上面我们可以看出,页表条目里有很大与安全相关的标志位,通过一些漏洞改写权限位,然后利用文章的利用方法将页表地址改到内核空间,达到内核读写的能力。大概的利用思路如上。文末我会给出链接。
0x04 名词索引
VPO:虚拟页面偏移(字节)
VPN:虚拟页号
TLB:翻译后备缓冲器
TLBI:TLB索引
TLBT:TLB标记
PPO:物理页面偏移量(字节)
PPN:物理页号
CO:缓冲块内的额字节偏移量
CI:高速缓存索引
CT:高速缓存标记
MMU:内存管理单元
0x05 参考
1.CSAPP
2.内核空间镜像攻击揭秘:ARM 硬件特性,竟能开启安卓8终端的上帝模式?
PS:有时间再把其他部分写一写