程序静态分析

程序静态分析(program static analysis)是指在不运行代码的方式下,通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。(百度百科

静态分析中的xxx-sensitive的一些理解:

(此内容来自知乎)

xxx-sensitive是指静态分析中用于降低误报(false positive)的技术。存在flow-、path-、context-。

flow-insensitive:是把statements当作一个集合来看的,各个statement之间没有顺序,所以control flow statement(if、while)可以直接删除;flow-sensitive是说要关注statements之间的先后顺序。

path-insensitive:if、while静态分析时不知道动态的执行路线(path),所以一般会把它们不同的分支的数据流集merge起来。而path-sensitive则针对不同的路径的数据集不会merge,而是分别进行分析;

context-insensitve:只关心function之间的数据传递(参数、返回值、side-effect)而忽略了同一函数在不同call side下不同的context,即忽略了call stack。将call site和return当作goto,并添加一些赋值语句,这样造成的情况是,第一个call site处正常,第二个call site时返回值可能出现两个。

静态分析时,无论是分析源代码还是目标代码,分析的对象(方法、语句、变量)都只有一份:同一个方法我们只会写一个方法体(方法体里的语句也就只有一份)。同一个变量只会声明一次。然后动态运行程序的时候:

一个方法可能会被调用N次,每次调用的上下文可以不一样,不同上下文中这个方法里的变量的值会不同;一个方法里,一个变量的不同位置的值也会不一样;一个方法里同一个位置的变量的值在程序执行不同路径时也不一样。写的方法、语句、变量在动态运行时仿佛有了“分身”,每个分身都有自己的值。静态分析的时候对于同一个对象只能看到一个实体,如果直接分析,一个变量所有“分身”的相关属性会全部合并,并且一个变量的属性合并了,会影响其他变量的分析结果。

静态分析为得到准确的结果,就得为分析的对象模拟动态运行时的分身。

xxx-sensitive就是在静态分析时,按照xxx给程序里的对象(模拟动态运行)创建“分身”(或者说按照xxx区分分析对象):按照上下文区分叫作context-sensitive;按照位置区分叫作flow-sensitive;按照路径区分叫作path-sensitive。区分之后就可以减少false positive。

数据流分析

(此内容来自龙书)

数据流分析:指的是一组用来获取有关数据如何沿着程序执行路径(control-flow graph)流动的相关信息的技术。

在所有的数据流分析应用中,我们都会把每个程序点和一个数据流(data-flow value)关联起来。这个值是在该点可能观察到的所有程序状态的集合的抽象表示。所有可能的数据流值的集合称为这个数据流应用的域(domain)。

我们把每个语句s之前和之后的数据流值分别记为IN[s]和OUT[s]。数据流问题(data-flow problem)就是要对一组约束求解。这组约束对所有的语句s限定了IN[s]和OUT[s]之间的关系。约束分为两种:基于语句语义(传递函数)的约束和基于控制流的约束。

数据流分析一般分为:intra-procedural analysis和inter-proceduralanalysis,在上篇Phase中提到,jtp pack和wjtp pack可以分别被用来实现自定义的数据流分析

实现数据流分析前需要搞清楚的问题

数据流的方向(前向、后向);交汇运算采用交集还是并集(当path-insenstitive时);传递函数;数据流集合的初始化。

采用soot框架实现过程内数据流分析

(此部分内容参考点击打开链接)

1.      过程内数据流分析

过程内数据流分析(intra-proceduraldata-flow analysis)指在一个单独方法的控制流图上操作。在soot中的控制流图为UnitGraph。UnitGraph中节点表示statements,如果在控制流上一个表示source node流向target node,那么这两个结点存在边(edge)。

数据流分析都与unitgraph每个节点上的两个元素有关,这两个集合被称为:in-set和out-set。这些集合会被初始化,然后沿着语句节点传播,指导一个定点抵达才停止。

最后,你要做的就是检查每个句子的前后的flow set。通过设计的数据流分析,你的flow sets应该会直接告诉你所需要的信息。

2.      Forward、backward orbranched(解决数据流的方向问题)?

在soot中FlowAnalysis存在三种不同类型的方法:

ForwardFlowAnalysis:这个分析以UnitGraph的entrystatement作为开始并开始传播;

BackwardsFlowAnalysis:这个分析以UnitGraph的exit node(s)作为分析并且向后开始传播(当然可以将UnitGraph转换产生inverseGraph,然后再使用ForwardFlowAnalysis进行分析);

ForwardBranchedFlowAnalysis:这个分析本质上也是Forward分析,但是它允许你在不同分支处传递不同的flow sets。例如:如果传播到如if(p!=null)语句处,当“p is not null”时,传播进入“then”分支,当“p is null”时传播进入“else”分支(Forward、backward分析都在分支处会将分析结果merge)。

3.      实现过程间数据流分析的关键方法

Constructor

必须实现一个携带DirectedGraph作为参数的构造函数,并且将该参数传递给super constructor。然后,在构造函数结束时调用doAnalysis(),doAnalysis()将真正执行数据流分析。而在调用super constructor和doAnalysis之间,可以自定义数据分析结构。

<span style="font-size:14px;">public MyAnalysis(DirectedGraph graph) { //构造函数super(graph);// TODO Auto-generated constructor stubemptySet = new ArraySparseSet();doAnalysis();//执行fixed-point
}</span>

newInitialFlow()和entryInitialFlow()(数据流集合的初始化问题

newInitialFlow()方法返回一个对象,这个对象被赋值给每个语句的in-set和out-set集合,除过UnitGraph的第一个句子的in-set集合(如果你实现的是backwards分析,则是一个exit statement语句)。第一个句子的in-set集合由entryInitialFlow()初始化。

<span style="font-size:14px;">@Override
protected Object newInitialFlow() {// TODO Auto-generated method stubreturn emptySet.emptySet();
}@Override
protected Object entryInitialFlow() {// TODO Auto-generated method stubreturn emptySet.emptySet();
}</span>

copy(..)

copy(..)方法携带两个参数,一个source和一个target。它仅仅实现将source中的元素拷贝到target中。

<span style="font-size:14px;">@Override
protected void copy(Object source, Object dest) {// TODO Auto-generated method stubFlowSet srcSet = (FlowSet)source,destSet = (FlowSet)dest;srcSet.copy(destSet);
}</span>

merge(..)(数据流的交汇运算问题

merge(..)方法被用来在control-flow的合并点处合并数据流集,例如:在句子(if/then/else)分支的结束点。与copy(..)不同的是,它携带了三个参数,一个参数是来自左边分支的out-set,一个参数是来自右边分支的out-set,另外一个参数是两个参数merge后的集合,这个集合将是合并点的下一个句子的in-set集合。

注:merge(..)本质上指的是控制流的交汇运算,一般根据待分析的具体问题来决定采用并集还是交集。

<span style="font-size:14px;">@Override
protected void merge(Object in1, Object in2, Object out) {// TODO Auto-generated method stubFlowSet inSet1 = (FlowSet)in1,inSet2 = (FlowSet)in2,outSet = (FlowSet)out;//inSet1.union(inSet2, outSet);inSet1.intersection(inSet2, outSet);
}</span>

flowThrough(..)(数据流的传递函数问题

flowThrough(..)方法是真正执行流函数,它有三个参数:in-set、被处理的节点(一般指的就是句子Unit)、out-set。这个方法的实现内容完全取决于你的分析。

注:flowThrough()本质上就是一个传递函数。在一个语句之前和之后的数据流值受该语句的语义的约束。比如,假设我们的数据流分析涉及确定各个程序点上各变量的常量值。如果变量a在执行语句b=a之前的值为v,那么在该语句之后a和b的值都是v。一个赋值语句之前和之后的数据流值的关系被称为传递函数。针对前向分析和后向分析,传递函数有两种风格。

<span style="font-size:14px;">@Override
protected void flowThrough(Object in, Object d, Object out) {// TODO Auto-generated method stubFlowSet inSet = (FlowSet)in,outSet = (FlowSet)out;Unit u = (Unit) d;kill(inSet,u,outSet);gen(outSet,u);
}private void kill(FlowSet inSet, Unit u, FlowSet outSet) {// TODO Auto-generated method stubFlowSet kills = (FlowSet)emptySet.clone();//Unit的killsIterator defIt = u.getDefBoxes().iterator();while(defIt.hasNext()){ValueBox defBox = (ValueBox)defIt.next();if(defBox.getValue() instanceof Local){Iterator inIt = inSet.iterator();while(inIt.hasNext()){Local inValue = (Local)inIt.next();if(inValue.equivTo(defBox.getValue())){kills.add(defBox.getValue());}}<span style="white-space:pre">  </span>}}inSet.difference(kills, outSet);
}private void gen(FlowSet outSet, Unit u) {// TODO Auto-generated method stubIterator useIt = u.getUseBoxes().iterator();while(useIt.hasNext()){ValueBox e = (ValueBox)useIt.next();if(e.getValue() instanceof Local)outSet.add(e.getValue());}
}</span>

Flow sets

(此部分内容参考点击打开链接)

在soot中,flow sets代表control-flowgraph中与节点相关的数据集合。Flow set存在有界限的(interface BoundedFlowSet)和无界限的(interfaceFlowSet)两种表达。有界限的集合知道可能值的全体集合,而无界限的集合则不知道。

Interface FlowSet<T>提供的关键方法有

<span style="font-size:14px;">FlowSet<T> clone() //克隆当前FlowSet的集合
FlowSet<T> emptySet() //返回一个空集,通常比((FlowSet)clone()).clear()效率更高
void copy(FlowSet<T> dest) //拷贝当前集合到dest集合中
void union(FlowSet<T> other) //FlowSet∪other = FlowSet
void union(FlowSet<T> other,FlowSet<T> dest) // FlowSet∪other = dest,其中other、dest可以与该FlowSet一样
void intersection(FlowSet<T> other) //FlowSet∩other = FlowSet
void intersection(FlowSet<T> other,FlowSet<T> dest) // FlowSet∩other = FlowSet,其中,dest、other可以和该FlowSet一样
void difference(FlowSet<T> other) // FlowSet-other = FlowSet
void difference(FlowSet<T> other,FlowSet<T> dest) // FlowSet-other = dest,其中,dest、other和FlowSet可能相同。
</span>

还有isEmpty()、size()、add(T obj)、remove(T obj)、contains(Tobj)、isSubSet(FlowSet<T> other)、iterator()、toList()等。

上述方法足以使flow sets成为一个有效的lattice元素。

当实现BoundedFlowSet时,它需要提供方法,该方法能够产生set‘s complement和its topped set(一个lattice element包括所有的可能的值的集合)。

Soot提供了四种flow sets的实现:ArraySparseSet,ArrayPackedSet,ToppedSet和DavaFlowSet。

ArraySparseSet:是一个无界限的flowset。该set代表一个数组引用。注意:当比较元素是否相等时,一般使用继承自Object对象的equals。但是在soot中的元素都是代表一些代码结构,不能覆写equals方法。而是实现了interface soot.EquivTo。因此,如果你需要一个包含类似binary operation expressions的集合,你需要使用equivTo方法实现自定义的比较方法去比较是否相等

针对intra-procedural analysis,本人实现了一个活跃变量的代码

import java.util.Iterator;import soot.Local;
import soot.Unit;
import soot.ValueBox;
import soot.toolkits.graph.DirectedGraph;
import soot.toolkits.scalar.ArraySparseSet;
import soot.toolkits.scalar.BackwardFlowAnalysis;
import soot.toolkits.scalar.FlowSet;class MyAnalysis extends BackwardFlowAnalysis{private FlowSet emptySet;public MyAnalysis(DirectedGraph graph) { //构造函数super(graph);// TODO Auto-generated constructor stubemptySet = new ArraySparseSet();doAnalysis();//执行fixed-point}@Overrideprotected void flowThrough(Object in, Object d, Object out) {// TODO Auto-generated method stubFlowSet inSet = (FlowSet)in,outSet = (FlowSet)out;Unit u = (Unit) d;kill(inSet,u,outSet);gen(outSet,u);}private void kill(FlowSet inSet, Unit u, FlowSet outSet) {// TODO Auto-generated method stubFlowSet kills = (FlowSet)emptySet.clone();//Unit的killsIterator defIt = u.getDefBoxes().iterator();while(defIt.hasNext()){ValueBox defBox = (ValueBox)defIt.next();if(defBox.getValue() instanceof Local){Iterator inIt = inSet.iterator();while(inIt.hasNext()){Local inValue = (Local)inIt.next();if(inValue.equivTo(defBox.getValue())){kills.add(defBox.getValue());}}}}inSet.difference(kills, outSet);}private void gen(FlowSet outSet, Unit u) {// TODO Auto-generated method stubIterator useIt = u.getUseBoxes().iterator();while(useIt.hasNext()){ValueBox e = (ValueBox)useIt.next();if(e.getValue() instanceof Local)outSet.add(e.getValue());}}@Overrideprotected Object newInitialFlow() {// TODO Auto-generated method stubreturn emptySet.emptySet();}@Overrideprotected Object entryInitialFlow() {// TODO Auto-generated method stubreturn emptySet.emptySet();}@Overrideprotected void merge(Object in1, Object in2, Object out) {// TODO Auto-generated method stubFlowSet inSet1 = (FlowSet)in1,inSet2 = (FlowSet)in2,outSet = (FlowSet)out;//inSet1.union(inSet2, outSet);inSet1.intersection(inSet2, outSet);}@Overrideprotected void copy(Object source, Object dest) {// TODO Auto-generated method stubFlowSet srcSet = (FlowSet)source,destSet = (FlowSet)dest;srcSet.copy(destSet);}}

基于soot的过程内数据流分析相关推荐

  1. soot数据流 -- 基于soot的过程内数据流分析

    原文出处 程序静态分析 程序静态分析(program static analysis)是指在不运行代码的方式下,通过词法分析.语法分析.控制流.数据流分析等技术对程序代码进行扫描,验证代码是否满足规范 ...

  2. 基于单片机的车内滞留儿童预警系统设计

     word完整版可点击如下下载>>>>>>>> 基于单片机的车内滞留儿童预警系统设计-嵌入式文档类资源-CSDN下载内容包括详细设计文档word版,附带 ...

  3. VCIP2020:不同尺寸块基于神经网络的帧内预测

    本文来自VCIP2020论文<Fully Neural Network Mode Based Intra Prediction of Variable Block Size> 论文提出使用 ...

  4. 《基于物联网的车内安防系统项目需求说明书+系统概要说明+系统详细说明》

    转载自:https://www.cnblogs.com/duibd/p/4893235.html ①需求说明书部分: 一.引言 1.编写目的 该需求说明书是"基于物联网的车内安防系统&quo ...

  5. ICASSP2020:VVC基于线性模型的帧内预测模式

    本文来自ICASSP2020论文<LINEAR MODEL-BASED INTRA PREDICTION IN VVC TEST MODEL> 论文使用含3个参数的线性模型进行帧内预测 L ...

  6. 基于Docker的frp内网穿透

    基于Docker的frp内网穿透 内网穿透 定义 内网穿透,也即 NAT 穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机. U ...

  7. 一个基于.Net高性能跨平台内网穿透工具

    作为一名程序员,我们平常需要调试远程API(如公众号回调).远程操作公司内部.家里的电脑,我们都会用到内网穿透的工具. 今天给大家推荐一个高性能跨平台内网穿透工具的开源项目. 项目简介 一个基于.Ne ...

  8. matlab换挡程序,一种基于MATLAB换挡过程中快速锁定分析数据的方法与流程

    本发明涉及汽车变速器数据分析,特别的,涉及一种基于matlab换挡过程中快速锁定分析数据的方法. 背景技术: 自动变速器的核心功能是能根据驾驶员意图进行自动换挡,解放驾驶员的左脚:在自动变速器的使用过 ...

  9. 一个很简单的基于栈式过程虚拟机的实现,它运行目标平台【x86】的原生代码。

    本文提供的 "栈式过程虚拟机" 的实现,挂在本人的 github 上面,对想要深入了解 "栈式过程虚拟机" 的人,它或许可以起到一个不错的作用,但是本人建议一般 ...

  10. matlab fni,一种基于MATLAB的车内语言清晰度自动计算方法与流程

    本发明涉及汽车nvh性能技术领域,具体为一种基于matlab的车内语言清晰度自动计算方法. 背景技术: 汽车行业中,语言清晰度(ai,articulationindex)常用于衡量车内噪声存在时,驾乘 ...

最新文章

  1. 经1503 20151453 张开拓
  2. 爱情这东西,真的有报应吗…
  3. [转]C++函数模板与模板函数
  4. axis的对象交由spring管理的配置
  5. Spring 3.x MVC 图解MVC整体流程
  6. CentOS7安装MySQL8.0图文教程
  7. sql查询字段的值不为空
  8. windowsCE异常和中断服务程序初探(-)
  9. 操作系统ppt_华为车BU王军:华为三大汽车操作系统,及跨域集成软件框架(内含PPT)...
  10. 庆祝喜提13337000编号,我悄悄把老板的Windows命令行设置成了这样
  11. 资金流学习 - 关注点
  12. 网络知识:光猫光纤宽带故障排查笔记!
  13. 倒闭跑路的P2P网贷平台的特征
  14. 今日头条信息流 - 橙子建站
  15. c语言程序设计精髓第六章编程题
  16. 【Python数据分析学习实例】计算某个函数的一阶导数、二阶导数,并绘出图像
  17. mysql程序选项有两种通用形式:长选项和短选项_MySQL程序概述
  18. python实操实例100例_趣学Python算法100例
  19. 【真相】网易暴力裁员事件 企业暴力开除重病员工事件绝非孤例
  20. OpenSSL SSL_read: Connection was reset, errno 10054

热门文章

  1. 脉冲云中使用的ajv
  2. linux 电驴,开源电驴 MLDonkey 3.0.7 发布
  3. 根据pc值确定出错的代码位置
  4. OpenChannelSSD之六_从OpenChannelSSD到ZNS
  5. 论文学习——基于滑动窗口预测的水位时间序列异常检测
  6. 文字转语音软件免费的哪个最好用:快试试最像人声的微软语音合成助手吧,本地版微软语音合成工具下载
  7. Spring之IOC概念、Bean对象创建及DI注入的三种方式
  8. 树莓派各类显示屏体验
  9. 买不起流量,那1.7亿日活的小程序可以拯救创业者吗?
  10. Linux内核info leak漏洞