逆向call栈追踪

参数传递

在函数调用时, 使用栈传递参数, 其汇编如下

1
2
3
push 参数2
push 参数1
call xxxxx

调用call后, 会将返回地址也压入栈中, 此时栈中结构如下

esp返回地址
esp+4参数1
esp+8参数2

函数开头push的作用

1. 局部变量开辟

1
2
push xxx
sub esp, 0x10

2. 保存寄存器

查看call的结尾, 查找对应的pop, 一个push对应一个pop

3. 下一个call的参数

对call进行下断, 查看call执行完毕后栈内内存收缩大小, 即为call的参数大小
比如 call 缩小了4个字节, 那么call的参数为 4 / 4 = 1个参数

函数内部esp和ebp的操作

1. ebp分析

特征: call下有如下指令

1
2
3
push ebp
mov ebp, esp
sub esp, 0x10

执行后栈中结构如下

相对位置
ebp-0x10开辟的局部空间
ebp原来的ebp
ebp+4返回地址
ebp+8参数1
ebp+C参数2

1. 如果xx很大, 或者esp和ebp的差值很大

那么ebp很可能时一个普通寄存器, 不能追

2. xx > 0, xx比较小

xx为参数, 参数为 (xx - 4) / 4, 例如ebp+8为参数1, ebp+C为参数2, 追踪参数即可

3. xx < 0, xx比较小

说明为栈内局部变量, 其变量值为 xx / 4, 例如ebp-4为局部变量1, ebp-8为局部变量2
追汇编位置到call开始位置

4. edp 和 edp + 4

正常情况不会出现, 很有可能为检测函数

esp分析

对于esp + xx, 首先查看其在栈中的位置, 确定其相对于返回地址的位置

1. 如果在返回地址之下`

数据为参数, 直接去call位置找参数即可

2. 如果在返回地址之上

那么为局部变量

会导致esp变化的指令

指令说明变动
sub esp, n; push eax;打开一个地址并写入值-n
pop eax; add esp, 4;关闭一个地址+n
add esp, 4;关闭一个地址+n
sub esp, 4;打开一个地址-n
call xxx; 无对应ret调用数据+4
ret; ret n;关闭n个地址-4 -n

3. 如果就为返回地址

那么为检测代码


逆向call栈追踪
https://simonkimi.githubio.io/2024/01/12/逆向call栈追踪/
作者
simonkimi
发布于
2024年1月12日
许可协议