美文网首页
iOS 逆向开发04:函数本质下

iOS 逆向开发04:函数本质下

作者: differ_iOSER | 来源:发表于2021-08-15 10:31 被阅读0次

    iOS 逆向开发 文章汇总

    目录

    一、内存分区

    • 代码区:存放代码。可读、可执行
    • 栈区: 参数、局部变量、临时数据。可读、可写
    • 堆区: 动态申请。可读、可写
    • 全局区/静态区(static):全局变量。可读、可写
    • 常量区:只读

    iOS内存五大分区

    二、全局变量、常量在内存中的情况

    main.m
    
    int g = 12;
    
    int func(int a, int b) {
        printf("haha");
        int c = a + g + b;
        return c;
    }
    
    int main(int argc, char * argv[]) {
       
        func(1, 2);
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    
    Demo`func:
        // 拉伸栈空间
    ->  0x104409f34 <+0>:  sub    sp, sp, #0x20             ; =0x20 
        0x104409f38 <+4>:  stp    x29, x30, [sp, #0x10]
        0x104409f3c <+8>:  add    x29, sp, #0x10            ; =0x10 
        // 函数参数入栈保存
        0x104409f40 <+12>: stur   w0, [x29, #-0x4]
        0x104409f44 <+16>: str    w1, [sp, #0x8]
    
        // 在常量区取出字符串常量---重点
        0x104409f48 <+20>: adrp   x0, 2
        0x104409f4c <+24>: add    x0, x0, #0xe15            ; =0xe15 (x0寄存器传参)
        0x104409f50 <+28>: bl     0x10440a378               ; symbol stub for: printf
    
        0x104409f54 <+32>: ldur   w8, [x29, #-0x4]
        // 在全局区取出全局变量
        0x104409f58 <+36>: adrp   x9, 8
        0x104409f5c <+40>: add    x9, x9, #0x480            ; =0x480 
        0x104409f60 <+44>: ldr    w10, [x9]
    
        0x104409f64 <+48>: add    w8, w8, w10
        0x104409f68 <+52>: ldr    w10, [sp, #0x8]
        0x104409f6c <+56>: add    w8, w8, w10
        0x104409f70 <+60>: str    w8, [sp, #0x4]
        0x104409f74 <+64>: ldr    w8, [sp, #0x4]
        0x104409f78 <+68>: mov    x0, x8                    ; x0寄存器存储返回值
        // 平衡栈空间
        0x104409f7c <+72>: ldp    x29, x30, [sp, #0x10]
        0x104409f80 <+76>: add    sp, sp, #0x20             ; =0x20 
        0x104409f84 <+80>: ret    
    
    重点代码解读:

    adrp x0, 2:当前指令的内存地址后三位清零,后第四位加2,保存到x0中-->得到该常量所在内存页的起始地址
    add x0, x0, #0xe15:x0保存的内存地址加上偏移地址-->得到该常量的内存地址

    三、汇编还原

    将可执行文件拖入Hopper软件中

    Hopper

    _func中的汇编代码如下:

            ; ================ B E G I N N I N G   O F   P R O C E D U R E ================
    
     _func:
    sub        sp, sp, #0x20 ; CODE XREF=_main+32
    stp        x29, x30, [sp, #0x10]
    add        x29, sp, #0x10
    stur       w0, [x29, #-0x4]
    str        w1, [sp, #0x8]
    adrp       x0, #0x100003000 ; argument #1 for method imp___stubs__printf
    add        x0, x0, #0xe15 ; "haha"
    bl         imp___stubs__printf
    ldur       w8, [x29, #-0x4]
    adrp       x9, #0x100009000
    add        x9, x9, #0x480 ; _g
    ldr        w10, x9
    add        w8, w8, w10
    ldr        w10, [sp, #0x8]
    add        w8, w8, w10
    str        w8, [sp, #0x4]
    ldr        w8, [sp, #0x4]
    mov        x0, x8
    ldp        x29, x30, [sp, #0x10]
    add        sp, sp, #0x20
    ret
    

    首先将栈拉伸和平衡的代码区分开、找出函数调用

            ; ================ B E G I N N I N G   O F   P R O C E D U R E ================
    
     _func:
    sub        sp, sp, #0x20 ; CODE XREF=_main+32
    stp        x29, x30, [sp, #0x10]
    add        x29, sp, #0x10
    
    stur       w0, [x29, #-0x4]
    str        w1, [sp, #0x8]
    
    adrp       x0, #0x100003000 ; argument #1 for method imp___stubs__printf
    add        x0, x0, #0xe15 ; "haha"
    bl         imp___stubs__printf
    
    ldur       w8, [x29, #-0x4]
    adrp       x9, #0x100009000
    add        x9, x9, #0x480 ; _g
    ldr        w10, x9
    add        w8, w8, w10
    ldr        w10, [sp, #0x8]
    add        w8, w8, w10
    str        w8, [sp, #0x4]
    ldr        w8, [sp, #0x4]
    mov        x0, x8
    
    ldp        x29, x30, [sp, #0x10]
    add        sp, sp, #0x20
    ret
    

    函数参数、变量处理,计算

    int gl;
    
            ; ================ B E G I N N I N G   O F   P R O C E D U R E ================
    
     _func:
    sub        sp, sp, #0x20 ; CODE XREF=_main+32
    stp        x29, x30, [sp, #0x10]
    add        x29, sp, #0x10
    
    //stur       w0, [x29, #-0x4]
    //str        w1, [sp, #0x8]
    函数两个参数:a、b
    
    ///adrp       x0, #0x100003000 ; argument #1 for method imp___stubs__printf
    //add        x0, x0, #0xe15 ; "haha"
    //bl         imp___stubs__printf
    print("haha")
    
    //ldur       w8, [x29, #-0x4]
    w8 = a
    
    //adrp       x9, #0x100009000
    //add        x9, x9, #0x480 ; _g
    //ldr        w10, x9
    w10 = gl
    
    //add        w8, w8, w10
    w8 = w8 + w10
    
    //ldr        w10, [sp, #0x8]
    w10 = b
    
    //add        w8, w8, w10
    w8 = w8 + w10
    
    //str        w8, [sp, #0x4]
    //ldr        w8, [sp, #0x4]
    //mov        x0, x8
    x0 = w8
    
    ldp        x29, x30, [sp, #0x10]
    add        sp, sp, #0x20
    ret
    

    还原出的伪代码:

    int gl = ?;
    
    int func(int a, int b) {
      print("haha")
      w8 = a
      w10 = gl
      w8 = w8 + w10
      w10 = b
      w8 = w8 + w10
      x0 = w8
    }
    

    从下至上进一步还原:

    int gl = ?;
    
    int func(int a, int b) {
      print("haha");
      return a + gl + b;
    }
    

    相关文章

      网友评论

          本文标题:iOS 逆向开发04:函数本质下

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