符号执行相关

符号执行相关

符号执行 (Symbolic Execution)是一种程序分析技术。其可以通过分析程序来得到让特定代码区域执行的输入。使用符号执行分析一个程序时,该程序会使用符号值作为输入,而非一般执行程序时使用的具体值。在达到目标代码时,分析器可以得到相应的路径约束,然后通过约束求解器来得到可以触发目标代码的具体值。

符号模拟技术(symbolic simulation)则把类似的思想用于硬件分析。符号计算(Symbolic computation)则用于数学表达式分析。

基本原理

符号执行的关键思想就是,把输入变为符号值,那么程序计算的输出值就是一个符号输入值的函数。这个符号化的过程在上一篇AEG文章中已有简要阐述,简而言之,就是一个程序执行的路径通常是true和false条件的序列,这些条件是在分支语句处产生的。在序列的 i t h i^{th} ith位置的判断如果值是 t r u e true true,那么意味着 i t h i^{th} ith条件语句走的是then这个分支;反之如果是false就意味着程序执行走的是else分支。

符号执行不关心程序的功能和实现,关心的是其分支结构(包括判断条件和分支去向).

/*ith branch*/
if(condition)
then
	...
else
	...

如果针对数个分支进行分析,那么程序可能执行的路径会形成一个树型结构.这种结构称为执行树.

比如:

if(condition0)
{
	...//Operation0_1
	if(condition1)
	{
		...//Operation1_1
		if(condition2)
		{
			...//Operation2_1
		}
		else
		{
			...//Operation2_0
		}
	}
	else
	{
		...//Operation1_0
	}
}
else
{
	...//Operation0_0
}

的树结构为

在这里插入图片描述

针对这样的树,很直观的得出最多需要3个输入分别针对condition0,condition1,condition2判断点即可遍历.

而需要的输入方案(即真值指派)有 2 3 = 8 2^3=8 23=8种.

如果某个以分支为划分的代码块内存在致使程序崩溃或发生其他问题的部分,当遍历至这一块时程序退出并生成错误报告.包括崩溃或错误类型和此时的输入方案.这就是符号执行的引擎的主要原理.

符号执行的要求

  • 尽可能的覆盖所有的可能的执行路径.
  • 速度尽可能快.

路径爆炸

可以看到,对于一组分支组成的树形结构,最少有 O ( n ) O(n) O(n)种指派方案可以覆盖到所有路径,也就是说最小的复杂度是线性的.最多有 O ( 2 n ) O(2^n) O(2n)种指派方案,是指数增长类型.这就是路径爆炸.

所以对于商业级的项目,遍历所有分支就成了一项近乎不可能的工程.

符号执行要做的

符号执行实质是通过限制路径搜索空间来进行程序遍历,运行时间与所需要遍历的路径空间大小成正比。

利用可靠的程序分析技术来减小路径爆炸的复杂度

利用启发式搜索搜索最佳路径.

启发式搜索

启发式搜索算法,就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。

启发式搜索算法有点像广度优先搜索,不同的是,它会优先顺着有启发性和具有特定信息的节点搜索下去

,这些节点可能是到达目标的最好路径。

我们称这个过程为最优(best-first)或启发式搜索。

下面是其基本思想:

  1. 假定有一个启发式(评估)函数f ,可以帮助确定下一个要扩展的最优节点,我们采用一个约定,即f的值小或大表示找到了好的节点。这个函数基于指定问题域的信息,它是状态描述的一个实数值函数。
  2. 下一个要扩展的节点n是f(n)值取最*值的节点
  3. 当下一个要扩展的节点是目标节点时过程终止.

程序分析

在计算机科学中,程序分析是指自动分析一个程序的包括正确性、健壮性、安全性和活跃性等特征的过程。 程序分析主要研究两大领域:程序的优化(英语:Program optimization)和程序的正确性。前者研究如何提升程序性能并且降低程序的资源占用,后者研究如何确保程序完成预期的任务。

程序分析可以在不执行程序的情况下进行(静态程序分析),也可在执行时进行.

方法1:静态地合并路径,然后再使用求解器。也就是分支的归并和约简.

方法2: 在后续的计算中,记录并重用low-level function的分析结果。

方法3 : 自动化剪枝.也就是减小分析量.

约束求解

约束求解是符号执行的技术瓶颈,是最为耗时的部分,会包含大量的复杂的数据操作,大大增加约束求解的难度.其实质是对于一个布尔方程,求使其成立的真值指派方案.使用穷举的方法非常没有效率.通常使用SMT求解方法、提高约束求解器的求解速度、利用查询技术简化约束项等优化方法。

不相关的约束项的去除

程序分支主要依赖于一小部分的程序变量,即依赖于一小部分来自路径条件的约束。因此,一种有效的方法就是去掉那些与当前分支的输出不相关的路径条件。

现有路径条件:

( x + y &gt; 10 ) a n d ( z &gt; 0 ) a n d ( y &lt; 12 ) a n d ( z − x = 0 ) (x+y&gt;10)and(z&gt;0)and(y&lt;12)and(z-x=0) (x+y>10)and(z>0)and(y<12)and(zx=0)

假设想生成满足

( x + y &gt; 10 ) a n d ( z &gt; 0 ) a n d ¬ ( y &lt; 12 ) (x+y&gt;10)and(z&gt;0)and¬(y&lt;12) (x+y>10)and(z>0)and¬(y<12)

的与y有关约束集合 { x = f ( y ) , z = g ( y ) } \{x=f(y),z=g(y)\} {x=f(y),z=g(y)}

则(z>0)和(z-x=0)这两个约束都可以去掉。

递增求解

核心思想就是缓存已经求解过的约束.

( x + y &lt; 10 ) a n d ( x &gt; 5 ) → { x = 6 , y = 3 } (x+y&lt;10)and(x&gt;5)\rightarrow\{x=6,y=3\} (x+y<10)and(x>5){x=6,y=3}

对于新的约束,首先判断这个新约束的搜索空间是缓存里约束的超集还是子集。如果是新的约束的搜索空间是缓存的约束的子集,那么,就把缓存中的约束去掉多余的条件后继续求解。如果是超集,那么直接把解代入去验证。

参考链接

https://www.wikiwand.com/zh-hans/程序分析

https://zhuanlan.zhihu.com/p/26927127

https://www.wikiwand.com/zh-cn/%E5%90%AF%E5%8F%91%E5%BC%8F%E6%90%9C%E7%B4%A2

https://www.wikiwand.com/zh-cn/%E5%90%AF%E5%8F%91%E5%BC%8F%E6%90%9C%E7%B4%A2

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
符号执行中的符号变量表示程序中的内存地址,符号内存就是指在符号执行过程中,用符号变量代替程序中的实际内存地址。符号内存可以用来发现程序中的内存相关漏洞,例如空指针引用、数组越界、内存泄漏等。 符号内存的主要问题在于,它会导致路径爆炸问题的加剧。由于符号内存的取值范围通常很大,符号执行需要对每个符号内存地址进行考虑,这会导致程序的执行路径数呈指数级别增长。此外,符号内存的处理还需要考虑指针的复杂语义,例如指针的动态分配和释放、指针的递归引用等等,这也会导致符号执行的计算复杂度变得非常高。 为了解决符号内存的问题,符号执行研究者提出了一些技术和方法,例如: 1.符号执行中的内存模型:为了简化符号内存的处理,符号执行可以采用一些简化的内存模型,例如基于语义的内存模型、基于类型的内存模型等等。 2.路径压缩技术:符号执行中的路径压缩技术可以减少路径爆炸问题的影响,例如基于路径约简的技术、基于路径合并的技术等等。 3.静态分析技术:符号执行可以结合静态分析技术,例如基于程序切片的技术、基于程序抽象的技术等等,来降低符号内存的计算复杂度。 4.约束求解技术:符号执行中的约束求解技术是符号内存处理的关键,可以采用一些高效的约束求解算法和数据结构,如基于位向量的算法、基于SMT求解器的算法等等。 综上所述,符号内存是符号执行中的一个重要问题,需要结合其他技术和方法来解决。在实际应用中,需要根据具体问题选择合适的技术,并进行优化和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值