Static Program Analysis

Introduction

1674379890829.png

为什么我们需要静态分析?

  • 程序可靠性——空指针引用、内存泄漏等

  • 程序安全性——敏感信息泄漏、注入攻击等

  • 编译优化——死代码、代码移动(code motion把一种需要执行多次但计算结果不会改变的计算移到前面)

  • 程序理解——IDE调用层次结构、类型指示等

1674381309785.png

但根据莱斯定理来看,不存在这样一个方法来精准判断一个程序是否满足以上性质。

1674381641229.png

虽然我们没办法准确的得到Truth,但我们可以得到Sound和Complete,往往我们选择Sound,有误报,但至少包含了全部Truth

1674381949823.png

上面这个例子可以得出两个Sound的结论,第一个结论更为精确,但他需要为此耗费更多资源。当分析复杂程序的时候,就应该在分析精度分析速度之间进行良好的平衡

抽象化(很好理解,把具体的东西给抽象化)

1674382632341.png

超近似(我的理解是: 把抽象的东西,尽可能的还原成真实情况)

抽象化和转换函数案例

1674383271552.png

后续的运算都是将x和y抽象后的值带入计算。这里其实已经发现1个除零操作和2个数组索引是负数的情况

c&p:Static analysis is useful

q: (over-approximated)Static analysis produces false positives(误报)

1674383817062.png

Intermediate Representation

Compilers and Static Analyzers

1674465667079.png

编译过程:首先对源码进行词法分析,然后进行语法分析,然后经过语意分析后转化为IR(3AC),最后生成机器码。静态分析在IR层面上进行分析。

简单的IR例子

1674466185560.png

Data Flow Analysis

Interprocedural Analysis