首页 > 其他分享 >SAST-数据流分析方法-理论

SAST-数据流分析方法-理论

时间:2024-04-08 18:25:12浏览次数:22  
标签:SAST 调用 ... void 分析方法 数据流 foo 方法

引言

众所周知,数据流分析是实现污点分析的一种常用技术

数据流分析分为过程内的数据流分析与过程间的数据流分析。前者是对一个方法体内的数据流分析,主要是基于CFG分析,不涉及方法调用;后者是基于不同方法间的数据流分析,主要是基于ICFG+CG分析,会涉及方法调用。

一、过程内数据流分析

1. CFG的构建

1.1.把程序转换为IR(此处采用3AC)表示

3地址码中的地址可能有如下的几种类型:

  • 名字(Name),包括
    • 变量(Variable)
    • 标签(Label)
      • 用于指示程序位置,方便跳转指令的书写
  • 字面常量(Literal Constant)
  • 编译器生成的临时量(Compiler-Generated Temporary)

每一种指令都有其对应的 3 地址码形式,一些常见的 3 地址码形式如下:(x, y, z是变量的地址)

x = y bop z  // bop 是双目操作符(Binary Operator),可以是算数运算符,也可以是逻辑运算符
x = uop y  // uop 是单目操作符(Unary Operator),可能是取负、按位取反或者类型转换
x = y 
goto L  // goto 是无条件跳转,L 是标签(Label),是标记程序位置的助记符,本质上还是地址
if x goto L  // if... goto 是条件跳转
if x rop y goto L // rop 是关系运算符(Relational Operator),运算结果一般为布尔值

1.2.找程序的Leader集合L,进而划分Basic Block

  • 程序入口
  • 跳转指令的目标指令
  • 跳转指令的下一条指令

(一个Leader到下一个Leader之前就是一个BB)

1.3.连接Basic Block

程序控制流的产生来源于两个地方:

  • 天然的顺序执行
    • 这是计算系统天然存在的一种控制流
  • 跳转指令
    • 这是人为设计添加的一种控制流

示例

二、过程间数据流分析

1.CG 方法调用图

1.1.Java中的方法调用类型

  • Static Call:调用静态方法 --> 编译时明确
  • Special Call:调用构造方法、私有方法、基类实例方法 --> 编译时明确
  • Virtual Call:调用其他实例方法 --> 运行时明确(多态,最常见)

所以在构建方法调用图时,最关键的是要处理好Virtual Call的情况

1.2.CG的构建方法

  • 类层级结构分析(Class Hierarchy Analysis,CHA)
  • 快速类型分析(Rapid Type Analysis,RTA)
  • 变量类型分析(Variable Type Analysis,VTA)
  • 指针分析(Pointer Analysis,k-CFA)

上面的四种方法自上而下精度(Precision)越来越高,但是效率(Efficiency)也越来越低。

本文只关注CHA的方式:

CHA

在方法调用点处,只关注caller的声明类型T及callee的方法签名sig,会把T及其子类中所有与sig匹配的方法都视为可能的目标方法,示例:

class A {
    void foo() { ... }
}

class B extends A { }

class C extends B {
    void foo() { ... }
}

class D extends B {
    void foo() { ... }
}

类层级结构如下:

现有以下代码片段:

void resolve() {
    C c = ...;
    c.foo();A a = ...;
    a.foo();B b = new B();
    b.foo();
}

CHA算法会对于每一个接收变量的声明类型本身及其子类关于调用点处的函数签名进行方法派发的操作,将所有找到的目标方法加入结果之中。因此,结果如下:

  • Resolve(c.foo()) = {C.foo()}
  • Resolve(a.foo()) = {A.foo(), C.foo(), D.foo()}
  • Resolve(b.foo()) = {A.foo(), C.foo(), D.foo()}

我们需要注意一下的是第三个调用点, A.foo() 也在其结果之内,因为对于 B 类本身的方法派发得到的结果是 A.foo()

并且,CHA的Resolve算法只关心声明类型,因此 new B() 其实并没有在算法中发挥作用,从而我们 Resolve(b.foo()) 产生了两个虚假(Spurious)的目标调用 C.foo()D.foo()

CG构建示例:

class A {
    static void main() {
        A.foo();
    }

    static void foo() {
        A a = new A();
        a.bar();
    }

    void bar() {
        C c = new C();
        c.bar();
    }
}

class B extends A {
    void bar() { }
}

class C extends A {
    void bar() {
        if (...) {
            A.foo();
        }
    }
    
    void m() { }
}

CHA最终构建的CG如下:

在上述例子当中需要注意的是,虽然 A a = new A() ,但是解析 a.bar() 的目标方法时候,依旧会对 A 以及 A 的所有子类作 Dispatch ,故而会有3条从 a.bar() 出发的边

最后我们会发现存在一个不可达的方法(Unreachable Method) C.m() ,那么这个方法中的代码就是死代码(Dead Code,即在任何情况下控制流都不能到达的代码)。

CHA的应用:IDE中的目标方法提示

2.ICFG 过程间控制流图

2.1.ICFG的构建

ICFG要在CFG基础上添加call Edges(调用边)、return Edges(返回边)

ICFG = CFGs + call & return edges ,连接调用边和返回边的信息可以从调用图中获得。因此,过程间控制流图的精度取决于调用图的精度。

示例:

static void main() {
    int a, b, c;
    a = 6;
    b = addOne(a);
    c = b - 3;
    b = ten();
    c = a * b;
}

static int addOne() {
    int y = x + 1;
    return y;
}

static int ten() {
    return 10;
}

构建的ICFG如下:

从上图可以看出,在构建ICFG时,仍然保留了Call-to-return edges(调用点到返回点的边),虽然实际程序运行过程不会走这条边,但是这条边可以传递callee方法不需要的数据,这样就避免了在目标方法中始终维护其不需要的数据,可以提高效率

公主号推荐

id:CodeAnalyzer,名称:CodeAnalyzer Ultra

开源仓库推荐

https://github.com/HaHarden/CPGPractise

标签:SAST,调用,...,void,分析方法,数据流,foo,方法
From: https://www.cnblogs.com/gxl98/p/18121880

相关文章

  • 软考 - 系统架构设计师 - 数据流图案例题
    阅读以下关于系统数据分析与建模的叙述,在答题纸上回答问题1至问题3。【说明】        某公司正在研发一套新的库存管理系统。系统中一个关键事件是接收供应商供货。项目组系统分析员小王花了大量时间在仓库观察了整个事件的处理过程,并开发出该过程所执行活动的列表:......
  • 验收测试E2E分析方法
    推荐阅读方式默认查看图片方式比较模糊,可以鼠标右键点击图片,采用在新标签页打开,此时可以查看高清大图;前言对于验收测试工程师来说,编写验收测试分析和测试用例是一项必须且重要的工作内容,但大多数同学在做验收测试分析及用例编写时,仍旧陷入到传统的分析及用例编写思维中,与内部......
  • 分析方法案例
    https://boardmix.cn/app/share/CAE.CPCQwQwgASoQYfH6G5uMEQpJtTjgmX-1qTAFQAE/vvi2eu,1.正太分布检验拿到数据之后,先看数据是否满足正态分布2.统计分析描述性分析:集中趋势的度量:这些度量描述了数据的中心点或典型值,包括均值(平均数)、中位数和众数。均值是所有观......
  • 齿轮系统故障跟踪:一种基于现场测量的传递路径分析方法(Matlab代码实现)
     ......
  • C# 数据流 FileStream
    //StreamMSHelpManual:https://learn.microsoft.com/zh-cn/dotnet/api/system.io.stream?view=net-8.0//FileStream官方手册:https://learn.microsoft.com/zh-cn/dotnet/api/system.io.filestream?view=net-8.0//StreamWriter:https://learn.microsoft.com/zh-cn/dotne......
  • 如何打破SAST代码审计工具的局限性?
    关键词:白盒测试;代码分析工具;代码扫描工具;静态代码检测工具;在代码的世界里,安全问题如同潜伏的暗礁,随时可能让航行中的软件项目触礁沉没。SAST代码审计工具如同雷达一样,以其独特的检测能力帮助开发者在代码层面进行深度扫描,识别并定位出潜在的安全漏洞。然而,即便是如此强大......
  • vue-pdf 预览pdf (数据流)
         页面有个要预览pdf的需求,数据是从后台传递过来的数据流:1.安装插件:npminstallvue-pdf2.在页面引用:importpdffrom'vue-pdf'...components:{pdf},3.html中添加:<pdf:src="pdfUrl"></pdf>4.通过接口获取数据:downloadFile({id:this.id}).t......
  • 获取Wireshark数据流
    背景:由于业务需要,需要接入一个第三方的设备,并在现场完成了数据抓包。实现一个全新的协议,但是没有设备。为了测试协议的正确性,需要把wireshark抓取数据的二进制进行回放。本文主要是把这些数据流提取成一个文件,并读取到内存中进行解析。 操作方法:根据端口和地址过滤数据包......
  • 需求分析方法论
    按照需求分析流程,我把需求分析方法论,分为三个阶段,分别是:收集需求阶段,评估需求阶段,精炼需求阶段。收集需求:尽可能全面的收集需求,不管需求能不能实现,这个阶段不要去考虑能不能实现的问题,务必要做到三个全面,即人员全面,结构全面,工具全面,后面逐一展开讲这三个全面是什么意思。评估需......
  • 数据流(Data Streams)
    一、简介在C#中,数据流(DataStreams)是一种用于读取和写入数据的抽象概念。数据流通常用于处理文件、网络通信、内存中的数据等场景。C#提供了多种数据流类来支持不同类型的数据读写操作。二、Stream(流)(一)简介在C#中,Stream是一个抽象类,用于提供对数据的读取和写入操作。它定......