汇编基础(八) 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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容