南京大学 静态软件分析(static program analyzes)-- introduction 学习笔记
一、Programming Languages体系

静态程序分析是编程语言中应用层面下的一个细分领域,它是一个非常重要的核心内容。
- 在理论部分,考虑的是如何设计一个语言的语法和语义,如何设计语言的类型系统等等问题。在过去十年中,语言核心几乎没有变化
- 有了语言的语法、语义和类型系统之后,我们需要支撑语言的运行。因此,在环境部分,需要考虑如何为运行中的程序提供运行时环境——如何设计编译器,在运行时需要怎样的支持(如内存的分配管理)等等。语言承载环境处于一个缓慢提升的阶段,主要集中在硬件设备以及高性能编程优化方面
- 变化最大的是程序分析,因为随着IT、云计算、软件SaaS的快速发展,软件的规模变得更大、结构更复杂、数量更多。如何确保系统的可靠性、安全性和其他承诺,如何自动合成一个程度,成为了一个日趋热门的研究和工程化领域
二、Static Analysis定义
Static analysis analyzes a program P to reason about its behaviors and determines whether it satisfies some properties before running P.
- Does P contain any private information leaks?
- Does P dereference any null pointers?
- Are all the cast operations in P safe?
- Can v1 and v2 in P point to the same memory location?
- Will certain assert statements in P fail?
- Is this piece of code in P dead (so that it could be eliminated)?
- …

上图中的两种答案在静态分析语义中都是对的,他们分别代表了两种求解方式:
- 分支穷举:耗时,但是精确
- 符号执行:快速,但是不那么精确
Static Analysis: ensure (or get close to) soundness, while making good trade-offs between analysis precision and analysis speed.
Two Words to Conclude Static Analysis:
Static Analysis = Abstraction + Over-approximation
举一个具体的例子:通过静态分析,判断一段PHP代码是否能存在外部任意参数执行风险,即是否是Webshell。要完成这个静态分析过程,需要进行如下处理:
- Abstraction
- Over-approximation
- Transfer functions
- Control flows
原始代码如下:
<?php
v1 = 1;
v2 = 2;
v3 = $_POST[1];
v4 = $_POST[2];
v5 = v3 == 1 ? v3 : 5;
$$_POST[3] = $_POST[4]; // $_POST[4] = v6 if(v3 == 1){
eval(v5);
}
echo "hello world";
?>
我们先来看Abstraction抽象,

通俗地理解Abstraction抽象,就是将程序从原始的、高维的源代码空间,映射到一个抽象的、低维的符号空间。符号化后,后续的优化、分析、处理都会更加方便。
接下来看Over-approximation: Transfer Functions转化函数,
- In static analysis, transfer functions define how to evaluate different program statements on abstract values.
- Transfer functions are defined according to “analysis problem” and the “semantics” of different program statements.
转化函数定义了抽象符号的运算结果,需要注意的是,转换函数和具体的语义和待分析问题有关.

需要注意的是,因为在Abstraction抽象过程中进行了值域空间的降维抽象,所以在转换函数映射中,静态符号执行和动态实际实行的结果之间,是存在差异的,这是不可避免的。

接下来看Over-approximation: Control Flows控制流,

As it’s impossible to enumerate all paths in practice, flow merging (as a way of over-approximation) is taken for granted in most static analyses.
在静态分析中,分支流合并是常用的分支推断技术,提升了Soundness的同时,也导致Completeness的下降,从而导致了不可避免的误报问题。
三、Why we need Static Analysis
- 近年来,程序复杂度越来越高,可靠性和安全性越来越难保证
- Null pointer dereference, memory leak, etc.
- 空指针引用与内存泄漏等:几乎每个程序编写者都被这两个问题所困扰过
- 对程序可靠性、安全性进行分析
- Private information leak, injection attack, etc.
- 隐私信息泄漏:这一问题在移动应用中较为普遍
- 注入攻击:这是网络安全中非常常见的议题
- 为编译优化提供基础技术
- Dead code elimination, code motion, etc.
- 死代码消除:在编译器的机器无关优化环节,将不会对程序执行结果产生影响的代码(即死代码)删除。
- 循环不变量的代码移动:在编译器的机器无关优化环节,在保证不影响程序执行结果的情况下,将循环中的特定语句移动到循环外,使得程序运行时执行的语句数减少。更为详细的解释可以参考StackOverFlow上的回答。
- 程序理解(调用栈、自动补全等)
- IDE call hierarchy, type indication, etc.
- 为集成开发环境的功能提供帮助:当你使用VS/Idea/Clion/Eclipse/Android Studio等等IDE时,将鼠标悬停在代码上,IDE能够动态地分析并提示你所悬停对象的相关信息,背后使用的技术就是静态程序分析。
- 更深入地理解编程语言的语法语义
- 自然地写出更可靠、安全、高效的程序
四、Rice’s Theorem -- 静态分析的局限
Any non-trivial property of the behavior of programs in a r.e.(recursively enumerable) language is undecidable.”
non-trivial properties:
- ~= interesting properties
- ~= the properties related with run-time behaviors of programs


按照莱斯定律,「完美静态分析」有两个核心特征:
- Sound(完全覆盖)
- Complete(精确推断)

如果一段程序是“non-trivial”的,则不存在一个完美的静态分析程序,可以同时满足Sound和Complete特征。换到工业界的术语就是,误报和漏报无法同时达到100%。
在实际使用中,我们并不是追求「完美静态分析」,而是追求「有用的静态分析」,即满足如下两个核心特征:
- Compromise soundness (false negatives,折中地漏报控制)
- Compromise completeness (false positives,折中地误报控制)

在实际工业场景中,Soundness往往是优先追求的目标,我们以Webshell静态代码分析为例说明。

如果追求Sound的目标,在进行静态代码分析的时候,完整性/覆盖度/高检出往往是优先追求的目标。在另一方面,相对的误报就不可避免了。
五、静态程序分析与类似技术的对比
静态程序分析
- 优点:
- 在选定的精度下能够保证没有bug
- 缺点:
- 学术门槛相对高。目前已知国内高校公开的课程资料只有北京大学,南京大学,国防科大,吉林大学的,且通俗易懂的教材稀少。作为一门计算机专业的高年级选修课,入门和提高都较困难。
动态软件测试
- 优点:
- 在工程中被广泛应用,并且有效。实现简单,便于自动化。
- 缺点:
- 无法保证没有bug。 这是无法遍历所有可能的程序输入的必然结果。
- 在当今的由多核与网络应用带来的并发环境下作用有限。 某个bug可能只在特定情况下发生,因而难以稳定地复现。
形式化语义验证
- 优点:
- 由于用数学的方法对程序做了抽象,能够保证没有bug。
- 缺点:
- 学术门槛较高,学习者必须有良好的数学基础才能入门。
- 验证代价较高,一般来说非常重要的项目会使用这一方式保证程序质量。甚至在操作系统这样重要的软件中,也并不一定会使用。
南京大学 静态软件分析(static program analyzes)-- introduction 学习笔记的更多相关文章
- 《Linux内核分析》第七周学习笔记
<Linux内核分析>第七周学习笔记 可执行程序的装载 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...
- 《Linux内核分析》第六周学习笔记
<Linux内核分析>第六周学习笔记 进程的描述和创建 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...
- 《Linux内核分析》第三周学习笔记
<Linux内核分析>第三周学习笔记 构造一个简单的Linux系统MenuOS 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.stud ...
- 《Linux内核分析》第八周学习笔记
<Linux内核分析>第八周学习笔记 进程的切换和系统的一般执行过程 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163 ...
- 《Linux内核分析》第五周学习笔记
<Linux内核分析>第五周学习笔记 扒开系统调用的三层皮(下) 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.c ...
- 20179223《Linux内核原理与分析》第八周学习笔记
视频学习 可执行文件是怎么得来的? .c汇编成汇编代码.asm,然后再汇编成目标码.o.然后在连接成可执行文件,然后加载到内存可执行了. 对hello.c文件预处理(cpp),预处理负责把includ ...
- 第十七篇:实例分析(1)--初探WDDM驱动学习笔记(八)
第四篇(VidPN)中提到过MIRROR驱动. 在进入本篇的实际内容前, 带着好奇心, 想请教CSDN中的显卡驱动方面的大虾, 怎样才干把这个驱动玩起来, 这个驱动的作用是什么,等等, 敬请不吝赐教. ...
- 20179223《Linux内核原理与分析》第十一周学习笔记
缓冲区溢出漏洞实验 一.实验简介 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和 ...
- 20179223《Linux内核原理与分析》第五周学习笔记
视频内容知识学习 一.用户态.内核态和中断 1.内核态:处于高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态 2.用户态:处于低的执行级别下,代码只能在级别允许的特定 ...
随机推荐
- C++五子棋(三)——判断鼠标有效点击
分析 在鼠标左键点击时,我们不能让新棋子在已有棋子的位置落下,同时我们还要让棋子在规定位置落下--棋盘线的交点处. 功能实现 创建数据类型 创建头文件chessData.h和源文件chessData. ...
- Logistic regression中regularization失败的解决方法探索(文末附解决后code)
在matlab中做Regularized logistic regression 原理: 我的代码: function [J, grad] = costFunctionReg(theta, X, y, ...
- struts2绕过waf读写文件及另类方式执行命令
之前碰到过好几次Struts2,还都是016,项目.众测都遇到过,每次都只是证明了一下存在,由于waf的存在,没有深入去利用,这里简单的记录下. 0x01 背景 xray或者Struts2漏扫可以扫到 ...
- js字符串操作方法集合
1.字符方法: str.charAt(): 可以访问字符串中特定的字符,可以接受0至字符串长度-1的数字作为参数,返回该位置下的字符,如果参数超出该范围,返回空字符串,如果没有参数,返回位置为0的字符 ...
- 【FAQ】接入HMS Core地图服务过程中常见问题总结
HMS Core地图服务(Map Kit)给开发者提供一套地图开发调用的SDK,助力全球开发者实现个性化地图呈现与交互,方便轻松地在应用中集成地图相关的功能,全方位提升用户体验. 在日常工作中,我们会 ...
- 【学习笔记】CDQ分治(等待填坑)
因为我对CDQ分治理解不深,所以这篇博客只是我现在的浅显理解有任何不对的,希望大佬指出. 首先就是CDQ分治适用的题型: (1)带修改,但修改互相独立 (2)必须允许离线 (3)解决数据结构的题,能把 ...
- XCTF练习题---MISC---give_you_flag
XCTF练习题---MISC---give_you_flag flag:flag{e7d478cf6b915f50ab1277f78502a2c5} 解题步骤: 1.观察题目,下载附件 2.打开发现是 ...
- [题解][YZOJ50104] 密码 | 简单计数
同步发表于 Mina! 题目大意 对于满足以下要求的长度为 \(n\) 的序列进行计数: 序列的值域为 \([1,k]\); 对于序列的任意位置 \(p\in[1,n]\),可以找到至少一个 \(i\ ...
- 使用Visual Studio 2022开发前端
前端开发环境多数基于Node.js,好处不多说了.但与使用Visual Studio开发的后端Asp.Net Core项目一起调试,却不是很方便,所以试着在Visual Studio 2022中开发前 ...
- 项目文章|DNA(羟)甲基化研究揭示铁离子依赖表观调控促进狼疮致病性T细胞分化|易基因
易基因(羟)甲基化DNA免疫共沉淀测序(h)MeDIP-seq研究成果见刊<Journal of Clinical Investigation> 2022年5月2日,中南大学湘雅二医院赵明 ...