0x6.so逆向深化及IDA静态分析-1

so逆向深化及IDA静态分析-1 :  反汇编之ARM指令介绍


本文介绍部分常用ARM指令,偏理论介绍,初学者仅做了解,后续会有实战分析,先上框架图:

基础篇中曾给大家提供ARM指令集,方便查阅,未下载的请从本文附件下载。
接下来介绍四类常用的指令,分别是 跳转指令数据处理指令加载/存储指令移位指令

0x1.跳转指令
跳转指令用于实现程序流程的跳转,不仅在逆向分析中常用到,而且在逆向修改中也常用来实现某些程序或流程的绕过。

1.1  B指令
  B指令的格式为:  B{条件}      <地址>
  B指令是最简单的跳转指令。一旦遇到一个B指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行。
  例:
  B   Label_1234 ;     程序无条件跳转到标号Label处执行

1.2  BL指令
  BL指令格式为:   BL{条件}      <地址>
  BL在跳转之前,会在寄存器R14中保存PC寄存器的内容。
  简言之,当跳转后的指令执行结束后,可通过将R14中的内容重新加载到PC寄存器来实现返回跳转指令后的那个指令处执行。
  也就相当于在指令执行过程中实现了一个子程序调用。
  例: 
  MOV   R0, R1
  BL       Label_1234
  MOV   R0, R2
  上述指令首先实现了R1中的内容转移给R0,之后跳转到Label_1234,在Label_1234执行完毕后,会返回执行MOV  R0, R2。

1.3  BEQ指令、BNE指令
  BEQ和BNE是条件跳转,也就是上面我们指令格式 "B{条件}      <地址>"中的“{条件}”,在smali和il中也有类似的指令,此处不再赘述。

0x2.数据处理指令
数据处理指令可分为数据传送指令、算术/逻辑运算指令、比较指令等。
- 数据传送指令用于在寄存器和存储器之间进行数据的双向传输。
- 算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中的相应条件标志位。
- 比较指令不保存运算结果,只更新CPSR中相应的条件标志位。
【 首先来解释一下CPSR( 程序状态寄存器current program status register)中的条件标志位,比如在BEQ中,EQ即条件标志。
     也就是说CPSR中存储的是譬如大于、小于、等于、不等于之类的条件标志,作为后续执行跳转的判断条件。】

2.1  MOV指令
  MOV指令常见格式为:  MOV{条件} 目的寄存器,源操作数
  MOV指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。
  例:
  MOV  R1, R0   ;将寄存器R0的值传送到寄存器R1

2.2  CMP指令
  CMP指令格式为: CMP{条件} 操作数1,操作数2
  CMP指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新CPSR中条件标志位的值。。
  例:
  CMP  R1, #100  ;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位

2.3  ADD指令、SUB指令、MUL指令

  2.3.1  ADD指令
    ADD指令常用格式为: ADD{条件} 目的寄存器,操作数1,操作数2
    ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
    例:
    ADD   R0, R1, R2           ; R0 = R1 + R2
    ADD   R0, R1, #123        ; R0 = R1 + 123

  2.3.2  SUB指令
    SUB指令常用格式为: SUB{条件} 目的寄存器,操作数1,操作数2
    SUB指令用于把操作数1减去操作数2,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
    例:
    SUB   R0, R1, R2           ; R0 = R1 - R2
    SUB   R0, R1, #123        ; R0 = R1 - 123 

  2.3.3  MUL指令
    MUL指令常用格式为: MUL{条件} 目的寄存器,操作数1,操作数2
    MUL指令完成将操作数1与操作数2的乘法运算,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。
    例:
    MUL  R0, R1, R2      ;R0 = R1 × R2 

2.4  AND指令、ORR指令、EOR指令

  2.4.1  AND指令
    AND指令常用格式为: AND{条件} 目的寄存器,操作数1,操作数2
    AND指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中。
   操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
   例:
    AND   R0, R0, #3           ; 该指令保持R0的0、1位,其余位清零。

  2.4.2  ORR指令
    ORR指令常用格式为: ORR{条件} 目的寄存器,操作数1,操作数2
   ORR指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。
   操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
   例:
   ORR   R0, R0, #3           ; 该指令设置R0的0、1位,其余位保持不变。

  2.4.3  EOR指令
    EOR指令常用格式为: EOR{条件} 目的寄存器,操作数1,操作数2
   EOR指令用于在两个操作数上进行逻辑异或运算,并把结果放置到目的寄存器中。
   操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
   例:
   EOR   R0, R0, #3          ; 该指令反转R0的0、1位,其余位保持不变。

0x3.加载/存储指令
ARM微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。

3.1  LDR指令
LDR指令格式为: LDR{条件} 目的寄存器,<存储器地址>
LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。
例:
LDR   R0, [R1]                  ;将存储器地址为R1的字数据读入寄存器R0。
LDR   R0, [R1, R2]           ;将存储器地址为R1+R2的字数据读入寄存器R0。
LDR   R0, [R1, #3]          ;将存储器地址为R1+3的字数据读入寄存器R0。

3.2  STR指令
STR指令格式为: STR{条件} 源寄存器,<存储器地址>
STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。
例:
STR  R0, [R1], #8         ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。
STR  R0, [R1, #8]         ;将R0中的字数据写入以R1+8为地址的存储器中。

0x4.移位指令
ARM微处理器内嵌的桶型移位器(Barrel Shifter),支持数据的各种移位操作。
移位操作在ARM指令集中不作为单独的指令使用,它只能作为指令格式中是一个字段,在汇编语言中表示为指令中的选项。

4.1  LSL指令、ASL指令
LSL(或ASL)操作格式为: 通用寄存器,LSL(或ASL) 操作数     
LSL(或ASL)可完成对通用寄存器中的内容进行逻辑(或算术)的左移操作,按操作数所指定的数量向左移位,低位用零来填充。
例:
MOV    R0, R1, LSL#2          ;将R1中的内容左移两位后传送到R0中。

4.2  LSR指令
LSR操作格式为: 通用寄存器,LSR 操作数     
LSR可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用零来填充。
例:
MOV    R0, R1, LSR#2         ;将R1中的内容右移两位后传送到R0中,左端用零来填充。

4.3  ASR指令
ASR操作格式为: 通用寄存器,ASR 操作数     
ASR可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用第31位的值来填充。
例:
MOV    R0, R1, ASR#2        ;将R1中的内容右移两位后传送到R0中,左端用第31位的值来填充。