美文网首页
汇编基础(七)Ida分析Ipa中的MachO文件,得到汇编,还原

汇编基础(七)Ida分析Ipa中的MachO文件,得到汇编,还原

作者: struggle3g | 来源:发表于2018-05-16 00:07 被阅读67次

    准备

    • 首先我们准备一个工程
    • 添加一些简单的函数调用,最基本的运算
    • Bulid得到一个app包
    • 将app包里面的MachO文件放入到ida中分析汇编(ida去网上找资源)
    • 初步的将汇编还原成高级代码

    操作

    1.创建工程名字就叫:还原高级代码

    2.添加函数、运算

    3.Bulid得到得到app包

    4.将App包中的MachO文件放入到ida进行解析,生成汇编代码

    汇编、源代码

    汇编

    __text:0000000100006228 _func ; CODE XREF: _main+28↓p
    __text:0000000100006228
    __text:0000000100006228 var_C = -0xC
    __text:0000000100006228 var_8 = -8
    __text:0000000100006228 var_4 = -4
    __text:0000000100006228 var_s0 = 0
    __text:0000000100006228
    __text:0000000100006228 SUB SP, SP, #0x20
    __text:000000010000622C STP X29, X30, [SP,#0x10+var_s0]
    __text:0000000100006230 ADD X29, SP, #0x10
    __text:0000000100006234 STUR W0, [X29,#var_4]
    __text:0000000100006238 STR W1, [SP,#0x10+var_8]
    __text:000000010000623C ADRP X0, #aHaha@PAGE ; "haha"
    __text:0000000100006240 ADD X0, X0, #aHaha@PAGEOFF ; "haha"
    __text:0000000100006244 BL _printf
    __text:0000000100006248 ADRP X30, #_number@PAGE
    __text:000000010000624C ADD X30, X30, #_number@PAGEOFF
    __text:0000000100006250 LDUR W1, [X29,#var_4]
    __text:0000000100006254 LDR W8, [SP,#0x10+var_8]
    __text:0000000100006258 ADD W8, W1, W8
    __text:000000010000625C LDR W1, [X30]
    __text:0000000100006260 ADD W8, W8, W1
    __text:0000000100006264 STR W0, [SP,#0x10+var_C]
    __text:0000000100006268 MOV X0, X8
    __text:000000010000626C LDP X29, X30, [SP,#0x10+var_s0]
    __text:0000000100006270 ADD SP, SP, #0x20
    __text:0000000100006274 RET
    __text:0000000100006274 ; End of function _func

    源代码

    int number = 30;
    int func(int a, int b){
    printf("haha");
    return a + b + number;
    }
    int main(int argc, char * argv[]) {
    printf("%d",func(1, 2));
    return 0;
    }

    汇编分析

    1. 定义的4个变量 将一些偏移量存起来,方便观看
      __text:0000000100006228 var_C = -0xC
      __text:0000000100006228 var_8 = -8
      __text:0000000100006228 var_4 = -4
      __text:0000000100006228 var_s0 = 0
    2. 下面三句拉伸栈空间
      __text:0000000100006278 SUB SP, SP, #0x30
      __text:000000010000627C STP X29, X30, [SP,#0x20+var_s0]
      __text:0000000100006280 ADD X29, SP, #0x20
    3. 将w0 w1 放入栈
      __text:0000000100006234 STUR W0, [X29,#var_4]
      __text:0000000100006238 STR W1, [SP,#0x10+var_8]
    4. 获取一个常量或者全局变量
      __text:000000010000623C ADRP X0, #aHaha@PAGE ; "haha"
      __text:0000000100006240 ADD X0, X0, #aHaha@PAGEOFF ; "haha"
    5. 打印这个常量或者全局变量
      __text:0000000100006244 BL _printf
    6. 获取一个常量或者全局变量
      __text:0000000100006248 ADRP X30, #_number@PAGE
      __text:000000010000624C ADD X30, X30, #_number@PAGEOFF
    7. 一个变量
      __text:0000000100006250 LDUR W1, [X29,#var_4]
    8. 一个变量
      __text:0000000100006254 LDR W8, [SP,#0x10+var_8]
    9. 运算 +
      __text:0000000100006258 ADD W8, W1, W8
    10. 一个变量
      __text:000000010000625C LDR W1, [X30]
    11. 运算 +
      __text:0000000100006260 ADD W8, W8, W1
    12. 将w0存入到栈
      __text:0000000100006264 STR W0, [SP,#0x10+var_C]
    13. x0 = x8
      __text:0000000100006268 MOV X0, X8
    14. 读取回家的路 栈底fp以及lr
      __text:000000010000626C LDP X29, X30, [SP,#0x10+var_s0]
    15. 将栈空间收回 用之前需要拉伸、 用完需要恢复
      __text:0000000100006270 ADD SP, SP, #0x20
    16. 返回main函数
      __text:0000000100006274 RET

    进一步简化

    1. 因为一开始就知道func函数,并且在main的汇编当中我们看到 w8 = #1 w9 = #2 w0 = w8 w1 = w9 所以判定有两个参数



      func(int a, int b){
      }

    2. STUR W0, [X29,#var_4] STR W1, [SP,#0x10+var_8] 存入栈两个参数 就是两个变量 main 中w8 = #1 w9 = #2 w0 = w8 w1 = w9
      int var_4 = a;
      int var_8 = b;
    3. ADRP X0, #aHaha@PAGE ; "haha" ADD X0, X0, #aHaha@PAGEOFF ; "haha" BL _printf
      printf("haha");
    4. ADRP X30, #_number@PAGE ADD X30, X30, #_number@PAGEOFF 拿到的是&number 因为下面的 LDR W1, [X30],ADD W8, W8, W1 w8 == var_8 var_8 == b b 是int 所以 _number 是int类型
      _number 是全局变量
      int number; &number
    5. LDUR W1, [X29,#var_4]
      int w1 = var_4
    6. LDR W8, [SP,#0x10+var_8]
      int w8 = var_8
    7. ADD W8, W1, W8
      w8 = w1 + w8
    8. LDR W1, [X30]
      w1 = number
    9. ADD W8, W8, W1
      w8 = W8 + W1
    10. W0, [SP,#0x10+var_C]
      int var_c = a;
    11. MOV X0, X8 保存返回值
      return x8;

    初步还原的代码

    int number; 
    func(int a, int b){
      int var_4 = a;
      int var_8 = b;
      printf("haha");
      int w1 = var_4;
      int w8 = var_8;
      w8 = w1 + w8;
      w1 =  number;
      w8 = W8 + W1;
      int var_c = a;
      return x8;
    } 
    
    

    最简化

    最终

    int number; 
    func(int a, int b){
      printf("haha");
      return a + b + number;
    } 
    

    原码

    >int number  = 30;
    int func(int a, int b){
        printf("haha");
        return a + b + number;
    }
    int main(int argc, char * argv[]) {
        printf("%d",func(1, 2));
        return 0;
    }
    

    结论

    问题

    • 怎么确定func是否有返回值?
      因为int var_c = a; W0, [SP,#0x10+var_C] 这句话,w0都是返回值,如果没有retrun 为什么多此一举呐?

    • 为什么有返回值在main函数中调用玩func没有调用w0这个返回值呐?
      因为大家在写代码的时候,函数有返回值,但是我们调用的时候没用,就会出现这个问题。

    • Number的值拿不到吗?
      因为系统知道静态变量的值,不需要我们做操作,就好比,为什么拉伸栈空间的时候函数一开始的栈起始位置是多少?因为系统知道,并且我们知道这个是一个值就OK,当成一个常量,只不过不知道它的值

    相关文章

      网友评论

          本文标题:汇编基础(七)Ida分析Ipa中的MachO文件,得到汇编,还原

          本文链接:https://www.haomeiwen.com/subject/gvhudftx.html