南京大学《软件分析》笔记第二节

笔记参考

视频链接

1.编译器和静态分析器

1.1编译器

编译器将源代码(Source code) 转换为机器代码(Machine Code)。

1.词法分析器(Scanner),结合正则表达式,通过词法分析(Lexical Analysis)将 source code 翻译为 token。保证单词的正确性,字母的拼写和有意义。
2.语法分析器(Parser),结合上下文无关文法(Context-Free Grammar),通过语法分析(Syntax Analysis),将 token 解析为抽象语法树(Abstract Syntax Tree)。保证句子的语法正确,主谓宾定状补。其中,上下文不敏感准确性弱于敏感,但是已经足够,保证速度。
3.语义分析器(Type Checker),结合属性语法(Attribute Grammar),通过语义分析(Semantic Analysis),将 AST 解析为 decorated AST。在语义合不合理的层面进行分析。
4.转换器(Translator),将 decorated AST 翻译为三地址码这样的中间表示形式IR(Intermediate Representation),并基于 IR 做静态分析(例如代码优化、查漏洞工作)。
5.代码生成器(Code Generator),将 IR 转换为机器代码

不可以跳步,因为静态分析要做的是non-trivial的事情(代码优化),前面先做trivial的事情,静态分析要在IR上进行下一步分析。 

2.抽象语法树(AST) vs. 中间表示(IR)

2.1差别

  • 抽象语法树:高层,贴近语法结构;依赖于编程语言;适合做快速的类型检查;看不出来控制流信息,但是人比较方便读懂。
  • 中间表示:底层,贴近机器码;具有语言无关性;简洁而统一;包含控制流信息;通常作为静态分析的基础。程序语言的中间表达形式,去除了如注释等无关程序运行的部分,通用。

2.2 IR: Three-Address Code (3AC)

2.2.1定义

三地址码(3AC)是指每一条指令最多包含三个地址(Address)的代码,其右侧结构最多只能有一个操作符,同时这里的地址也不是内存中的地址,而是下面三种形式中的一种:

  • 变量:如a,b
  • 常量:如3
  • 编译器自动生成的临时变量:如t1,t2

范例如下: 

  • 将 t2 = a + b + 3转换成三地址码(3AC):
  • t1 = a + b
  • t2 = t1 + 3
2.2.2三地址码常见形式 

x = y bop z,        bop:二元运算符或者逻辑操作(+ - * /)
x = uop y,           uop:一元运算符(取负,取反,转换)
goto L,                L:程序位置标记
if x rop y goto L, rop:关系运算符 (<, >, ==, >=, <=等)
goto L:                无条件跳转
if x goto L,

if … goto L:           条件跳转

2.2.3 3AC in Real Static Analyzer: Soot 

Soot 是一个用于分析和优化 Java 字节码的框架,它提供了一系列强大的功能和工具,广泛应用于研究和工业界的程序分析、优化和安全性检查。Jimple 是 Soot 框架中提供的一种中间表示,专门设计用于简化和提高 Java 字节码的分析和优化效率,主要特点是将复杂的字节码指令简化为三地址码形式。

 DoWhileLoop3AC.java:

package nju.sa.examples;
 
public class DoWhileLoop3AC {
    public static void main(String[] args) {
        int[] arr = new int[10];
        int i = 0;
        do {
            i = i + 1;
        } while (arr[i] < 10);
    }
}

使用soot框架转化代码:

javac DoWhileLoop3AC.java
java -cp soot.jar soot.Main -cp . -pp -f jimple DoWhileLoop3AC

DoWhileLoop3AC.jimple:

public static void main(java.lang.String[])
{
    int[] r0;
    int $i0, i1;
    java.lang.String[] r1;
    r1 := @parameter0: java.lang.String[];
    r0 = newarray (int)[10];
    i1 = 0;
 label1:
    i1 = i1 + 1;
    $i0 = r0[i1];
    if $i0 < 10 goto label1;
    return;
}

java IR(Jimple)基本知识 

invokespecial:call constructor, call superclass methods, call private methods
invokevirtual: instance methods call (virtual dispatch)
invokeinterface: cannot optimization, checking interface implementation
invokestation:call static methods

Java 7: invokedynamic -> Java static typing, dynamic language runs on JVM

method signature: class name, return type, method name(parameter1 type, parameter2 type)

3.Static Single Assignment (SSA) 

3.1定义

静态单赋值(SSA)也是一种经典的IR,普通三地址码与静态单赋值形式最主要的区别就是SSA给每个变量都赋值一次,不会出现变量的重复赋值,每个变量都有一个定义。

3.1.1Φ函数

由于SSA的性质,为了保证每个变量拥有唯一定义且不会产生歧义,故引入了Φ函数(称为phi-function),在控制流交汇结点使用Φ函数进行聚合,比如Φ(x0,x1)会根据流的路径来选择是x2=x0或者x2=x1。

3.2优缺点

优点:

  • 控制流信息间接地集成到了独特变量名中,传递一些简单的分析信息,加快流不敏感分析的速度;
  • 定义与使用是显式的,能更精确地找到其定义的地方,此外一些优化算法在SSA上表现更好。

缺点:

  • 如果程序分叉太多,则引入了太多的变量和Φ函数;
  • 转换到机器码的过程会产生许多性能的问题。

4.Basic Blocks (BB) 

基本块(Basic Blocks),就是满足以下性质的,最大长度的连续三地址码单元:

  • 只可以把块的第一个指令作为入口,不能从其他地方进入。
  • 只可以把块的最后一条指令作为出口,不能从其他地方出去。

 4.1构建思路

INPUT:  三地址指令序列 P
OUTPUT:  P 的基本块列表
Method:
    (1) 确定 P 的入口 (leaders)

          P 的第一个指令是一个leader
          任何一个有条件或无条件跳转的目标指令,是一个leader
          任何一个有条件或无条件跳转的下一条指令,是一个leader
    (2) 建立P的基本块

           每个leader到下一个leader之间就是一个BB

5.Control Flow Graphs (CFG) 

5.1介绍

  • 三地址码最终是在控制流图(CFG) 上进行分析,通常要构建控制流图进行控制流分析。
  • CFG作为静态分析的基础架构。
  • CFG中的节点既可以是单个的3AC,也可以是Basic Blocks(BB)。

5.2添加边

  • 如果两个BB前后相连且无跳转,则加边
  • 如果从A无条件跳转B,则A到B加边
  • 如果从A有条件跳转到B,则加边

 

此外,将跳转的目标从指令代号改成基本块的名字。在CFG中若 A -> B,则我们说 A 是 B 的前驱(predecessor),B 是 A 的后继(successor)。

除了构建好的基本块,通常还会额外添加两个结点入口(Entry)和出口(Exit)便于初始化,最终控制流图就构建完毕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值