南大静态分析-2

课程链接

0x01 Compilers and Static Analyzers

编译器工作原理, 开始贴ppt:

截屏2020-05-04 下午8.53.05

IR之前前端, 之后称后端。 前端是词法、语法、简单的语义检查。 后端是在IR上分析一些高级的程序属性。(其实我觉得编译过程任何一个阶段的输出表示,都可以叫做IR(中间表示),一般IR指的是编译后段处理的目标内容形式,一般用3AC(三地址码)表示)。

0x02 AST vs. IR

重点来了, AST 和 IR做为编译过程中两个重要的中间表示,各自有什么意义与区别呢? 我们继续贴ppt...

截屏2020-05-04 下午8.58.04

这里提出了几点:

AST 贴合于上层代码,依赖于语言。 而IR贴近于底层,不依赖语言。 (多种语言可以翻译成同一种3AC?)。还有一个重要特点就是AST缺少控制流信息, 而3AC包含了控制流信息。

Each 4AC contains at most 3 addresses

  • Name: a, b
  • Constant: 3
  • Compiler-generated temporary: t1, t2

常见3AC(三地址码)形式

  • x = y bop z

  • x = top y

  • x = y

  • goto L

  • if x got L

  • if x rop y goto L

其中, x, y, z表示地址。 bop是二元运算符或逻辑运算符; uop 是一元操作符;L是地址的label; rop 关系操作符。 goto L 无条件跳转; if...goto L:条件跳转。

soot介绍略...

0x03 Static Single Assignment(SSA)

  • Give each definition a fresh name
  • Propagate fresh name to subsequent use
  • Ever variable has exactly one definition

截屏2020-05-04 下午9.16.05

截屏2020-05-04 下午9.17.15

每一个variable在不同语句都给一个地址, 在control flow 汇合处就是这个变量的集合。

0x04 Control Flow Analysis

重点来了...

之前构造了3AC,那么在后端中需要在此之上构建控制流图进行控制流分析。 控制流图中, 每一个节点为一个基本快。

Basic Blokcs(BB)

截屏2020-05-04 下午9.21.28

一个基本块应该满足,唯一一个入口进,唯一一个出口出。

入口必须是第一条指令, 而出口必须是最后一条, 这样最大的块就是一个BB。

构建basic block

按视频给出的算法:

首先,标出跳转语句的目标

截屏2020-05-04 下午9.32.58

之后,标出紧接着jump之后的指令

截屏2020-05-04 下午9.34.26

找到了所有的leaders之后,构造基本块。

截屏2020-05-04 下午9.36.17

有了基本块, 建立控制流的边。

构建Control Flow Graph(CFG)

  1. There is a conditional or unconditional jump from the end of A to the beginning of B(跳转添边)

  2. B immediately follows A in the original order of instructions(依序添边) and A does not end in an unconditional jump(且A块出口并没有无条件跳转)

截屏2020-05-04 下午9.43.32

  1. It is normal to replace the jumps to instruction labels by jumps to basic blocks(很自然的将指令跳转转化为basic block 跳转)

截屏2020-05-04 下午9.47.18

(这里将goto 目标都换成了基本块label)

截屏2020-05-04 下午9.49.11

加上了CFG的入口和出口,形成一个完整的CFG。

说明:

  • 红边有条件跳转, 蓝边无条件
  • 黑边顺序执行,除无条件goto外都加
  • A是B的前驱, B是A的后继
  • 入口节点加入第一个,指向第一条执行的指令

算法

image-20211111072257404