因此,为了在启用加密和保护的情况下执行,您需要访问
0x00000 1 00'xxxxxxxx 形式的地址。
这时硬件模块才开启保护机制。因此,在硬件级别,会自动添加所需的位,也就是这个“1”
(一个特殊寄存器 “HRMOR” - 虚拟机管理程序实模式偏移寄存器,负责此操作)!
再次强调,一旦虚拟机管理程序访问像
0x00000 0 00'xxxxxxx 这样的地址,
MMU 就会自动将该地址更改为 0x00000 1 00'xxxxxxx,包括加密和保护,且无法跳过这一加密过程!因此,任何在没有保护和加密的情况下“直接”从物理内存执行代码的尝试都注定会失败......或者不一定?
我们来看看虚拟机管理程序版本 4532 的易受攻击的代码:
//в %r0 – 获取系统调用号
13D8: cmplwi %r0, 0x61 –//与最大有效ID(0x61)的值进行比较
13DC: bge illegal_syscall –//如果传输的数字值大于0x61,我们就说它不正确(非法)
...
13F0: rldicr %r1, %r0, 2, 61 –//将系统调用号乘以4
13F4: lwz %r4, syscall_table(%r1) –//从syscall固定调用表中获取处理程序地址
13F8: mtlr %r4 –//将处理程序地址放入 lr 寄存器中
...
1414: blrl —//跳转到这个地址
你发现漏洞了吗?他就是!cmplwi 指令适用于32 位值,但 rldicr 指令适用于64 位值!也就是说,我们可以提交值0x20000 0 00'0000002A作为系统调用号,它会通过检查(因为低于32位部分0x20小于0x61),因此,处理程序地址不是地址0x00000 0 00'0x10EC,而是将从
0x80000 0 00'000010EC 获取!
然后,正如他们所说,小心你的手。地址的最高有效位不为零,因此不添加HRMOR !并且由于真实地址空间是32位,所以我们设置的63位被简单地忽略。我们只需提供不正确的系统调用号即可将虚拟机管理程序重定向到未加密且未受保护的内存!
