Soot中的包(Packs)和阶段(phases)

原文链接:点击打开链接

在Soot的反馈邮箱中最常问的一个问题就是在Soot中什么时候运行一个特定的分析。Soot的执行被分割在一组不同的包里(packs),每个包包含不同的阶段(phases)。因此上面这个问题也可以表述为:我应该在哪个包里运行我的分析和转换(transformation)?。这篇文章将帮助你回答这个问题。


Phase options(阶段选项)

Soot支持上百种细粒度的选项,这使得你能够直接通过命令行调整你所需要的分析和优化。

这些命令行选项一般格式为 -p PHASE OPT : VAL。关于所有阶段选项(phase options)的完整文档见点击打开链接。比如说,当我们在Soot里进行分析时我们想保存局部变量的名字(如果可以的话)。那么我们可以添加这个命令行选项 -p jb use-original-names:true。一个更快捷的方式是 -p jb use-original-names,此时true为默认值。


jb: Jimple Body Creation


上面这个图表为Soot里面含有的不同的包。首先,Soot对每一个方法体,或者说对每一个含有方法体的方法应用 jb 包。本地方法比如System.currentTimeMillis()没有方法体(body),jb 包是固定的,它与Jimple表示的创建有关,不能被改变。


Whole-program packs(整个程序范围的包)

接着,Soot应用四个整个程序范围的包

1. cg,调用图包

2. wtjp,whole-jimple 转换包

3. wjop,whole-jimple优化包

4. wjap,whole-jimple注释包

所有的这些包都可以被改变,特别地,可以通过添加 [SceneTransformers](http://www.sable.mcgill.ca/soot/doc/soot/SceneTransformer.html)到这些包中从而进行全程序范围的分析(whole-program analysis)。为了分析和转换程序,SceneTransformer通过[Scene](http://www.sable.mcgill.ca/soot/doc/soot/Scene.html)访问整个程序。下面这个代码段往wjtp包中添加了一个伪转换器(dummy transformer)

public static void main(String[] args) {
  PackManager.v().getPack("wjtp").add(
      new Transform("wjtp.myTransform", new SceneTransformer() {
        protected void internalTransform(String phaseName,
            Map options) {
          System.err.println(Scene.v().getApplicationClasses());
        }
      }));
  soot.Main.main(args);
} 
注意:整个程序范围内的包默认不可用,要使用它们需要在Soot的命令行中声明  -w 选项


Jimple包 jtbjopjap

类似于Soot的整个程序范围内的包(whole-program packs),Soot对每个body应用下面三个包:

1. jtp ,jimple转换包

2. jop,jimple优化包

3. jap,jimple注释包

jtp默认是可用且是空的。通常在这里进行过程内分析(intra-procedural analyses)。

jop包包含一套Jimple优化操作。它默认未启用,可以通过Soot的命令行 -o 或者 -p jop enabled 来启用。

jap是Jimple的注释(annotation)包。每个Jimple body里都可以加入注释,这样你或者其他人或JVM便可以评估优化的结果。这个包默认是启用的,但该包中所有的阶段(phases)默认未启用,因此,如果你把你的分析添加到这个包里,默认会自动启用。

下面这段代码启用空指针标签并注册一个新的[BodyTransformer](http://www.sable.mcgill.ca/soot/doc/soot/BodyTransformer.html),用来打印每个方法里每条语句的标签:

public static void main(String[] args) {
  PackManager.v().getPack("jap").add(
      new Transform("jap.myTransform", new BodyTransformer() {

        protected void internalTransform(Body body, String phase, Map options) {
          for (Unit u : body.getUnits()) {
            System.out.println(u.getTags());
          }
        }
      }));
  Options.v().set_verbose(true);
  PhaseOptions.v().setPhaseOption("jap.npc", "on");
  soot.Main.main(args);
}
注意:每一个添加到非整个程序范围内(non-whole)的Jimple包中的Transform必须是 BodyTransformer


bb tag

正如上面的表格描述那样,Soot接下来对每个body应用bbtag包。bb包将优化并打了标签(optimized anf tagger)的Jimple bodies转换成Baf bodies。Baf是Soot里一种基于栈的中间表示,通过Baf,Soot创建字节码。tag包汇聚特定的标签(aggregates certain tags)。比如说,如果有多条Jimple(或者Baf)语句共享同一个行号标签,那么Soot便只会在第一条含有这个标签的语句上保留这个标签,保证唯一性。


Dava body包 db

Soot中有一个额外的包 db,在上面未标明出来,挡使用 -f java 命令行选项反编译代码转换成Java时,db包被单独使用用来启用或关闭特定的转换。它不包含实际的转换,同时不能往这个包中添加任何东西。


什么时候启用哪个包?

另一个困惑的问题是什么时候启用哪个包,下面这个文档介绍了所有的内容:点击打开链接

这个文档同样描述了每个包中的每个阶段和对应的设置。

你可能感兴趣的:(数据流分析,android分析,Soot)