原文链接:https://github.com/Sable/soot/wiki/Implementing-an-intra-procedural-data-flow-analysis-in-Soot
过程内数据流分析是什么
向前、向后还是分支
Soot中三种FlowAnalysis的实现:
- ForwardFlowAnalysis:从UnitGraph入口点开始并向前发展
- BackwardsFlowAnalysis:从出口点开始并向后发展
- ForwardBranchedFlowAnalysis:本质是哪个也是一种ForwardFlowAnalysis但沿着不同的分支发展。例如:执行类似这样的表达式(if(p!=null))时,若p不空进入then分支,否则进入else分支
实现分析接口
为了实现向前流分析,我们继承类ForwardFlowAnalysis,这里有个例子GuaranteedDefsAnalysis。
构造函数
用的时候将DirectedGraph作为参数,并将它用在super函数中。同样还需要在构造函数最后使用doAnalysis(),在这二者中间,你可以建立自己分析的数据结构。
newInitialFlow()和entryInitialFlow()
newInitialFlow()方法必须返回一个你抽象类型A的对象,这个对象被用作每个statement的初始入口和出口,除了第一个statement的入口(通过entryInitialFlow()初始化)
copy()
这个方法仅仅是将源复制给目标,注意A类(你的抽象)必须提供合适的方法。特别指出的是A不可变,你可以在这个限制下使用A。
示例:
@Override
protected void copy(Object source, Object dest) {
FlowSet srcSet = (FlowSet)source,
destSet = (FlowSet)dest;
srcSet.copy(destSet);
}
merge()
这个方法用于在控制流的节点处融合流集合。例如在分支语句结尾。与copy()不同它有三个参数,两个out-set和另一个集合,即融合后新生成的集合。示例:
@Override
protected void merge(Object in1, Object in2, Object out) {
FlowSet inSet1 = (FlowSet)in1,
inSet2 = (FlowSet)in2,
outSet = (FlowSet)out;
inSet1.intersection(inSet2, outSet);
}
flowThrough()
我们需要实现的最后一个方法是flowThrough(),它实现了你实际流的功能。有三个输入参数:类型为A的入口集合和出口集合,以及待处理的节点,通常是Unit.示例:
@Override
protected void flowThrough(Object in, Object node, Object out) {
FlowSet inSet = (FlowSet)in,
outSet = (FlowSet)out;
Unit u = (Unit)node;
// out <- (in - expr containing locals defined in d) union out
kill(inSet, u, outSet);
// out <- out union expr used in d
gen(outSet, u);
}
在eclipse中执行你的流分析
很容易使用Soot ,首先安装Soot插件,可以参考我另一篇译文
注意:该插件不兼容最新的luna版本
然后,
File –> New –> Example,选择A simple BodyTransformer,然后指定工程名(跟一般Java工程类似),实现子类继承FowardFlowAnalysis(或backward/branched)。假设我们把它命名为LocalMustNotAliasAnalysis,你的工程结构如下:
修改MyMain.java使之实例化你的分析,在我们这里main方法代码如下:
public static void main(String[] args) {
PackManager.v().getPack("jtp").add(
new Transform("jtp.myTransform", new BodyTransformer() {
protected void internalTransform(Body body, String phase, Map options) {
new LocalMustNotAliasAnalysis(new ExceptionalUnitGraph(body));
}
}));
soot.Main.main(args);
}
分析在imple Transformation Pack 执行。