Android 图解逆向工程中ARM常用汇编指令(一)

我们走得太快,灵魂都跟不上了。

微小的幸福就在身边,容易满足就是天堂。


在逆向和爆破中我们经常会在IDA中接触到汇编,一般做安卓的不会太了解VB回编等,不太了解的同学可以先查看上篇文章《Android ARM常用的汇编指令合集》 再来继续我们的学习,我们先来看张图。

这个view里面有 PUSH/LDR/SUB/MOVS/BLX/SUBS/BEQ/CMP ,这些差不多都是常见的,不过也不需要看得懂,理解这个指令即可,接下来我们就来分析下这些指令分别有什么作用吧。

先引入 概念性 东西,免得大家后面被搞混,那就是为什么会有S和!

  • S:指令执行后程序状态寄存器的条件标志位将被刷新 , 如ADDS R1,R0,#2
  • ! :指令中的地址表达式中含有!后缀时,指令执行后,基址寄存器中的地址值将发生变化,变化的结果是:基址寄存器中的值(指令执行后)=指令执行前的值 + 地址偏移量,如 LDR R3,[R0,#2]! 指令执行后,R0 = R0 + 2

接下来分别讲解这个View里面的指令分别有什么作用。

PUSH,顾名思义,直接PUSH进栈了。相反的,POP则为出栈了。

?指令示例:

  • PUSH{cond} reglist PUSH将寄存器推入满递减堆栈
  • PUSH {r0,r4-r7} 将R0,R4-R7寄存器内容压入堆栈
  • POP{cond} reglist POP从满递减堆栈中弹出数据到寄存器
  • POP {r0,r4-r7} 将R0,R4-R7寄存器从堆栈中弹出

LDR,指令语法:LDR{条件} 目的寄存器,<存储器地址>,LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理,当程序计数器PC作为 目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计 中比较常用,且寻址方式灵活多样。

??详情可见上篇文章中 Ctrl + F 搜索《Android ARM常用的汇编指令合集》:加载/存储指令

?指令示例:

  • LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。
  • LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。

MOVS 、LDR 这些是跳转指令,直接向程序计数器PC写入跳转地址值,通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,那有人会问,如果说从当前指令向前或向后的32MB的地址空间的跳转是怎么个实现原理?其实在 上篇文章中提及到了,它们是B\BL\BLX\BX 四大指令,这个我们最后才来讲解,其实它们有点像我们常说的分支结构,我们从图片里面选第四条指令作为查看数据。

则可以看到,R5是原地址,其实为0xFF8->0x104A,复制返回地址到PC,实现子的返回,做安卓的同学可能会有个疑问,为什么有个S,因为语法就是 MOV{条件}{S} 目的寄存器+源操作数

看到这里大家可能会头晕,怎么感觉都是看不懂的数字,那其它那些,如ADD、等就给大家整理了一份表格。

助记符 指令功能描述 助记符 指令功能描述
ADD 加法指令 MRS 传送CPSR或SPSR的内容到通用寄存器指令
ADC 带进位加法指令 MRC 从协处理器寄存器到ARM寄存器的数据传输指令
AND 逻辑与指令 MSR 传送通用寄存器到CPSR或SPSR的指令
B 分支指令 MUL 32位乘法指令
BL 带返回的分支指令 BIC 位清零指令
BLX 带返回和状态切换的分支指令 MLA 32位乘加指令
BX 带状态切换的分支指令 MVN 数据取反传送指令
TST 位测试指令 ORR 逻辑或指令
CDP 协处理器数据操作指令 RSC 带错位的逆向减法指令
RSB 逆向减法指令 SBC 带错位减法指令
CMN 比较反值指令 CMP 比较指令
STC 协处理器寄存器写入存储器指令 EOR 异或指令
STM 批量内存字写入指令 LDC 存储器到协处理器的数据传输指令
STR 寄存器到存储器的数据存储指令 LDM 加载多个寄存器指令
SUB 减法指令 LDR 存储器到寄存器的数据加载指令
SWI 软件中断指令 MCR 从ARM寄存器到协处理器寄存器的数据传输指令
TEQ 相等测试指令 MOV 数据传送指令

SUBS 从表中可以看到,SUB是减法指令,如SUB R0,R1,R2则对应了R0 = R1 - R2,SUB R0,R1,#1 则是R0 = R1 -1,要注意的是 SUBS 是低32位相减。

BEQ 呢?!不要着急,来看下图

BEQ 指令是跳转指令,但是跳转要满足一定的条件,满足则跳转执行,看下图红框部分。

那就只剩下 CMP 了,CMP是比较指令,指令格式:CMP{条件} 操作数1,操作数2

?指令示例:

  • 如 CMP R1,#10,则等于比较R1和10,并设置CPSR的标志位。
  • CMP R1,R0 ;将寄存器R1的值与寄存器R0的值相减,并根据 结果设置CPSR的标志位
  • CMP R1,#100 ;将寄存器R1的值与立即数100相减,并根 据结果设置CPSR的标志位
  • 如果和BEQ一起使用话则是:CMP R1,#0 换行 BEQ Label ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行

OK , 从第一张图中我们看到后面跟的是两位,那如果是复杂一点的两位以上怎么看

?指令示例:

  • 先来看MOV的,如MOV R0,R1 , LSL R3 ,这个又是何解?其实它是将R1的值左移R3位,然后将结果存放到R0中 。
  • 再来看LDR的,LDR R0,[R1],R2 ,这个何解? 它是将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1 , 要记住,R1是最终落地的地址 。

上篇文章中提及了其它更复杂的指令示例,不太明白这些可以看上篇文章的《Android ARM常用的汇编指令合集》,然后Ctrl + F 搜:数据加载/存储指令 或者搜索 数据处理指令,又或者搜索 自己需要的指令

|| 版权声明:本文为博主杜锦阳原创文章,转载请注明出处。http://blog.csdn.net/DJY1992/article/details/71404947

时间: 2024-10-13 11:45:57

Android 图解逆向工程中ARM常用汇编指令(一)的相关文章

ARM 常用汇编指令

ARM 汇编程序的框架结构 .section .data <初始化的数据> .section.bss <未初始化的数据> .section .text .global _start _start: <汇编代码> 注意: 一般是将上面结构进行简化 .text .global  _start _start: <汇编代码> 寄存器操作指令: 算术和逻辑指令: MOV :用于将一个寄存器或被移位寄存器或一个立即数移动到目的寄存器 MOV  r1 ,#8 (注意:#+

ARM常用汇编指令介绍

b     跳转指令(跳转范围为32Mb) bl    带返回地址的跳转,指令自动将下一条指令的地址复制到R14寄存器,然后跳转到指定地址去执行,执行完后返回到下一条指令处执行 pc    寄存器R15,程序计数器指向当前执行的程序地址 lr    寄存器R14,链接寄存器保存程序跳转时的返回地址 ldr   从内存中读取数据加载到寄存器中 str   将寄存器中的数据保存到内存 mov   寄存器与寄存器之间的数据传送指令,也可以将立即数传给目标寄存器 add   加法指令 sub   减法指

ARM重要汇编指令记录

IMPORT ,定义表示这是一个外部变量的标号,不是在本程序定义的EXPORT ,表示本程序里面用到的变量提供给其他模块调用的.以上两个在汇编和C语言混合编程的时候用到 ENDP    表示PROC所定义的过程结束. (end procedure)ENDS    表示SEGMENT定义的段结束.   (end segment)END     程序结束. B.BL.BX.BLX 和 BXJ跳转.带链接跳转.跳转并切换指令集.带链接跳转并切换指令集.跳转并转换到 Jazelle 状态. 状态寄存器传

常用汇编指令集合

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 常用汇编指令集合 1. gdtr 1.gdtr 读取gdt表地址 其需要六个字节,但是前两个字节并没有用处. 汇编代码: CHAR Sgdtr[6] = { NULL };    __asm {        sgdt Sgdtr;    }   查看内存地址:ff 03 00 f0 03 80   后四个字节值为 8003f000,可以用windbg r gdt

汇编--常用汇编指令与标志位关系

加法指令 ADD (addition) 指令对标志位的影响: CF=1   最高有效位向高位有进位 CF=0   最高有效位向高位无进位 OF=1   两个同符号数相加(正数+正数 或 负数+负数),结果符号与其相反. OF=0   两个不同符号数相加,或同符号数相加,结果符号与其相同. 带进位加法指令 ADC (add with carry) 指令对标志位的影响: CF=1   最高有效位向高位有进位 CF=0   最低有效位相高位无进位 OF=1   两个同符号数相加,结果符号与其相反, O

汇编笔记二【32位通用寄存器 以及 常用汇编指令】

一.32位通用寄存器(EAX,ECX,EDX,EBP,ESP,EBP,ESI,EDI) 二.十六位通用寄存器(AX,CX,DX,BX,SP,BP,SI,DI) 三.八位通用寄存器(AH,AL,CH,CL,DH,DL,BH,BL) 四.32位,16位,8位寄存器之间的关系 1.寄存器都是高位在前,低位在后. 2.都是包含关系,32位寄存器之中包含了16位寄存器,16位寄存器之中包含了8位寄存器. 关系如下: 五.32位的含义 一位只能放0或1,32位就意味着能放32个0或1. 所以32位最小取值为

ARM 内核 汇编指令 的 8种 寻址方式

str: store register ->指令将寄存器内容存到内存空间中, ldr:  load register 将内存内容加载到通用寄存器, ldr/str 组合来实现ARM CPU 和内存数据的 交换! 1.mov r1,r2;  //寄存器r2的内容复制到r1中,寄存器寻址方式,(r1,r2 ARM中的通用寄存器) 2.mov r0,#0xFF00; //数0xFF00复制到r0中,立即寻址方式,(#代表后面跟一个数) 3.mov r0,r1,lsl #3; //将r1中的内容左移三位

常用汇编指令及其影响的标志位

加法指令 ADD (addition) 指令对标志位的影响: CF=1   最高有效位向高位有进位 CF=0   最高有效位向高位无进位 OF=1   两个同符号数相加(正数+正数 或 负数+负数),结果符号与其相反. OF=0   两个不同符号数相加,或同符号数相加,结果符号与其相同. 带进位加法指令 ADC (add with carry) 指令对标志位的影响: CF=1   最高有效位向高位有进位 CF=0   最低有效位相高位无进位 OF=1   两个同符号数相加,结果符号与其相反, O

常用汇编指令

CMP A,B 比较A与B其中A与B可以是寄存器或内存地址,也可同时是两个寄存器,但不能同都是内存地址.这个指令太长见了,许多明码比较的软件,就用这个指令. MOV A,B 把B的值送给A其中,A与B可是寄存器或内存地址,也可同时是两个寄存器,但不能同都是内存地址. Xor a,a异或操作,主要是用来将a清空 LEA装入地址,例如LEA DX,string 将字符的地址装入DX寄存器 PUSH 压栈 POP 出栈 ADD 加法指令 格式:ADD DST,SRC 执行的操作:(DST)<-(SRC