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

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:函数本质下)