Page 109 - 《软件学报》2020年第11期
P. 109

陈千  等:函数级数据依赖图及其在静态脆弱性分析中的应用                                                    3425


                    (3)  函数 a 到函数 b 之间存在一条可执行路径,且此路径上不存在其他对参数 v 的定义.
                    图 4 所示为代码片段及其对应的函数级数据依赖图示例.其中,函数 fread(⋅)对参数 buf 进行定义,函数
                 base64_decode(⋅)引用了参数 buf,同时,两个函数之间存在一条可执行路径,因此,函数 base64_decode(⋅)和 fread(⋅)
                 之间关于参数 buf 存在“引用关系”.同理,函数 strstr(⋅)和 base64_decode(⋅)、函数 printf(⋅)和 copy_lower(⋅)之间关
                 于参数 cmd 均存在“引用”关系.另外,函数 copy_lower(⋅)对参数 cmd 进行重新定义,而函数 base64_decode(⋅)和
                 copy_lower(⋅)之间存在一条可执行路径,且路径上没有对参数 cmd 的其他定义,因此,函数 copy_lower(⋅)和
                 base64_decode(⋅)之间关于参数 cmd 存在“消灭”关系.



























                               Fig.4    Example of code snippet and its function-level data dependence graph
                                           图 4   代码片段及其函数级数据依赖图示例
                 2.3   函数级数据依赖图特性分析

                    指令级数据依赖图 DDG 以语句为节点,在构建过程中会考虑所有的变量,即在所有相关变量之间建立“定
                 义-引用”依赖关系,关系精确、完整,适用于程序切片、程序数据结构恢复等应用,但在程序静态脆弱性分析方
                 面却不高效.一方面,DDG 将变量与变量所处的语境(如变量为函数 strcpy(⋅)的参数)分开,变量的上下文信息变
                 得不明确;另一方面,考虑所有变量会造成 DDG 的规模极大,而很多变量信息对脆弱性分析没有帮助,导致后续
                 的数据依赖分析效率低下,浪费计算时间和空间.
                    函数级数据依赖图 FDDG 以函数为节点,在构建过程中仅考虑函数之间参数的相互依赖关系,得到的依赖
                 图粒度较“粗”,难以用于程序切片.但 FDDG 将变量与其所处的语境保存在一起,同时保留了变量路径分析所需
                 要的全部信息,适用于程序静态脆弱性分析,如对缓冲区溢出和命令注入等漏洞进行检测.此外,由于 FDDG 的规
                 模比较小,数据流比较清晰,因此对参数进行回溯效率很高.
                    图 5 所示为针对同一段汇编代码构建的两种数据依赖图示例.由图 5 可知,指令级数据依赖图 DDG 的规模
                 明显大于函数级数据依赖图 FDDG.同时,在 DDG 中,函数与函数参数是分离的;而 FDDG 则直接将函数参数和
                 函数保存在一起.此外,针对图 5(a)中的 strcpy(buf,argv[1])语句,在进行静态脆弱性分析时,需要对参数 buf 和
                 argv[1]进行溯源,以获取参数指向的内存空间大小、参数来源等信息.基于图 5(c)所示的 DDG 进行回溯,查找路
                 径包括“11→10”和“9→8→7→6→2”;而在图 5(d)所示的 FDDG 中,函数参数中已经包含了所需的信息,不用进行
                 回溯.
   104   105   106   107   108   109   110   111   112   113   114