逆向call栈追踪

逆向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日
许可协议