1.1.1 定义与核心概念 #
二进制Diff(Binary Diff) 是一种分析技术,用于比较两个或多个二进制可执行文件之间的差异。与源代码层面的diff不同,二进制diff需要在没有源代码的情况下,直接对编译后的机器码进行分析和比较。
源代码Diff 二进制Diff
┌─────────────────┐ ┌─────────────────┐
│ source_v1.c │ │ binary_v1.exe │
│ source_v2.c │ │ binary_v2.exe │
│ ↓ │ │ ↓ │
│ 文本行比较 │ │ 反汇编分析 │
│ 语法树比较 │ │ CFG比较 │
│ 语义分析 │ │ 函数匹配 │
└─────────────────┘ └─────────────────┘
1.1.2 二进制Diff的核心挑战 #
1. 信息丢失问题 #
- 编译过程中丢失了变量名、函数名、注释等源代码信息
- 编译器优化会改变代码结构
- 不同编译器生成的代码差异巨大
2. 地址随机化 #
- ASLR(地址空间布局随机化)导致每次加载地址不同
- 函数和变量的相对位置可能改变
3. 代码变形 #
- 相同源代码用不同编译器/优化级别编译结果差异很大
- 代码混淆技术主动破坏代码结构
4. 规模化问题 #
- 现代软件动辄数十MB到数GB
- 需要高效的算法处理大规模二进制
1.1.3 二进制Diff与传统Diff的本质区别 #
| 维度 | 源代码Diff | 二进制Diff |
| 输入 | 文本文件 | 二进制字节流 |
| 基本单位 | 字符/行/Token | 字节/指令/基本块/函数 |
| 结构信息 | AST、语法树 | CFG、调用图 |
| 语义理解 | 变量、类型、作用域 | 寄存器、内存、指令语义 |
| 噪声来源 | 格式化、空白 | 编译器、优化、混淆 |
| 算法复杂度 | O(n) 到 O(n²) | O(n²) 到 O(n³) 或更高 |