目录
一、内存分区
- 代码区:存放代码。可读、可执行
- 栈区: 参数、局部变量、临时数据。可读、可写
- 堆区: 动态申请。可读、可写
- 全局区/静态区(static):全局变量。可读、可写
- 常量区:只读
二、全局变量、常量在内存中的情况
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软件中
_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;
}
网友评论