异构pwn学习记录
MIPS
Mips寄存器
MIPS32寄存器分为两类:通用寄存器(GPR)和特殊寄存器。 通用寄存器:MIPS体系结构中有32个通用寄存器,汇编程序中用$0~$31表示。也可以用名称表示,如$sp、$t1、$ra等。
编号 | 寄存器名称 | 描述 |
---|---|---|
$0 | $zero | 第0号寄存器,其值始终为0。 |
$1 | $at | 保留寄存器 |
$2-$3 | $v0-$v1 | values,保存表达式或函数返回结果 |
$4-$7 | $a0-$a3 | argument,作为函数的前四个参数 |
$8-$15 | $t0-$t7 | temporaries,供汇编程序使用的临时寄存器 |
$16-$23 | $s0-$s7 | saved values,子函数使用时需先保存原寄存器的值 |
$24-$25 | $t8-$t9 | temporaries,供汇编程序使用的临时寄存器,补充$t0-$t7。 |
$26-$27 | $k0-$k1 | 保留,中断处理函数使用 |
$28 | $gp | global pointer,全局指针 |
$29 | $sp | stack pointer,堆栈指针,指向堆栈的栈顶 |
$30 | $fp | frame pointer,保存栈指针 |
$31 | $ra | return address,返回地址 |
特殊寄存器:有3个特殊寄存器:PC(程序计数器)、HI(乘除结果高位寄存器)和LO(乘除结果低位寄存器)。在乘法时,HI保存高32位,LO保存低32位。除法时HI保存余数,LO保存商。
MIPS常用指令集
lb/lh/lw: 从存储器中读取一个byte/half word/word的数据到寄存器中.如lb $1, 0($2) ($1=$2+0)
li:立即数的值给寄存器 li $1,0x1
move:将寄存器里的值赋值给寄存器
la:将地址传递给寄存器
lui:把一个16位的立即数填入到寄存器的高16位,低16位补零。
sb/sh/sw: 把一个byte/half word/word的数据从寄存器存储到存储器中.如 sb $1, 0($2) ($2+0=$1)
add/addu:把两个定点寄存器的内容相加add $1,$2,$3($1=$2+$3);u为不带符号加。
addi/addiu:把一个寄存器的内容加上一个立即数add $1,$2,#3($1=$2+3);u为不带符号加。
sub/subu:把两个定点寄存器的内容相减。
div/divu:两个定点寄存器的内容相除。
mul/mulu:两个定点寄存器的内容相乘。
**and/andi:**与运算,两个寄存器中的内容相与and $1,$2,$3($1=$2 & $3);i为立即数。
or/ori:或运算。
xor/xori:异或运算。
beq/beqz/benz/bne:条件转移eq相等,z零,ne不等。
bal:跳转指令
j/jr/jal/jalr:j直接跳转;jr使用寄存器跳转;
sll/srl:逻辑左移/右移sll $1,$2,#2。
slt/slti/sltui:如果$2的值小于$3,那么设置$1的值为1,否则设置$1的值为0。slt $1,$2,$3。
mov/movz/movn:复制,n为负,z为零。mov $1,$2; movz $1,$2,$3($3为零则复制$2到$1)。
trap:根据地址向量转入管态。
eret:从异常中返回到用户态。
Mips函数调用过程
mips架构和x86架构中,栈的增长方向相同,都是从高地址向低地址增长,但是没有栈底指针,所以调用一个函数是,需要将当前栈向低地址处移动n比特这个大小为n比特的空间就是此函数的栈桢存储区域;
mips架构中有叶子函数和非叶子函数的区别,叶子函数就是此函数自身不再调用别的函数,非叶子函数就是此函数自身调用别的函数。如果函数A调用函数B,调用者函数会在自己的栈顶预留一部分空间来保存被调用者(函数B)的参数,称之为参数调用空间;
函数调用过程中,父函数调用子函数,复制当前$PC的值到$RA寄存器,然后跳转到子函数执行。到子函数是,子函数如果为非叶子函数,则在函数入口子函数的返回地址会先存入堆栈。
参数传递方式,前四个参数通过$a0-$a3来传递,多于的参数会放入调用参数空间(参数会被保存在栈上),可以类比x86_64参数传递规则来进行记忆。
1 | #进入函数 |
Arm
Arm寄存器
ARM | Description | x86 |
---|---|---|
R0 | General Purpose(可被用作累加器、第一个参数) | EAX |
R1-R5 | General Purpose(第2、3、4个参数) | EBX,ECX,EDX,ESI,EDI |
R6-R10 | General Purpose(R7存储系统调用号) | - |
R11(FP) | Frame Pointer | EBP |
R12 | Intra Procedural Call | - |
R13(SP) | Stack Pointer | ESP |
R14(LR) | Link Register | - |
R15(PC) | <Program Counter/Instruction Pointer> | EIP |
Arm常用指令集
指令 | 描述 | 指令 | 描述 |
---|---|---|---|
MOV | 移动数据 | EOR | 按位异或 |
MVN | 移动并取反 | LDR | 加载 |
ADD | 加 | STR | 存储 |
SUB | 减 | LDM | 加载多个 |
MUL | 乘 | STM | 存储多个 |
LSL | 逻辑左移 | PUSH | 入栈 |
LSR | 逻辑右移 | POP | 出栈 |
ASR | 算数右移 | B | 跳转 |
ROR | 右旋 | BL | link跳转 |
CMP | 比较 | BX | 分支跳转 |
AND | 按位与 | BLX | link分支跳转 |
ORR | 按位或 | SWI/SVC | 系统调用 |
CMP R0, R1 ; R0与R1比较,做R0-R1的操作
ADDHI R0, R0, #1 ;若R0 > R1, 则R0 = R0 + 1
ADDLS R1, R1, #1 ; 若R0 <= R1, 则R1 = R1 + 1
Aarch64(Arm64)
Aarch64(Arm64)寄存器
ARM64 | Descript |
---|---|
X0~X7 | 传递参数,返回值用X0表示 |
X8 | 程序返回地址 |
X9~X15 | 临时寄存器,使用时不需要保存 |
X16~X17 | 子程序内部调用寄存器 |
X18 | 平台寄存器 |
X19~X28 | 临时寄存器,使用时必须保存 |
X29 | 帧指针寄存器,使用时需要保存() |
X30 | 链接寄存器LR,保存跳转返回信息地址 |
X31 | 堆栈指针寄存器SP或零寄存器 (esp) |
XZR | 64bit Zero寄存器,读出的数据全为0 |
WZR | 32bit Zero寄存器的32bit形式 |
子程序调用时必须要保存的寄存器:X19~X29和SP(X31)
不需要保存的寄存器:X0X7,X9X15
只用低 32bit的w0-w30
Arm64常用指令集
- MOV x1,x0; 将寄存器x0的值传送到寄存器x1
- ADD x0,x1,x2; 寄存器x1和x2的值相加后传送到x0
- SUB x0,x1,x2; 寄存器x1和x2的值相减后传送到x0
- AND x0,x0,#0xF; x0的值与0xF相位与后的值传送到x0
- ORR x0,x0,#9; x0的值与9相位或后的值传送到x0
- EOR x0,x0,#0xF; x0的值与0xF相异或后的值传送到x0
- LDR x5,[x6,#0x8]; x6寄存器加0x8地址的内容传送到x5
- STR x0, [SP, #0x8]; x0寄存器的数据传送到SP+0x8地址值指向的存储空间
- STR x0, [x1], #8 将x0中的字数据写入以x1为地址的存储器中,并将新地址x1+8写入x1
- STP x29, x30, [sp, #0x10]; 入栈指令
- LDP x29, x30, [sp, #0x10]; 出栈指令,将sp-0x10 前8bytes给x29,后8bytes给x30
- CBZ x19, 0x10; 比较,如果结果为零(Zero)就转移(只能跳到后面的指令)
- CBNZ x19, 0x10; 比较,如果x19非零(Non Zero)就转移PC+0x10(只能跳到后面的指令)
- B/BL ; 绝对跳转#imm,返回地址保存到LR(x30)
- B.NE
- b ffff000008283b80
- bl ffff000008dc566c
MOV 指令只能用于寄存器之间传值,寄存器和内存之间传值通过 LDR 和 STR.
example:
1 | 000000000003a150 <example_test>: |
Aarch64函数调用过程
1 | #进入函数 |
PowerPC
PowerPC寄存器
r0 在函数開始(function prologs)时使用。
r1 堆栈指针,相当于ia32架构中的esp寄存器,idapro把这个寄存器反汇编标识为sp。
r2 内容表(toc)指针,idapro把这个寄存器反汇编标识为rtoc。系统调用时。它包括系统调用号(这个好像跟系统有关吧)。
r3 作为第一个參数和返回值。
r4-r10 函数或系统调用開始的參数。
r11 用在指针的调用和当作一些语言的环境指针。
r12 它用在异常处理和glink(动态连接器)代码。
r13 保留作为系统线程ID。
r14-r31 作为本地变量。非易失性。
lr 链接寄存器,它用来存放函数调用结束处的返回地址。
ctr 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。
xer 定点异常寄存器。存放整数运算操作的进位以及溢出信息。
msr 机器状态寄存器,用来配置微处理器的设定。
cr 条件寄存器。它分成8个4位字段,cr0-cr7。它反映了某个算法操作的结果而且提供条件分支的机制。
PowerPC指令
名称 | 助记符 | 语法格式 |
---|---|---|
字节存储(偏移地址寻址) | stb | rS, d(rA) |
字节存储(寄存器寻址) | stbx | rS, rA, rB |
记录有效地址的字节存储(偏移地址寻址) | stbu | rS, d(rA) |
记录有效地址的字节存储(寄存器寻址) | stbux | rS, rA, rB |
半字存储(偏移地址寻址) | sth | rS, d(rA) |
半字存储(寄存器寻址) | sthx | rS, rA, rB |
记录有效地址的半字存储(偏移地址寻址) | sthu | rS, d(rA) |
记录有效地址的半字存储(寄存器寻址) | sthux | rS, rA, rB |
字存储(偏移地址寻址) | stw | rS, d(rA) |
字存储(寄存器寻址) | stwx | rS, rA, rB |
记录有效地址的字存储(偏移地址寻址) | stwu | rS, d(rA) |
记录有效地址的字存储(寄存器寻址) | stwux | rS, rA, rB |
名称 | 助记符 | 语法格式 |
---|---|---|
高位清零载入字节指令(偏移地址寻址) | lbz | rD, d(rA) |
高位清零的载入字节指令(寄存器寻址) | lbzx | rD, rA, rB |
高位清零的载入字节并记录有效地址指令(偏移地址寻址) | lbzu | rD, d(rA) |
高位清零的载入字节并记录有效地址指令(寄存器寻址) | lbzux | rD, rA, rB |
高位清零的载入半字指令(偏移地址寻址) | lhz | rD, d(rA) |
高位清零的载入半字指令(寄存器寻址) | lhzx | rD, rA, rB |
高位清零的载入半字并记录有效地址指令(偏移地址寻址) | lhzu | rD, d(rA) |
高位清零的载入半字并记录有效地址指令(寄存器寻址) | lhzux | rD, rA, rB |
载入半字指令(偏移地址寻址) | lha | rD, d(rA) |
载入半字指令(寄存器寻址) | lhax | rD, rA, rB |
载入半字并记录有效地址指令(偏移地址寻址) | lhau | rD, d(rA) |
载入半字并记录有效地址指令(寄存器寻址) | lhaux | rD, rA, rB |
载入字指令(偏移地址寻址) | lwz | rD, d(rA) |
载入字指令(寄存器寻址) | lwzx | rD, rA, rB |
载入字并记录有效地址指令(偏移地址寻址) | lwzu | rD, d(rA) |
载入字并记录有效地址指令(寄存器寻址) | lwzux | rD, rA, rB |
名称 | 助记符 | 语法格式 |
---|---|---|
多字载入 | lmw | rD,d(rA) |
多字存储 | stmw | rS,d(rA) |
名称 | 助记符 | 语法格式 |
---|---|---|
无条件转移 | b( ba bl bla) | target_addr |
条件转移 | bc( bca bcl bcla) | BO,BI,target_addr |
条件转移(转移目标地址由LR指出) | bclr(bclrl) | BO,BI |
条件转移(转移目标地址由CTR指出) | bcctr(bcctrl) | BO,BI |
名称 | 助记符 | 语法格式 |
---|---|---|
读取机器状态寄存器 | mfmsr | rD |
写入机器状态寄存器 | mtmsr | rS |
读取特殊功能寄存器 | mfspr | rD, SPR |
写入特殊功能寄存器 | mtspr | SPR, rS |
读取段寄存器 | mfsr | rD, SR |
写入段寄存器 | mtsr | SR, rS |
间接读取段寄存器 | mfsrin | rD, rB |
间接写入段寄存器 | mtsrin | rS, rB |
读取时基寄存器 | mftb | rD, TBR |
例题
异构pwn的栈题与x86架构的题差别挺大,主要是理解其函数调用的过程以及寄存器的作用。例题都是两个月前做的,现在也忘的差不多了,准备这里是放2022的hws的题,结果他没有出异构题,等到下次遇见好的题再放吧。