最近写论文遇到了符号执行方法,想起来上学期上《形式化方法》课有专门关于符号执行的内容,在此先就课堂内容和课后作业对符号执行做一个简要的概述吧。
1 背景引言相关
1.1 程序验证方法的范围
程序安全性验证的技术如下:
横轴-Cost 程序验证的代价/要求(对程序员的要求、时间、经验等等)
纵轴-Confidence 可信度
(1)Ad-hoc Testing(随机测试)
随机测试是没有书面测试用例、记录期望结果、检查列表、脚本或指令的测试。主要是根据测试者的经验对软件进行功能和性能抽查。其需要花费的代价低,不过相应的其能提供的可信度也很低。
(2)Concolic Testing(混合测试)& Whitebox Fuzzing(白盒模糊测试)
混合测试是具体的符号执行测试,是具体执行和符号执行相结合,后面可能会单独写一篇文章进行介绍。【先立个flag在这hhhh】
模糊测试是一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法,可分为黑盒模糊测试、白盒模糊测试和灰盒模糊测试,后面可能也有单独写文章介绍模糊测试。【第二个flag】
(3)Symbolic Execution(符号执行)
符号执行的代价高于前两种工具,但相应的可信度也提升了,可以实现全路径覆盖,也能发现一些其他工具发现不了的BUG。
工具举例:KLEE
(4)Extended Static Checking
(5)Static Analysis(静态分析/程序分析)
(6)Verification(验证)
1.2 使用符号执行的原因
1.2.1 黑盒测试的困难性
考虑下方代码什么时候会触发 “DivdieByZero” 异常?
int foo(int x, int y){
if(x==32467289)
return x/y;
else
return 0;
}
根据代码可知,当 x== 32467289 && y == 0 时,会触发 除零 异常。
当看不到源代码时,如何发现代码中的这一漏洞?
考虑黑盒模糊测试,即随机生成整型的输入值:
Foo(1, 1)