数据流分析

基本原理

数据流分析是一种用来获取相关数据沿着程序执行路径流动的信息分析技术。分析对象是程序执行路径上的数据流动或可能的取值

  • 优点:具有更强的分析能力,适合需要考虑控制流信息且变量属性之操作十分简单的静态分析问题

  • 缺点:分析效率低,过程间分析和优化算法复杂,编程工作量大,容易出错且效率低

一个数据流分析框架(D, L, F)包含:

  1. D:数据流的方向,前向或者后向

  2. L:包含数值作用域V和操作符meet ⊓ 或 join ⊔ 的lattice

  3. F:一系列V to V的传递函数

Tips: 数据流分析可以看成在一个lattice的数值域上,迭代地使用传递函数和操作符

数据流分析的分类

  • 对程序路径的分析精度分类

    • 流不敏感分析(flow insensitive):不考虑语句的先后顺序,按照程序语句的物理位置从上往下顺序分析每一语句,忽略程序中存在的分支

    • 流敏感分析(flow sensitive):考虑程序语句可能的执行顺序,通常需要利用程序的控制流图(CFG)

    • 路径敏感分析(path sensitive):不仅考虑语句的先后顺序,还对程序执行路径条件加以判断,以确定分析使用的语句序列是否对应着一条可实际运行的程序执行路径

  • 分析程序路径的深度分类

    • 过程内分析(intra-procedure analysis):只针对程序中函数内的代码

    • 过程间分析(inter-procedure analysis):考虑函数之间的数据流,即需要跟踪分析目标数据在函数之间的传递过程

      • 上下文不敏感分析(context-insensitive):将每个调用或返回看做一个 “goto” 操作,忽略调用位置和函数参数取值等函数调用的相关信息

      • 上下文敏感分析(context-sensitive):对不同调用位置调用的同一函数加以区分

检测程序漏洞

基于数据流的源代码漏洞分析的原理如下图所示:

  • 代码建模

    • 该过程通过一系列的程序分析技术获得程序代码模型。首先通过词法分析生成词素的序列,然后通过语法分析将词素组合成抽象语法树。如果需要三地址码,则利用中间代码生成过程解析抽象语法树生成三地址码。如果采用流敏感或路径敏感的方式,则可以通过分析抽象语法树得到程序的控制流图。构造控制流图的过程是过程内的控制流分析过程。控制流还包含分析各个过程之间的调用关系的部分。通过分析过程之间的调用关系,还可以构造程序的调用图。另外,该过程还需要一些辅助支持技术,例如变量的别名分析,Java 反射机制分析,C/C++ 的函数指针或虚函数调用分析等

      • 代码解析:指词法分析、语法分析、中间代码生成以及过程内的控制流分析等基础的分析过程

      • 辅助分析:包括控制流分析等为数据流分析提供支持的分析过程

  • 程序代码建模

    • 漏洞分析系统通常使用树型结构的抽象语法树或者线性的三地址码来描述程序代码的语义。控制流图描述了过程内程序的控制流路径,较为精确的数据流分析通常利用控制流图分析程序执行路径上的某些行为。调用图描述了过程之间的调用关系,是过程间分析需要用到的程序结构

  • 漏洞分析规则

    • 漏洞分析规则是检测程序漏洞的依据。对于分析变量状态的规则,可以使用状态自动机来描述。对于需要分析变量取值的情况,则需要指出应该怎样记录变量的取值,以及在怎样的情况下对变量的取值进行何种的检测

      • 程序漏洞通常和程序中变量的状态或者变量的取值相关。状态自动机可以描述和程序变量状态相关的漏洞分析规则,自动机的状态和变量相应的状态对应

  • 静态漏洞分析

    • 数据流分析可以看做一个根据检测规则在程序的可执行路径上跟踪变量的状态或者变量取值的过程。在该过程中,如果待分析的程序语句是函数调用语句,则需要利用调用图进行过程间的分析,以分析被调用函数的内部代码。另外,数据流分析还可以作为辅助技术,用于完善程序调用图和分析变量别名等

      • 赋值语句控制转移语句过程调用语句是数据流分析最关心的三类语句

      • 过程内分析

        • 对于抽象语法树的分析,可以按照程序执行语句的过程从右向左、自底向上地进行分析

        • 对于三地址码的分析,则可以直接识别其操作以及操作相关的变量

        • 流不敏感分析中,常常使用线性扫描的方式依次分析每一条中间表示形式的语句

        • 流敏感的分析路径敏感的分析,则根据控制流图进行分析。对控制流图的遍历主要是深度优先广度优先两种方式

      • ​​

        • 如果在分析某段程序中遇到过程调用语句,就分析其调用过程的内部的代码,完成分析之后再回到原来的程序段继续分析

        • 借鉴基本块的分析,给过程设置上摘要,也包含前置条件和后置条件

          • 前置条件记录对基本块分析前已有的相关分析结果

          • 后置条件是分析基本块后得到的结果

  • 处理分析结果

    • 对检测出的漏洞进行危害程度分类等

方法实现

数据流分析使用的程序代码模型主要包括程序代码的中间表示以及一些关键的数据结构,利用程序代码的中间表示可以对程序语句的指令语义进行分析

抽象语法树(AST)

是程序抽象语法结构的树状表现形式,其每个内部节点代表一个运算符,该节点的子节点代表这个运算符的运算分量。通过描述控制转移语句的语法结构,抽象语法树在一定程度上也描述了程序的过程内代码的控制流结构

例子:

while b ≠ 0
    if a > b
        a := a − b
    else
        b := b − a
return a

对应的抽象语法树为:

由一组类似于汇编语言的指令组成,每个指令具有不多于三个的运算分量。每个运算分量都像是一个寄存器

静态单赋值形式(SSA)

是一种程序语句或者指令的表示形式,在这种表示形式中,所有的赋值都是针对具有不同名字的变量,也就是说,如果某个变量在不同的程序点被赋值,那么在这些程序点上,该变量在静态单赋值形式的表示中应该使用不同的名字。在使用下标的赋值表示中,变量的名字用于区分程序中的不同的变量,下标用于区分不同程序点上变量的赋值情况。另外,如果在一个程序中,同一个变量可能在两个不同的控制流路径中被赋值,并且在路径交汇后,该变量被使用,那么就需要一种被称为 Φ 函数的的表示规则将变量的赋值合并起来

 

作用:静态单赋值形式对于数据流分析的意义在于,可以简单而直接地发现变量的赋值和使用情况,以此分析数据的流向并发现程序不安全的行为

控制流图(CFG)

是指用于描述程序过程内的控制流的有向图。控制流由节点和有向边组成。典型的节点是基本块(BB),即程序语句的线性序列。有向边表示节点之间存在潜在的控制流路径,通常都带有属性(如if语句的true分支和false分支)

调用图(CG)

是描述程序中过程之间的调用和被调用关系的有向图。控制图是一个节点和边的集合,并满足如下原则

  • 对程序中的每个过程都有一个节点

  • 对每个调用点都有一个节点

  • 如果调用点 c 调用了过程 p,就存在一条从 c 的节点到 p 的节点的边

静态漏洞分析

数据流分析检测漏洞是利用分析规则按照一定的顺序分析代码中间表示的过程

  • 过程内分析:对于抽象语法树的分析,可以按照程序执行语句的过程从右向左、自底向上地进行分析。对于三地址码的分析,则可以直接识别其操作以及操作相关的变量

  • 过程间分析:如果在分析某段程序中遇到过程调用语句,就分析其调用过程的内部的代码,完成分析之后再回到原来的程序段继续分析。另一种思路是借鉴基本块的分析,给过程设置上摘要,也包含前置条件和后置条件

原文链接

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值