PowerPC
之前接触的pwn题一般都是x86架构,少数arm和mips,前段时间一场国外的比赛出现了一道PowerPC的题目,对于PowerPC架构的题目还是第一次遇到,借此机会整理一下相关的资料。
PowerPC)英语:Performance Optimization With Enhanced RISC – Performance Computing,有时简称PPC)是一种精简指令集)RISC)架构的中央处理器)CPU),其基本的设计源自IBM的POWER)Performance Optimized With Enhanced RISC;《IBM Connect电子报》2007年8月号译为“增强RISC性能优化”)架构。POWER是1991年,Apple、IBM、Motorola组成的AIM联盟所发展出的微处理器架构。PowerPC是整个AIM联盟平台的一部分,并且是到目前为止唯一的一部分。但苹果电脑自2005年起,将旗下电脑产品转用Intel CPU。
指令集
寄存器
PPC使用RISC精简指令集,指令字长都是32bit,4字节对齐。PPC和IA32 CPU的不同点在于其定义了大量的通用寄存器,这个和ARM和X64有点类似。
序号 | 寄存器 | 功能 |
---|---|---|
1 | GPR0-GPR31(共32个寄存器) | 整数运算和寻址通用寄存器.在ABI规范中,GPR1用于堆栈指针,GPR3-GPR4用于函数返回值,GPR3-GPR10用于参数传递 |
2 | FPR0-FPR31(共32个寄存器) | 用于浮点运算。PPC32和PPC64的浮点数都是64位 |
3 | LR | 连接寄存器,记录转跳地址,常用于记录子程序返回的地址。 |
4 | CR | 条件寄存器。 |
5 | XER | 特殊寄存器,记录溢出和进位标志,作为CR的补充 |
6 | CTR | 计数器,用途相当于ECX |
7 | FPSCR | 浮点状态寄存器,用于浮点运算类型的异常记录等,可设置浮点异常捕获掩码 |
PowerPC ABI 中的寄存器被划分成 3 种基本类型:专用寄存器、易失性寄存器和非易失性寄存器。
专用寄存器 是那些有预定义的永久功能的寄存器,例如堆栈指针(r1)和 TOC 指针(r2)。r3 到 r12 是易失性寄存器,这意味着任何函数都可以自由地对这些寄存器进行修改,而不用恢复这些寄存器之前的值。而r13及其之上的寄存器都是非易失性寄存器。这意味着函数可以使用这些寄存器,前提是从函数返回之前这些寄存器的值已被恢复。因此,在函数中使用非易失性寄存器之前,它的值必须保存到该函数的堆栈帧中,然后在函数返回之前恢复。
CR寄存器用于反映运算结果、跳转判断条件等,分为以下8组。
CR0 | CR1 | CR2 | CR3 | CR4 | CR5 | CR6 | CR7 |
---|---|---|---|---|---|---|---|
0-3 | 4-7 | 8-11 | 12-15 | 16-19 | 20-23 | 24-27 | 28-31 |
每组4位,分别为LT(小于)、GT(大于)、EQ(等于)、S0(Summary ovweflow)。CR0默认反映整数运算结果,CR1默认反浮点数运算结果。S0是XER寄存器S0位的拷贝。对于比较指令,很容易理解LT、GT、EQ的含义,对于算数运算指令,结果为负数则为LT,正数为GT,0为EQ。
PowerPC 体系结构本身支持字节(8 位)、半字(16 位)、字(32 位) 和双字(64 位) 数据类型,为方便起见,和IA32做个对比。见下表:
PPC | 字长(BITS) | 简称 | IA32 |
---|---|---|---|
BYTE | 8 | B | BYTE |
HALF WORD | 16 | H | WORD |
WORD | 32 | W | DWORD |
DWORD | 64 | D | QWORD |
通用寄存器
寄存器 | 说明 |
---|---|
r0 | 在函数开始(function prologs)时使用。 |
r1 | 堆栈指针,相当于IA32中的esp寄存器,IDA把这个寄存器反汇编标识为sp。 |
r2 | 内容表(toc)指针,IDA把这个寄存器反汇编标识为rtoc。系统调用时,它包含系统调用号。 |
r3 | 作为第一个参数和返回值。 |
r4-r10 | 函数或系统调用开始的参数,部分情况下r4寄存器也会作为返回值使用。 |
r11 | 用在指针的调用和当作一些语言的环境指针。 |
r12 | 它用在异常处理和glink(动态连接器)代码。 |
r13 | 保留作为系统线程ID。 |
r14-r31 | 作为本地变量,非易失性。 |
专用寄存器
寄存器 | 说明 |
---|---|
lr | 链接寄存器,它用来存放函数调用结束处的返回地址。。 |
ctr | 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。 |
xer | 定点异常寄存器,存放整数运算操作的进位以及溢出信息。 |
msr | 机器状态寄存器,用来配置微处理器的设定。 |
cr | 条件寄存器,它分成8个4位字段,cr0-cr7,它反映了某个算法操作的结果并且提供条件分支的机制。 |
寄存器r1、r14-r31是非易失性的,这意味着它们的值在函数调用过程保持不变。寄存器r2也算非易失性,但是只有在调用函数在调用后必须恢复它的值时才被处理。
寄存器r0、r3-r12和特殊寄存器lr、ctr、xer、fpscr是易失性的,它们的值在函数调用过程中会发生变化。此外寄存器r0、r2、r11和r12可能会被交叉模块调用改变,所以函数在调用的时候不能采用它们的值。
条件代码寄存器字段cr0、cr1、cr5、cr6和cr7是易失性的。cr2、cr3和cr4是非易失性的,函数如果要改变它们必须保存并恢复这些字段。
异常处理器
整数异常寄存器XER是一个特殊功能寄存器,它包括一些对增加计算精度有用的信息和出错信息。XER的格式如下:
寄存器 | 说明 |
---|---|
SO 总体溢出标志 | 一旦有溢出位OV置位,SO就会置位。 |
OV 溢出标志 | 当发生溢出时置位,否则清零;在作乘法或除法运算时,如果结果超过寄存器的表达范围,则溢出置位。 |
CA 进位标志 | 当最高位产生进位时,置位,否则清零;扩展精度指令(后述)可以用CA作为操作符参与运算。 |
常用指令
li REG, VALUE
加载寄存器 REG,数字为 VALUE
add REGA, REGB, REGC
将 REGB 与 REGC 相加,并将结果存储在 REGA 中
addi REGA, REGB, VALUE
将数字 VALUE 与 REGB 相加,并将结果存储在 REGA 中
mr REGA, REGB
将 REGB 中的值复制到 REGA 中
or REGA, REGB, REGC
对 REGB 和 REGC 执行逻辑 “或” 运算,并将结果存储在 REGA 中
ori REGA, REGB, VALUE
对 REGB 和 VALUE 执行逻辑 “或” 运算,并将结果存储在 REGA 中
and, andi, xor, xori, nand, nand, and nor
其他所有此类逻辑运算都遵循与 “or” 或 “ori” 相同的模式
ld REGA, 0(REGB)
使用 REGB 的内容作为要载入 REGA 的值的内存地址
lbz, lhz, and lwz
它们均采用相同的格式,但分别操作字节、半字和字(“z” 表示它们还会清除该寄存器中的其他内容)
b ADDRESS
跳转(或转移)到地址 ADDRESS 处的指令
bl ADDRESS
对地址 ADDRESS 的子例程调用
cmpd REGA, REGB
比较 REGA 和 REGB 的内容,并恰当地设置状态寄存器的各位