符号化执行引擎对比

随着fuzz技术的发展,发现以AFL为代表coverage-guided的fuzz引擎达到一个瓶颈,因为是盲目的,所以现在有很流行的方法——加入符号化执行。比如Driller、QSYM、和我讲过的SAVIOR,这三个都很大的提高了fuzz的效率。但是符号化执行也是和fuzz一样复杂而内容丰富的领域,这里就把最近看的一个文章跟大家分享下,简单介绍几个流行的符号化执行。

[1]Roberto Baldoni, Emilio Coppa, Daniele Cono D’elia, Camil Demetrescu, and Irene Finocchi. 2018. A Survey of Symbolic Execution Techniques. ACM Comput. Surv. 51, 3, Article 50 (May 2018), 39 pages. DOI:https://doi.org/10.1145/3182657
[2]Sebastian Poeplau and Aurélien Francillon. 2019. Systematic comparison of symbolic execution systems: intermediate representation and its generation. In Proceedings of the 35th Annual Computer Security Applications Conference (ACSAC ’19). Association for Computing Machinery, New York, NY, USA, 163–176. DOI:https://doi.org/10.1145/3359789.3359796

符号化执行概念

在一次有具体输入的程序运行过程中,经过的路径都是确定的。而符号化执行就是把变量变成符号(即无确定数值),那么根据变量的不同取值,就可以动态地执行不同的程序路径。
在一次符号执行的过程中,符号执行引擎通常要保存以下两个信息:1、一个一阶布尔公式,描述沿着该路径的分支所满足的条件;2、一个将变量映射到符号表达式或值的符号内存。

运算
以执行上述代码为例,符号化执行引擎会生成以下的一个执行树。其中σ是程序中变量与含αi 的表达式或者具体值的映射,π 是当前路径的约束。
这样一来,通过对当前路径的约束进行求解(一般用 solversatisfiability modulo theories (SMT) )就可以知道当前路径是否可达并生成到达该路径的输入。
在这里插入图片描述

几种不同的符号执行引擎

符号执行引擎首先是对象不同,有的需要源码支持,有的对二进制机器码进行翻译;其次是中间语言(Intermediate Representation),有的不翻译成中间语言直接执行机器码,流行的有LLVM bitcode,VEX IR;还有就是使用的语言不一样,有的是C++,有的是Python,可能会对效率产生印象;最后就是是否支持concolic execution(fuzz结合常用这个,先用具体的input得到一个执行路径,按照某种策略对分支点依次翻转获得别的执行路径)。[2]这个文章主要比较了四个符号执行引擎:KLEE,S2E,angr和QSYM。

NameObjectIRProgram Languageconcolic execution
KLEEsource codeLLVMC++
S2EbinaryLLVMC++QEMU with KVM
angrbinaryVEX IRPythonUnicore
QSYMbinaryC++directly on CPU

S2E是针对KLEE无法对二进制生成LLVM IR的缺点,在QEMU虚拟机上实现了将二进制程序翻译成LLVM IR。
其他的符号执行引擎有,Manticore在重点上与angr相似,也在Python中实现,但不使用任何中间表示。Triton是基于动态二进制转换的,类似于Qsym。基于BAP的Mayhem是DARPA CGC竞赛的获胜者(但不是免费提供的)。SAGE是微软公司开发的一种封闭源代码系统,采用并行执行方式。奠基于KLEE的Inception是为数不多的支持ARM的符号执行引擎之一,它解决了在基于源代码的符号执行中处理内联汇编的挑战

如何比较

为了研究源码生成IR和二进制程序生成IR对符号执行的影响以及不同IR的优劣,有三个指标可以进行比较:
1、相较于直接对机器码进行执行,不同的IR会增加还是减少指令的数量。
2、IR的执行效率会是多少。
3、约束求解器在IR的查询效率。

作者采用了CGC(DARPA’s Cyber Grand Challenge)的程序,不同的IR可能会不兼容一些程序,最后在四个符号执行引擎下能够使用的程序如下图所示。
在这里插入图片描述
代码大小
在比较源码生成IR和二进制程序生成IR的实验中,方法是比较生成的IR指令数,下图是IR指令数和源码指令数(用angr反汇编算出)的比,简称膨胀系数。
在这里插入图片描述
其中McSema是IDA Pro使用的静态分析引擎。从图中可以看出,KLEE使用了源码,因此可以生成更加简洁的IR,膨胀系数小于1,S2E不近翻译了二进制程序,因为在QEMU中,QEMU的指令翻译加大了膨胀系数。
执行速度
单位内执行的IR指令数称为执行效率。
在这里插入图片描述
可以发现QSYM因为没有使用IR直接执行机器码,有更高效率。虽然S2E和KLEE都是使用LLVM源码,但是S2E以来QEMU虚拟机的动态仿真,效率更低。Angr的效率低很有可能是他的编程语言用的是Python,这里没有认为是LLVM比VEX快,因为在代码大小那里比较时观察力angr和S2E的指令大小范围相差不大。

solver 查询复杂性
IR的生成会对solver的查询性能产生影响,这里举了一个例子,比如约束条件里对list[3]这个变量进行查询,S2E需要十多行代码,而KLEE只有四行代码。很明显,这是源码带来的优化效果。
这里的比较方法是使用concolic execution到达一条特定的执行路径,然后把这条路径的约束条件收集起来,然后在本地用四个引擎跑solver,看求解使用时间的大小,如下图。
在这里插入图片描述
可以发现KLEE得益于源码优势可以少快于其他三个引擎,在大部分的查询效率中和S2E一样(符合统一IR)。

结论

源码和二进制对符号执行有什么影响
影响不是很大,源码带来的优势是查询复杂度会大大降低,但是对与整体的测试执行效率不会有很大提升。比如QSYM对机器码的直接执行带来的加速效果远远覆盖了复杂度劣势。
不同的IR是否有优劣之分
这里是认为QSYM执行机器码能够得到很有效的提升,但是牺牲了可移植性和兼容性。LLVM和VEX的话性能相似,选择的话要基于其他需求,比如API的稳定性、语言的可兼容性(angr使用python,KLEE使用C++)、是否需要源码、交互性(angr加入了很多交互接口,降低了速率但是提升了可使用性)。


接下来可能对angr或者klee进行进一步了解,研究一下fuzz和concolic execution的结合使用。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值