北大软件CoBOT(库博)是具有自主知识产权的静态检测工具。在2013年获得了计算机软件著作权,基于值依赖分析的C程序缺陷静态检测系统。很多同行对值依赖分析的概念可能不是太清楚,今天我们主要分析一下这个技术。
值依赖分析是建立在值流模型基础之上的,值流模型最早由Horwitz提出,值流图中结点与结点之间的连线表示的是数据流分析中的定值使用关系。值流依赖表示由于定值-使用连接的依赖关系。值流依赖关系可以通过值依赖图来表现。
Value Dependence Graph(简称VDG),值依赖图,是一种基于程序值依赖分析的、路径敏感的空指针解引用检测方法,主要分析守卫值依赖分析和非守卫值依赖分析。该方法通过结合数据流分析中的到达定值分析、区间分析及指向分析创建了值依赖分析图,该图刻画了可能产生空指针语句到其解引用语句的值依赖关系.该图中的边采用守卫标注,即描述了相邻点之间的到达条件,降低误报率。
值依赖的边连接两个存在依赖关系值依赖结点。值依赖边是有向边,边的头结点被称为定义结点,尾结点称为使用结点。定义结点和使用结点中分别存在一个导致依赖关系的变量,分别称为定义变量和使用变量。此外,值依赖边还存储了定义结点和使用结点之间的到达条件。
康奈尔大学Cherem等人对值流模型进行完善,在值流模型的边上增加约束表达式,以此来表达相邻结点之间的可达条件。扩展后的值流模型应用于内存泄漏的缺陷检测,将程序分析问题规约为逻辑的问题,通过约束求解器来判断缺陷是否可能发生。
基于改进后的值流模型有一款缺陷检测工具FastCheck,其基本流程是:第一步,通过前端构建的待测程序的控制流图。第二步,通过标准的数据流分析程序的定值使用关系。第三步,根据定值使用分析的结果,辅以指向分析的信息,构建直流图。第四步,以此进行无守卫的值流分析和基于守卫的值流分析。最后,综合值流分析结果和布尔可满足求解器SAT的结果,给出缺陷报告。
新南威尔士大学的Yulei等人对值流模型进一步改进、利用流敏感、上下文敏感的指向分析技术,通过分析数值型变量和非嵌套指针的静态单赋值形式表示的定制使用关系,建立全稀疏直流图。
值依赖分析技术以程序源代码作为输入、采用数据流分析、指向分析、区间分析等多种分析技术给出每个变量的值的依赖关系,并以此为基础构建程序表达模型。值依赖分析方法是一种解决跨函数问题的静态分析求精技术,它改进了值流模型的不足,使得模型表达语义更加丰富,模型表达能力更加强大,从而使分析结果更加准确。
值流模型仍然存在着下面问题:
- 无法表达指针操作的副作用;
- 无法表达数值型变量的定制使用关系;
- 无法表达数组、结构体以及解引用之间的定值使用关系。
因此北京大学的马森博士对值流模型进行优化和改进,将改进后的模型成为值依赖模型。
- 通过对程序中所有语句进行定值使用关系的分析,为程序中出现的变量(包括指针型和数值型)建立值依赖关系,改善了模型对数组、解引用、结构体等数据结构的表达;
- 通过部分定值概念的引入支持结构体对其域的影响;
- 通过计算值依赖模型中的守卫条件,表达定值节点所处分支的条件;
- 通过优化原有的守卫计算算法,降低复杂度使其可应用于大规模工程检测;
- 通过区间分析、指向分析等多种静态分析技术的引入、增强模型的表达能力,从而值依赖模型可以正确地表达别名指针对变量取值的影响。
值依赖模型的构建方法如下图:
第一步:初步构建值依赖图,根据到达定值分析得到的变量间的使用关系,在结点之间添加依赖边,但增加了对结构体域、解引用、数组的处理。
第二步:值依赖的守卫构建。通过控制流分析计算结点之间的可达条件,标注在相应的边上。
第三步:值依赖图的精化构造。根据指向分析结果完善指针对变量值流的影响;根据区间分析移除事实上不可能存在的值依赖边;通过常量扩展、常量折叠的技术,简化值依赖边上的守卫信息。
值依赖模型的结点有如下几种类型:
赋值结点:对于形如x=y的函数赋值语句,值依赖模型创建一个反应该语句语义的赋值结点。此外,对于存在右值的形如S var=e的声明语句,值依赖模型也创建一个反应该语句语义的赋值结点。
声明结点:对于不存在右值的形如S var的声明语句,值依赖模型创建一个反映该语句语义的声明结点。
函数返回结点:对于形如return e的函数返回语句,值依赖模型创建一个反映该语句语义的函数返回结点。
实参结点:对于形如e=f(p1,p2,…pn)的函数调用语句,值依赖模型对每个参数pi创建一个实参结点pi@e= f(p1,p2,…pn)
形参结点:对于形如e=f(p1,p2,…pn)的函数调用语句,根据函数调用图,找到被调函数的函数声明f(fp1,fp2,…fpn),对于每个形参fpi创建一个形参结点,并从实参结点向对应形参的形参结点连接值依赖边。
值依赖入口结点:值依赖模型拥有唯一的值依赖入口结点。该结点的作用是,对于其他的原本没有前驱的值依赖结点n,若从程序入口到n存在不为真的达到条件,则从值依赖入口结点向n连接一条值依赖边。边上的守卫为程序入口到n的条件。
分支语句结点:对于每条条件分支语句,值依赖模型创建一个反映该语句语义的分支语句结点。
成员方法调用结点:该结点与实参结点类似,区别在于成员方法调用结点处理实参在对象上的方法调用。
构造器参数结点:对于形如C(p1,p2,…pn)的构造器语句,值依赖模型对每个参数pi创建一个构造参数结点pi@ C(p1,p2,…pn)。
下面是一个通过CoBOT工具生成的VDG图。
更多信息请咨询库博技术。
(完)