赞
踩
几乎每个程序员都遇到过这样的情况:为了在一行代码中发现错误,需要阅读成百行的代码。(可能不止)此外,程序切片作为一种程序分析基础方法也应用于软件安全分析领域中,在程序和网络协议逆向、软件漏洞成因和机理分析、软件漏洞利用自动生成领域都发挥了重要作用。
程序切片旨在从程序汇总提取满足一定约束条件的代码片段(对指定变量施加影响的代码指令,或者指定变量所影响的代码片段),是一种重要的程序分解技术。
以C语言为例,不说也都知道,为了叙事的完整性,还是加上喽哈哈哈
其实就是什么结构都么有…
i = 1;
j = i;
判断
if (i == 1)
j = 1;
else
j = 2;
while(count --) {
i += 1;
}
这个用汇编直观一点
call func
对于绝大部分程序而言,形成控制流的结构主要为3种,即顺序、条件和循环,本质上循环就是一种条件结构。因此控制流的基本结构除了顺序执行外就是由条件结构形成的非顺序执行结构。
下面我们引入“基本块”的概念,“基本块”就是一个顺序执行的语句序列,只能从该块的第一条语句开始执行一直到该代码块的最后一句离开该块。
所以基本块应该满足下面的条件:
学过编译原理的小伙伴应该对基本块这个东西并不陌生。
一般而言,入口指令包括程序入口指令,函数入口指令,跳转指令的目的地址处的指令。获得了入口指令之后,只需要把两两入口指令之间的代码抽取出来就是一个基本块。
程序被划分为基本块后,若将基本块视为一个基本单元节点,基本块之间在程序执行流程上互为前驱和后继关系视为两个基本块之间存在一条边,则整个程序能够转换为一个有向图,该图被称为控制流图。
if A = 10 then
if B > C
A = B
else A = C
endif
endif
print A, B, C
在上图CFG中,我们用<1, 2>作为图上连接1,2的有向边,这里称2为1的直接后继,1为2的直接前驱。1的所有直接前驱集合为Pred(1)
,所有直接后继为Succ(2)
。
对于两个节点a, b,若从开始接节点Entry
到节点b的所有路径都经过节点a,则称节点a支配节点b,并称a是b的前必经节点,表示为a—>b。若a<>b,则a是b的严格前必经节点,表示为a—>pb
如果不存在节点使得a—>pq, q—>pb,则称a是节点b的严格直接前必经节点。
反之亦然。
数据流分析关注的是跨越多条语句的变量定义、复制和运算操作,但是由于变量所存储的数据在多条语句中时动态变化的,难以同时进行分析。
所以,在数据分析的过程中需要确定一条特定的语句为基准进行数据流分析。通常一条语句都会有引用变量和定义变量两种行为。
产生集: Gen(s)
消灭集: Kill(s)
入集: In(s)
出集: Out(s)
O u t [ s ] = I n [ s ] + g e n − k i l l Out[s] = In[s] + gen - kill Out[s]=In[s]+gen−kill
loop0 | loop1 | loop2 | loop3 | |||||||
---|---|---|---|---|---|---|---|---|---|---|
gen(Bi) | kill(Bi) | In | Out | In | Out | In | Out | In | Out | |
Entry | Φ | Φ | Φ | Φ | Φ | Φ | Φ | Φ | Φ | Φ |
B1 | 1,2 | 3,4,5 | Φ | 1,2 | 3 | 1,2 | 2,3 | 1,2 | 2,3 | 1,2 |
B2 | 3 | 1 | Φ | 3 | 1,2 | 2,3 | 1,2 | 2,3 | 1,2 | 2,3 |
B3 | 4 | 2,5 | Φ | 4 | 2,3 | 3,4 | 2,3 | 3,4 | 2,3 | 3,4 |
B4 | 5 | 2,4 | Φ | 5 | 3,4 | 3,5 | 3,4 | 3,5 | 3,4 | 3,5 |
Exit | Φ | Φ | Φ | Φ | 3,5 | 3,5 | 3,5 | 3,5 | 3,5 | 3,5 |
在程序的某处为 x 引入一个未定义值 ⊥,如果 ⊥ 能达到某个 x 的使用,那么说明这个地方的使用可能是未定义值,这就是一个程序错误隐患。java中的nullpointerexception
就可以套用这个分析发现错误。
活性分析是指对某个语句定义的变量是否在后续语句中被引用以及被哪些语句引用的情况。
程序依赖和上文中前后必经关系的最大区别在于,程序依赖需要被依赖节点能够决定依赖节点的被执行与否。能够决定是否被执行的情况往往为条件、循环等。顺序结构没有必然的前后因果关系所以他们没有依赖和被依赖的关系。
累了累了,直接放个图…
最初的程序切片技术应用于软件维护阶段的排错调试阶段,即为研发人员提供一种观察和理解程序的方法。在实际的程序调试过程中,通常程序员只关注程序的部分行为。
在一段程序中找到感兴趣的代码段,即为切片准则。这个感兴趣通常是与某个变量相关。
程序切片通常包括三个部分。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。