核心概念:符号变量、符号状态、路径约束、执行树
好,咱们正式开始啃符号执行的核心概念。
说实话,这四个概念就像汽车的四个轮子——少一个你都跑不起来。我当年刚接触符号执行时,就是被这些术语搞得晕头转向。后来在逆向一个混淆过的二进制时,才真正体会到它们有多重要。
今天咱们就把这四个轮子一个一个拆开看。你搞懂了它们,符号执行的大门就算正式推开了。
符号变量:不是具体值,而是一个“未知数”
先问个问题:普通程序执行时,变量存的是什么?
具体值。比如 int x = 5,x 就是 5。
但符号执行不一样。它把变量变成一个“符号”——说白了就是一个未知数,就像你初中数学里的 x、y。它不绑定具体数值,只代表一个“可能的值”。
核心区别:
- 具体执行: x = 5,y = 3,z = x + y → z = 8
- 符号执行: x = α,y = β,z = α + β → z 是一个表达式
我在逆向一个加密算法时遇到过这种情况。输入是一个 16 字节的 key,如果用具体值去跑,你得试 2^128 种可能——这辈子都试不完。但用符号变量,我直接把 key 的每个字节设成符号 α0、α1、α2...,然后让符号执行引擎自己去推导它们之间的关系。
我的习惯:给符号变量命名时,尽量用有意义的名称。比如输入缓冲区叫 input_0、input_1,别用 a、b、c。不然约束条件一多,你自己都看不懂。
符号状态:程序在“符号世界”里的快照
符号状态是什么?你可以把它理解成程序在某个时刻的“内存快照”——只不过这个快照里存的不是具体值,而是符号表达式。
举个例子。假设有这么一段代码:
int a = sym_input(); // a 是符号变量 α
int b = a * 2;
int c = b + 10;
执行到第三行时,符号状态大概是这样的:
| 变量 | 符号表达式 |
|---|---|
| a | α |
| b | α * 2 |
| c | α * 2 + 10 |
你看,符号状态记录的不是“c 等于多少”,而是“c 是怎么算出来的”。这个信息在逆向时特别有用——你能追踪到每个变量和原始输入之间的关系。
我曾经踩过的坑:符号状态会随着路径分支而分裂。如果你不控制分支数量,状态会爆炸式增长。我有个项目跑了 3 个小时,生成了 20 多万个状态——最后内存直接爆了。后来加了路径剪枝才搞定。
路径约束:程序走过的“路”的条件
路径约束,说白了就是“程序要走到当前这行代码,必须满足哪些条件”。
来看个经典例子:
int x = sym_input();
if (x > 10) {
// 路径 A
} else {
// 路径 B
}
如果程序走到了路径 A,那路径约束就是 x > 10。如果走到了路径 B,约束就是 x <= 10。
你想想看,这个有什么用?
我在逆向一个 license 验证函数时,就靠路径约束找到了正确的序列号。那个函数有 5 层嵌套的 if 判断,每层都检查输入的不同位。我用符号执行跑了一遍,收集了所有路径的约束条件,然后用约束求解器一算——直接得到了能让程序走到“验证通过”分支的输入值。
路径约束的本质:它是从程序入口到当前位置的所有分支条件的“与”运算。
比如:(x > 10) ∧ (y < 5) ∧ (z == 0)
执行树:所有可能路径的“地图”
执行树就是把所有可能的执行路径画成一棵树。每个节点代表一个程序状态,每条边代表一次分支选择。
我习惯把执行树想象成“程序的可能性空间”。你从根节点(程序入口)出发,每遇到一个条件分支,树就分叉一次。最终,每条从根到叶子的路径,都对应一组特定的输入条件。
下面是我画的一张执行树示意图,帮你直观理解:
你看这张图。从入口开始,每遇到一个条件判断,树就分叉一次。最终 8 个叶子节点,对应 8 条不同的执行路径。每条路径的约束条件都不一样。
实际项目中的经验:执行树的深度和宽度直接决定了符号执行的效率。我一般会设置一个最大深度(比如 100 层),超过这个深度的路径直接丢弃。不然遇到循环结构,树能长到天上去。
四个概念怎么配合?
好,现在咱们把四个概念串起来。我用自己的理解给你捋一遍:
- 符号变量是原材料——你把输入变成未知数
- 符号状态是中间结果——记录每个变量怎么算出来的
- 路径约束是条件记录——记下程序走了哪条路
- 执行树是全局视图——展示所有可能的路
它们的关系是这样的:符号执行引擎从符号变量开始,维护着符号状态往前走。遇到分支时,复制当前状态,分别加上不同的路径约束,形成新的分支。所有分支合在一起,就是执行树。
一句话总结:符号变量是“问号”,符号状态是“草稿纸”,路径约束是“路标”,执行树是“地图”。四者缺一不可。
嗯,这四个概念你吃透了,后面学约束求解、路径探索这些高级话题就会轻松很多。我当年就是在这四个概念上花了最多时间——一旦搞明白,后面的东西就是水到渠成的事。