一、程序切片定义
程序切片
程序切片,旨在从程序中提取满足一定约束条件的代码片段(对指定变量施加影响的代码指令,或者指定变量所影响的代码片段),是一种重要的程序分解技术。
程序切片,可以从大规模程序中精确定位分析员所关心的代码片段,有效缓解程序规模日益增长带来的分析效率难以同步提高的问题。
比如,在漏洞挖掘中,我们可以只关注可执行文件或者源代码某一行敏感函数调用相关的代码片段,来分析是否存在缓冲区溢出漏洞等。
根据计算方向的不同,程序切片可以分为,前向切片和后向切片。前向切片的计算方向和程序的运行方向是一致的。
控制流图
控制流图(Control Flow Graph,简称CFG),也叫控制流程图,是一个过程或程序的抽象表现,代表了一个程序执行过程中会遍历到的所有路径。
控制流图:一个程序的控制流图CFG可以表示为一个四元组,形如G=(V,E,s,e),其中V表示变量的集合,E表示边的集合,s表示控制流图的入口,e表示控制流图的出口。
程序中的每一条指令都映射为CFG上的一个节点,具有控制依赖关系的结点之间用一条边连接。
程序依赖图
程序依赖图(Program Depandence Graph,PDG),可以表示一个五元组,形如G=(V,DDE,CDE,s,e),其中V表示变量的集合,DDE表示数据依赖边的集合,CDE表示控制依赖边的集合,每条边连接了图中的两个结点,程序中的每一条指令都映射为CFG上的一个结点。s表示程序依赖图的入口结点,e表示程序依赖图的出口结点。
控制依赖:表示两个基本块在程序流程上存在的依赖关系。
数据依赖:表示程序中引用某变量的基本块(或者语句)对定义该变量的基本块的依赖,即是一种“定义-引用”依赖关系。
系统依赖图
系统依赖图(Sysem Dependence Graph,SDG),可以表示为一个七元组,形如G=(V,DDE,CDE,CE,TDE,s,e),其中V变量的集合,DDE表示数据依赖边的集合,CDE表示控制依赖边的集合,CE表示函数调用边,TDE表示参数传递造成的传递依赖边的集合,结点s表示系统依赖图的入口结点,结点e表示系统依赖图的出口结点。 SDG在PDG的基础上进行了扩充,系统依赖图中加入了对函数调用的处理。
二、程序切片方法
工作原理
在实际的程序调试过程中,通常程序员只关注程序的部分行为。
切片准则包含两个要素,即切片目标变量(如变量z),以及开始切片的代码位置(如z所在的代码位置:第12行)。严格来说,程序P的切片准则是二元组<n,V>,其中n是程序中一条语句的编号,V是切片所关注的变量集合,该集合是P中变量的一个子集。
切片语句,可以利用数据依赖和控制依赖分析方法来获取。
程序切片,通常包括3个步骤:
图可达算法
程序切片技术有多种计算方法,例如:数据流方程算法、图可达性算法,基于波动图的切片算法、基于信息流关系的切片算法等。其中,最常用和最主流的算法是数据流方程算法与图可达性算法。
图可达性算法根据程序建模的不同分为许多子类,最常用的包括基于程序依赖图的图可达性算法和基于系统依赖图的图可达性算法。
在程序依赖图PDG中,具有直接依赖关系和间接依赖关系的结点都用一条边连接,因此基于PDG的图可达性切片算法只需从指定结点遍历每一个具有依赖关系的结点即可,计算过程比较简单直观。
例子
动态切片
从切片角度,切片分为静态程序切片、动态程序切片、条件切片。
由于静态切片中包含了到达兴趣点的所有可能路径,而对于程序的某一次特定执行,其中的许多路径实际上是不会被执行的。
动态切片需要考虑程序的特定输入,切片准则是一个三元组(N,V,I),其中N是指令集合,V是变量集合,I是输入集合。
动态切片可以看做静态切片的子集。
参考
南开大学刘哲理老师编写的《软件安全:漏洞利用及渗透测试》教材的配套教学视频