汇编基础(八) if、循环的汇编识别

描述

验证if、循环、switch在汇编当中是怎么表示的

if 的汇编

新建的工程 源代码

int g = 12;
void func(int a,int b){
    if(a >b){
        g = a;
    }else{
        g = b;
    }
}
int main(int argc, char * argv[]) {
    func(1, 2);
    return 0;
}

汇编的代码

ext:00000001000068B0 _func ; CODE XREF: _main+28↓p
__text:00000001000068B0
__text:00000001000068B0 var_8 = -8
__text:00000001000068B0 var_4 = -4
__text:00000001000068B0
__text:00000001000068B0 SUB SP, SP, #0x10
__text:00000001000068B4 STR W0, [SP,#0x10+var_4]
__text:00000001000068B8 STR W1, [SP,#0x10+var_8]
__text:00000001000068BC LDR W0, [SP,#0x10+var_4]
__text:00000001000068C0 LDR W1, [SP,#0x10+var_8]
__text:00000001000068C4 CMP W0, W1
__text:00000001000068C8 B.LE loc_1000068E0
__text:00000001000068CC ADRP X8, #_g@PAGE
__text:00000001000068D0 ADD X8, X8, #_g@PAGEOFF
__text:00000001000068D4 LDR W9, [SP,#0x10+var_4]
__text:00000001000068D8 STR W9, [X8]
__text:00000001000068DC B loc_1000068F0
__text:00000001000068E0 ; ---------------------------------------------------------------------------
__text:00000001000068E0
__text:00000001000068E0 loc_1000068E0 ; CODE XREF: _func+18↑j
__text:00000001000068E0 ADRP X8, #_g@PAGE
__text:00000001000068E4 ADD X8, X8, #_g@PAGEOFF
__text:00000001000068E8 LDR W9, [SP,#0x10+var_8]
__text:00000001000068EC STR W9, [X8]
__text:00000001000068F0
__text:00000001000068F0 loc_1000068F0 ; CODE XREF: _func+2C↑j
__text:00000001000068F0 ADD SP, SP, #0x10
__text:00000001000068F4 RET
__text:00000001000068F4 ; End of function _func

汇编代码分析

  • SUB SP, SP, #0x10
    • 拉伸栈空间
  • STR W0, [SP,#0x10+var_4],STR W1, [SP,#0x10+var_8],LDR W0, [SP,#0x10+var_4],LDR W1, [SP,#0x10+var_8]
    • 将w0,w1入栈,并从栈读到w0,w1
  • CMP W0, W1
    • 这个是相当于减法 w0 - w1,会修改标志寄存器,>,<,= ;
  • B.LE loc_1000068E0
  • LE 代表的含义是如果是w0小于等于w1那么会直接跳转到后面写的内存的方法中去_text:00000001000068E0 ADRP X8, #_g@PAGE
    • ADRP X8, #_g@PAGE ,ADD X8, X8, #_g@PAGEOFF 读取一个全局变量_g 存入x8
    • LDR W9, [SP,#0x10+var_8] 从栈读取一个数据存入w9
    • STR W9, [X8] 将w9存入x8的地址中
  • 如果w0大于w1 走这里__text:00000001000068CC ADRP X8, #_g@PAGE
    • ADRP X8, #_g@PAGE ,ADD X8, X8, #_g@PAGEOFF 读取一个全局变量_g 存入x8
    • LDR W9, [SP,#0x10+var_4] 从栈空间读取 [SP,#0x10+var_4] 数据放入w9
    • STR W9, [X8] 将w9的值存入到x8的栈空间
  • ADD SP, SP, #0x10 回复栈空间
  • RET 返回

汇编还原源代码

因为w0、w1是两个参数,在main的汇编当中有
int g = 12;  //动态分析可以知道
func(int a , int b){
STR W0, [SP,#0x10+var_4]
STR W1, [SP,#0x10+var_8]
LDR W0, [SP,#0x10+var_4]
 LDR W1, [SP,#0x10+var_8]
- int var_4 = a
- int var_8 = b
- int w0 = var_4
- int w1 = var_8
- if(w0>w1){
    ADRP X8, #_g@PAGE
    ADD X8, X8, #_g@PAGEOFF
    LDR W9, [SP,#0x10+var_4]
    STR W9, [X8]
    int* x8 = &g;
    int w9 = var_4; 
    *x8 = w9;
  }else{
    ADRP X8, #_g@PAGE
    ADD X8, X8, #_g@PAGEOFF
    LDR W9, [SP,#0x10+var_8]
    STR W9, [X8]
    int *x8 = &g
    int w9 = var_8;
    *x8 = w9
   }
}

最简化代码

int g = 12;
void func{
  if(a>b){
    g = a;
  }else{
    g = b;
  } 
}xw

循环的汇编

源代码 do while

int main(int argc, char * argv[]) {
    int nSum = 0;
    int i = 0;
    do {
        nSum = nSum + 1;
        i++;
    } while (i<100);
    return 0;
}

汇编代码

代码分析

首先从SUB SP, SP, #0x20开始

  • 拉伸栈空间
  • 0x20+var_4 存入0
  • 0x20+var_8 存入w0
  • x1 入栈 SP,#0x20+var_10
  • SP,#0x20+var_14存入0
  • SP,#0x20+var_18存入0
    loc_100006900 ; CODE XREF: _main+38↓j
  • w8 = 读取[SP,#0x20+var_14]
  • W8 = W8 + #1
  • w8 存入SP,#0x20+var_14
  • 从SP,#0x20+var_18 读取给 w8
  • W8 = W8+#1
  • w8 存入 SP,#0x20+var_18
  • SP,#0x20+var_18 读取给w8
  • CMP W8, #0x64 减法运算判断
  • B.LT loc_100006900 判断如果小于执行地址中的方法,如果大于等于直接走下面方法
  • w8 = 0
  • x0 = x8
  • 恢复栈空间
  • 返回

还原源代码

先做后判断 是do while

var_4 = 0
var_8 = w0
var_10 = x1
var_14 = 0
var_18 = 0

do{
  w8 = var_14
  w8 = w8 + 1
  var_14 = w8
  w8 = var_18
  w8 = w8 + 1
  var_18 = w8
  w8 = var_18
}while(w8<0x64)
w8 = 0
x0 = x8

简化

func(id w0,id w1){
do{
  int var_14 = 0;
  var_14 = var_14 + 1;
  int var_18 = 0;
  var_18 = var_18 + 1;
}while(var_18<0x64);
return 0;
}

源代码while

int main(int argc, char * argv[]) {
    int nSum = 0;
    int i = 0;
    while (i<100){
        nSum = nSum + 1;
        i++;
    } ;
    return 0;
}

汇编代码while

0x104a1a8e4 <+0>: sub sp, sp, #0x20 ; =0x20
0x104a1a8e8 <+4>: str wzr, [sp, #0x1c]
0x104a1a8ec <+8>: str w0, [sp, #0x18]
0x104a1a8f0 <+12>: str x1, [sp, #0x10]
-> 0x104a1a8f4 <+16>: str wzr, [sp, #0xc]
0x104a1a8f8 <+20>: str wzr, [sp, #0x8]
0x104a1a8fc <+24>: ldr w8, [sp, #0x8]
0x104a1a900 <+28>: cmp w8, #0x64 ; =0x64
0x104a1a904 <+32>: b.ge 0x104a1a924 ; <+64> at main.m
0x104a1a908 <+36>: ldr w8, [sp, #0xc]
0x104a1a90c <+40>: add w8, w8, #0x1 ; =0x1
0x104a1a910 <+44>: str w8, [sp, #0xc]
0x104a1a914 <+48>: ldr w8, [sp, #0x8]
0x104a1a918 <+52>: add w8, w8, #0x1 ; =0x1
0x104a1a91c <+56>: str w8, [sp, #0x8]
0x104a1a920 <+60>: b 0x104a1a8fc ; <+24> at main.m:19
0x104a1a924 <+64>: mov w8, #0x0
0x104a1a928 <+68>: mov x0, x8
0x104a1a92c <+72>: add sp, sp, #0x20 ; =0x20
0x104a1a930 <+76>: ret

代码分析

  • sub sp, sp, #0x20 ; =0x20 拉伸栈空间
  • 0x1c = 0
  • 0x18 = w0
  • 0x10 = x1
  • 0xc = 0
  • 0x8 = 0
  • w8 = 0x8
  • w8 和0x64比较大小 w8 - 0x64
  • 如果上面的结果 大于等于执行地址中的方法,否则向下执行
    • 小于等于
      • w8 = 0xc
      • w8 = w8 + 1
      • 0xc = w8
      • w8 = 0x8
      • w8 = w8 + 1
      • 0x8 = w8
  • w8 = 0
  • x0 = x8
  • 回复栈空间

简化代码

int func(id a, id b){
    int 0xc = 0
    int 0x8 = 0
  while(0x8<0x64){
    0xc = 0xc + 1
    0x8 = ox8 + 1 
  }
  return 0;
}

源代码循环for

int main(int argc, char * argv[]) {
    for (int i = 0; i<100; i++) {
        printf("woqu");
    }
    return 0;
}

汇编代码

__text:00000001000068C8 _main
__text:00000001000068C8
__text:00000001000068C8 var_18          = -0x18
__text:00000001000068C8 var_14          = -0x14
__text:00000001000068C8 var_10          = -0x10
__text:00000001000068C8 var_8           = -8
__text:00000001000068C8 var_4           = -4
__text:00000001000068C8 var_s0          =  0
__text:00000001000068C8
__text:00000001000068C8                 SUB             SP, SP, #0x30
__text:00000001000068CC                 STP             X29, X30, [SP,#0x20+var_s0]
__text:00000001000068D0                 ADD             X29, SP, #0x20
__text:00000001000068D4                 STUR            WZR, [X29,#var_4]
__text:00000001000068D8                 STUR            W0, [X29,#var_8]
__text:00000001000068DC                 STR             X1, [SP,#0x20+var_10]
__text:00000001000068E0                 STR             WZR, [SP,#0x20+var_14]
__text:00000001000068E4
__text:00000001000068E4 loc_1000068E4                           ; CODE XREF: _main+44↓j
__text:00000001000068E4                 LDR             W8, [SP,#0x20+var_14]
__text:00000001000068E8                 CMP             W8, #0x64
__text:00000001000068EC                 B.GE            loc_100006910
__text:00000001000068F0                 ADRP            X0, #aWoqu@PAGE ; "woqu"
__text:00000001000068F4                 ADD             X0, X0, #aWoqu@PAGEOFF ; "woqu"
__text:00000001000068F8                 BL              _printf
__text:00000001000068FC                 STR             W0, [SP,#0x20+var_18]
__text:0000000100006900                 LDR             W8, [SP,#0x20+var_14]
__text:0000000100006904                 ADD             W8, W8, #1
__text:0000000100006908                 STR             W8, [SP,#0x20+var_14]
__text:000000010000690C                 B               loc_1000068E4
__text:0000000100006910 ; ---------------------------------------------------------------------------
__text:0000000100006910
__text:0000000100006910 loc_100006910                           ; CODE XREF: _main+24↑j
__text:0000000100006910                 MOV             W8, #0
__text:0000000100006914                 MOV             X0, X8
__text:0000000100006918                 LDP             X29, X30, [SP,#0x20+var_s0]
__text:000000010000691C                 ADD             SP, SP, #0x30
__text:0000000100006920                 RET
__text:0000000100006920 ; End of function _main

分析

  • 从 STUR WZR, [X29,#var_4] var_4 = 0
  • var_8 = w0
  • var_10 = x1
  • var_14 = 0
  • w8 = var_14
    • 因为_text:00000001000068E4 loc_1000068E4 ,__text:000000010000690C B loc_1000068E4 所以是一个循环
  • cmp w8 0x64 比较
  • B.GE 上面大于等于直接跳出循环。
  • 小于
    • ADRP、ADD获取一个常量或者全局变量 “我去” x0 是参数
    • BL printf 打印
    • var_18 = w0
    • w8 = var_14
    • w8 = w8 + 1
    • var_14 = w8
    • 跳转到 loc_1000068E4 B直接跳转没有 不用保存lr
  • 下面的不用说了

简化代码

int func(id var_8, id var_10){
   for(int var_14 = 0;var_14<0x64;i++){
    printf("woqu");
  }
  return 0;
}

你可能感兴趣的:(汇编基础(八) if、循环的汇编识别)