0x00 概述
通过阅读本文您将能够了解到如下几个方面:
- 函数调用过程中发生的事情。
- 函数栈帧空间的布局与变化。
- 局部变量作用域理解。
- 函数调用堆栈的一个实现原理。
- ARM栈空间操作和X86、X64的异同。
本文将通过IDA实际调试一个函数调用过程为读者展示栈空间的操作过程。
0x01 ARM堆栈空间变化
Thumb指令集就是ARM指令集的一个子集,其指令长度为2,ARM指令长度为4字节,所以很多指令不能用。例如函数序言部分(函数开头部分,一般为堆栈开辟指令)的寄存器保存 ,ARM中一般使用STMFD,LDMFD指令进行保存与恢复, thumb则通过push、pop指令。下面分析使用了Thumb指令集代码(只是随意选择了一个SO的一个任意函数)。
在函数的其中一个调用函数指令处设置断点,汇编如下所示:
.text:76564B0A MOV R0, SP ; memcpy dest 将其余参数拷贝到SP开始的位置
.text:76564B0C ADD R3, PC ; dword_766235D8
.text:76564B0E LDR R5, [R3]
.text:76564B10 STR R1, [SP,#0xD0+var_68]
.text:76564B12 MOVS R2, #0x44 ;memcpy size
.text:76564B14 LDR R4, [R5]
.text:76564B16 ADD R1, SP, #0xD0+fileList+4 ; memcpy src
.text:76564B18 BLX memcpy ;把后续参数依次拷贝到sp+0起始地址处
.text:76564B1C LDR R2, [SP,#0xD0+s] ; 第三个参数,r2寄存器
.text:76564B1E LDR R3, [SP,#0xD0+fileList] ; 第四个参数,r3寄存器
.text:76564B20 LDR R1, [SP,#0xD0+var_68] ; 第二个参数,r1寄存器
.text:76564B22 MOVS R0, R5 ; 第一个参数,this指针,r0寄存器
.text:76564B24 LDR R4, [R4,#0x40]
.text:76564B26 BLX R4 ;调用了一个函数,在该位置设置断点进行调试
.text:76564B28 STR