我们知道android 的原生程序是运行于linux内核上的 ,并且处理器基于arm 那么我们想要学习安卓手游逆向就要学习arm汇编的基础知识
学习的前提是你已经掌握了一定的0x86汇编基础,在0x86汇编基础上对比学习即可,如果没有一定的端游逆向基础,可以回去看看我之前的端游逆向基础
arm汇编指令
1.ldr 和mov的区别 mov只能传递寄存器之间的值 例如 mov r0,r1 ldr 传递内存地址里的值到寄存器 例如 ldr r1,[r3] 例如 ldr r0,[r1,#4] 这在0x86里都是mov负责的工作,现在被分工了 ldr伪指令可以当mov一样使用 例如 ldr r0,=ffff 操作数前加一个等号 操作数大小在mov指令范围内的话会自动编译成mov指令
2.str 和 ldr str是传递寄存器里的值到内存地址中 例如 str r0,[r1] r0寄存器的值写入到r1所表示的内存地址里 这跟我们以往见到的汇编指令是相反的,第一个操作数是源操作数,第二个操作数是目标操作数,这里应该注意一下. 理解一str 是ldr反操作
对比 ldr r0,[r1] 和 str r0,[r1] 是相反的执行过程 理解二可以理解str为写内存 ldr 为读内存
这些在0x86里都是MOV 负责的工作,现在被分工了
3.stm和ldm 批量读写 后面往往会跟着ia ib da db等等条件 i表示 加4 d表示减4 a表示赋值后 b表示赋值前 都是对应的英文单词的缩写 例子: STMIA r0!,{r1,R3,R5} IA表示赋值后加4,也就是先存后增 产生的结果是: r1存至r0 R3存至r0+4 R5存至r0+8 r0最后指向的地址是r0(初)+0xC 因为是先存后增,所以寄存器组存数据也是递增的,从r1递增取至R5 成对使用的取数据操作是: LDMDB r0!,{r1,R3,R5} 这个时候r0指向的地址已经是r0(初)+0xC,先减后取,所以产生的结果是: r0+8取至R5 r0+4取至R3 r0取至r1 这两句命令相当于保存和还原的操作 类似PUSHAD POPAD的功能
4.跳转 B 无条件跳转指令 对应JMP mov pc ,xxxx 相当于B(PC 之前我们说了 相当于EIP) ldr pc,_xxxx往往都是异常处理 例如 ldr pc, _data_abort 数据异常 BEQ相等跳转指令 对应JE
BL保存PC到LR再跳转 相当于CALL 也就是 mov lr,pc 然后B mov pc,lr 可以返回 相当于retn BLX和BX 中的X表示跳转切换指令集 arm和thumb
5.状态寄存器
我们看到很多指令后面跟个S 例如 adds 带s 表示影响状态寄存器
6.立即数 前面要加#
7.SWP 后面跟B交换字节否则交换32位 SWP 指令举例如下 SWP R1,R1,[R0] 将R1 的内容与R0 指向的内存地址里的值交换 SWPB R1,R2,[R0] 将R0指向的内存地址里的值读取一字节数据到R1中(高 24位清零) 并将R2的内容写入到该内存单元中
实际上这个过程可以拆分成3句代码 来赋值,相当于C++里的变量交换 8.异或 E0R 对应 XOR lsl,lsr 左右移 例如 mov r0,r1,lsl #2 结果 r0=r1*4 9.Ball对应Call 省略成 BL Ball=B+All(条件)+保存LR 10.mvn 取反然后mov 例如 mvn r0,#0 结果 r0=ffffffff
汇编指令很多不是我们几天能够完全掌握的 可以在逆向的学习过程中慢慢吸收 这里面只是给大家列举比较常用的一些指令而已 |