逆向call栈追踪
参数传递
在函数调用时, 使用栈传递参数, 其汇编如下
1 |
|
调用call后, 会将返回地址也压入栈中, 此时栈中结构如下
esp | 返回地址 |
---|---|
esp+4 | 参数1 |
esp+8 | 参数2 |
函数开头push的作用
1. 局部变量开辟
1 |
|
2. 保存寄存器
查看call的结尾, 查找对应的pop, 一个push对应一个pop
3. 下一个call的参数
对call进行下断, 查看call执行完毕后栈内内存收缩大小, 即为call的参数大小
比如 call 缩小了4个字节, 那么call的参数为 4 / 4 = 1个参数
函数内部esp和ebp的操作
1. ebp分析
特征: call下有如下指令
1 |
|
执行后栈中结构如下
相对位置 | 栈 |
---|---|
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栈追踪/