这一部分从“看指令”进入“用工具复盘函数结构”。IDA 偏静态分析,DBG/x64dbg/WinDbg 偏动态调试。两者结合,才能把函数边界、交叉引用、参数、返回值和调用栈看清楚。

1、内容范围

小节 内容 复盘点
08.0 代码堆栈回溯栈帧 从栈帧定位调用链
08.1 模块符号信息解析 PDB、符号名和模块信息
08.2 DBG 工具下载与配置 调试器环境、符号路径、插件
08.3 / 09.0 DBG 逆向调试技巧 断点、单步、内存、寄存器
08.4 IDA 交叉引用回溯 Xref、函数调用关系
08.5 - 08.9 函数参数与返回分析 栈参数、寄存器返回、调用约定
09.1 - 09.3 还原思路与堆栈逃逸 控制流、栈异常、线程栈信息

2、IDA 静态分析

IDA 更适合先看整体结构。

功能 用途
Functions 查看函数列表
Strings 查找字符串入口
Imports 查看导入 API
Xrefs 追踪谁引用了某个函数/字符串
Graph View 看控制流分支
Pseudocode 辅助理解高级逻辑

复盘时不要完全相信伪代码,关键判断还要回到汇编。

3、DBG 动态调试

动态调试适合验证程序实际怎么跑。

操作 复盘问题
下断点 程序什么时候执行到这里
单步 每条指令如何影响寄存器
内存窗口 数据是否按预期改变
调用栈 当前函数由谁调用
模块窗口 当前地址属于哪个模块
异常窗口 崩溃或断点如何触发

4、符号信息

符号能把地址还原成函数名、变量名或源码位置。没有符号时,只能靠地址、字符串、导入表和调用关系推测。

情况 分析方式
有 PDB 使用符号名、源码行辅助定位
无 PDB 根据函数结构和引用关系命名
第三方库 结合导入表、字符串和已知库特征

5、函数结构分析

分析一个函数时可以按固定模板走:

步骤 问题
函数入口 有没有保存寄存器、建立栈帧
参数来源 来自栈还是寄存器
局部变量 栈上留了多少空间
调用 API 调用了哪些系统或库函数
分支逻辑 条件跳转依赖哪些标志
返回值 最终写入哪个寄存器

6、参数传递与返回值

x86 里常看 [ebp+8][ebp+0Ch] 这类参数;x64 里常看 RCX/RDX/R8/R9 和栈上的额外参数。

1
2
x64 常见前四个整数/指针参数:
RCX, RDX, R8, R9

7、反汇编还原正向代码

还原时不要追求“写回原源码”,而是写出等价逻辑。

1
2
cmp eax, 0
jz label_false

可以先还原成:

1
2
3
if (value != 0) {
// true branch
}

8、堆栈异常与回溯

如果返回地址被破坏、栈指针不平衡、函数指针异常,调用栈可能断裂。防护复盘里看到这种现象,要优先保留崩溃地址、调用栈、寄存器和异常码。

9、学习检查清单

检查项 状态
能用 IDA 找字符串引用和函数交叉引用 待复盘
能用调试器观察寄存器、栈和内存 待复盘
能说明有无符号信息对逆向的影响 待复盘
能根据调用约定推测函数参数 待复盘
能把简单汇编分支还原成 C 风格逻辑 待复盘