🎨 颜色标记说明

  • 粉色:特别重要、主线必掌握、优先复盘的内容。
  • 蓝色:核心概念、术语、分类名。
  • 橙色:需要关注的边界、易错点、注意事项。
  • 绿色:解释类内容、帮助理解知识点。

返回:全书总览 · 下一章:基本数据类型

工具不是主角

逆向分析的主线是提出假设并验证,工具只是观察程序的不同窗口。

工具 主要用途 适合回答的问题
Visual Studio 编译、源码调试、查看编译器输出 一段 C++ 会生成什么代码
GCC / MinGW 对比不同编译器和 ABI 同一语法在不同工具链下是否相同
OllyDbg 经典 32 位用户态动态调试 指令执行时寄存器和栈如何变化
x64dbg x86/x64 用户态动态调试 断点、模块、内存和调用跟踪
WinDbg 用户态、内核态和转储分析 异常、线程、符号和系统结构
IDA 静态反汇编、函数识别、交叉引用 程序整体结构和调用关系是什么

静态分析负责建立全局地图,动态调试负责验证某一次真实执行。

建议实验矩阵

同一份最小代码至少保留四个构建:

1
2
x86 Debug     x86 Release
x64 Debug x64 Release

比较时记录:

  • 是否保留帧指针。
  • 参数通过栈还是寄存器传递。
  • 函数是否被内联。
  • 常量和分支是否被优化掉。
  • 调试填充值和安全检查是否出现。

Visual Studio 中应掌握的观察点

  1. 项目平台必须明确选择 x86 或 x64。
  2. Debug 与 Release 的优化配置需要分开记录。
  3. 反汇编窗口要与寄存器、内存、调用堆栈一起看。
  4. 关闭“仅我的代码”后,才能更完整地观察 CRT 和系统库。
  5. 保留 PDB,便于对照源码与机器代码。

带符号的 Debug 版本适合学习映射关系,但真实逆向经常面对无符号、优化后的 Release 代码。

动态调试器的基本节奏

1
2
加载目标 → 确认模块与入口 → 设置断点 → 运行到断点
→ 单步观察 → 记录证据 → 回到静态视图命名

常用动作:

动作 含义
Step Into 进入调用目标
Step Over 执行调用并停在下一条指令
Run Until Return 执行到当前函数返回
Follow in Dump 在内存窗口跟随地址
Cross Reference 查看代码或数据被谁引用

IDA 的核心价值

IDA 会进行递归遍历、函数识别、控制流分析和交叉引用整理,但自动分析不是事实本身。

分析时重点使用:

  • Functions:函数边界与命名。
  • Imports:导入 API 与能力线索。
  • Strings:字符串及其引用。
  • Xrefs:调用者、被调用者和数据访问点。
  • Graph View:基本块和分支结构。
  • Structures:结构体偏移和成员类型。

反汇编引擎的基本原理

x86/x64 指令长度可变。反汇编器从某个地址开始读取字节,依次解析:

1
前缀 → 操作码 → ModR/M → SIB → 位移 → 立即数

同一串字节从不同位置开始解码,可能产生不同指令。因此必须结合入口点、分支目标、函数边界和可执行节属性判断代码起点。

1
2
3
4
机器字节: 55 8B EC 83 EC 10
反汇编: push ebp
mov ebp, esp
sub esp, 10h

我的分析记录模板

1
2
3
4
5
6
7
8
9
10
样本与哈希:
文件架构:
编译配置:
模块基址:
关键函数 RVA:
断点位置与原因:
输入条件:
寄存器/栈变化:
静态推测:
动态验证:

学习检查清单

检查项 状态
能构建四种实验版本并说明差异 待复盘
能区分静态分析和动态调试的职责 待复盘
能在调试器中查看寄存器、栈和内存 待复盘
能使用字符串和交叉引用定位函数 待复盘
能说明变长指令为什么会产生解码边界问题 待复盘