符号执行简介
1
定义
符号执行(英语:symbolic execution)是一种计算机科学领域的程序分析技术,通过采用抽象的符号代替精确值作为程序输入变量,得出每个路径抽象的输出结果。这一技术在硬件、底层程序测试中有一定的应用,能够有效的发现程序中的漏洞。
基本原理
举例说明:
1 | int f() { |
对于以上代码,如果实际执行,那么效果是:读入一个值到y,然后令z等于y的2倍。如果z等于6,调用fail(),反之打印ok。
对于符号执行来说,流程中不定的值会被赋为$\lambda$,一个符号值,这个值可以是任何值,在这个例子中,y会等于$\lambda$,z会等于2$\lambda$,当遇到分支时,会模拟执行所有分支,即当2$\lambda$等于12时调用fail(),当2$\lambda$不等于12时打印ok。在符号执行完所有的路径后,会计算出一个能完成这个路径的符号的变量实际值,该例中,调用fail()是$\lambda$==6的结果,打印ok是$\lambda$!=6时成立
上面这个过程中,每一个条件被叫做一个约束
,每一个结果对应的所有约束被称为约束集,每一个结果经过的约束集被称为路径
,路径可以由执行树表示。而符号执行的目的,就是让符号值遍历所有路径,找到所有对应的约束集。
为了完成以上工作,在整个流程中存在两个变量符号状态
$\sigma$和路径条件
$PC$,并根据读到的语句对约束进行添加(以下为例子):
- 若是输入语句,在$\sigma$中添加映射:$\sigma$={var$\rightarrow$$\lambda_0$},此时$\lambda_0$是var变量的符号值。
- 若是赋值语句,则把符号值代入计算,在$\sigma$中添加映射:$\sigma$={var$\rightarrow$$\lambda_0$,$var_2$$\rightarrow$$\lambda_0$+7}
- 当遇到条件语句if(e) a else b.PC会先更新为PC$\land$$\sigma$(e)表示then,然后创建PC$^`$初始化为PC$\neg$$\land\sigma$(e)表示另一条路径
- 如果遇到exit,错误,前后约束矛盾,这一个路径会终止。
评论