在soot的学习过程中会遇到大量的和配置相关的一些内容,这些内容设置的不正确会很让人感到苦恼,为此做出以下总结。
基本的流程图如下:
【类加载】在类加载阶段,可以设置加载哪些类,哪些不进行加载。【类加载】类加载之后,还需要对类贴上一定的标签,分类。(哪些类是应用的类,哪些类是library类等等),进而为phase的处理阶段进行一定的准备。 -【phase处理类】 phase阶段对于一些类的处理,是可以定制的。(比如说,只解析应用的类,而不考虑library类等)【因为前面对于类进行了标记】* 一般配置 * 输入配置 * 输出配置 * 处理配置 * 应用模式的配置 * 输入特性的配置 * 输出特性的配置 * 注释的配置 * 其他配置
1.1. -help 展现帮助,以及退出。
1.2. -phase-list 打印可能的阶段。
1.3. -verbose 啰嗦模式,会打印在处理过程中,丰富的提示信息。
1.4. -app 应用模式运行。
1.5. -whole-program 开启全局模式。对于阶段会产生一定的效果,效果如下:
1.6. -on-the-fly 复杂分析的办法,能够提升精确度。(但是会消耗较多的时间)
(通过观察call graph边的数量来查看相应的效果) 1.1. -no-bodies-for-excluded 不加载被排除的类的类体(body)。 【效果】false —》(93749条边) , true —》 (131)
PS:
* 哪些类被排除了?soot默认会排除哪些类? * flowdroid会排除哪些类?1.2. -allow-phantom-refs 允许未被处理(unresolve)的类,可能引发错误。 什么叫做未处理的类?
* 找不到对应的源代码就被称作是虚类(phantom class)。 设置为true的时候,出现下面一些提示信息: * 这条语句的 意思是,无法找到 LambdaMetafactory的源代码。(也就是解析无法进入其中)Warning: java.lang.invoke.LambdaMetafactory is a phantom class!
设置为false的时候,可能引发异常:异常信息:
* 之所以会出现异常是因为,大部分情况下,不可能将所有需要的类都加载进来。【建议为true】Exception in thread “main” java.lang.RuntimeException: Phantom refs not allowed at soot.SootMethod.setPhantom(SootMethod.java:212) at soot.SootResolver.processResolveWorklist(SootResolver.java:160) at soot.SootResolver.resolveClass(SootResolver.java:134) at soot.Scene.tryLoadClass(Scene.java:826) at soot.Scene.loadBasicClasses(Scene.java:1487) at soot.Scene.loadNecessaryClasses(Scene.java:1566) at soot.pointTo.SPARKBasicTest.main(SPARKBasicTest.java:30)
1.3. -src-prec format 设置优先处理的源码的格式。(比如,java,apk等等)
1.4. -process-path dir 或者 -process-dir dir 处理所有在dir中发现的类。
1.5. -main-class class 在进行全局分析的时候,需要设定main class 作为入口处。
* 【jb】可以看出先将装载的相应的类通过jb阶段的处理转化为jimple形式。(phantom类是不被转化的,因为找不到类体) 【其他的都进行了转化吗?】 * 【call graph 构造】转化成jimple形式之后,接下来就是建立起call graph.(三种方式可选:CHA,SPARK,Paddle) * 【phase的选择】,通过设置如下的形式:(开启spark模式)Options.v().setPhaseOption(“cg.spark”, “on”); * 【main】main class的作用在于,是生成call graph必不可少的环节。(call graph的定义,起点不同,则生成的call graph不同)
目前关注此方面比较少,所以只说两个。 1. -output-dir dir 将输入的文件保存到 dir 中。
-output-format format 为soot设置输出的格式。(比如,jimple,shimple等等)1.-phase-option phase opt:val 将阶段phase 的opt选项设置成value值。 spark开启后,运行时会出现如下的结果:
[Spark] Pointer Assignment Graph in 0.1 seconds. [Spark] Type masks in 0.0 seconds. [Spark] Pointer Graph simplified in 0.0 seconds. [Spark] Propagation in 0.0 seconds. [Spark] Solution found in 0.0 seconds.-include pkg 将pkg中的类(classes)作为应用的类(application class)。【soot对于要处理的类,进行了分类】
-exclude pkg 将pkg中的类(classes)从应用类中排除。
3.-include-all 将排除(excluded)的包设置为空的列表。【就没有了被排除的包了】
4.-dynamic-class class 注意在class可以被动态加载。
5.-dynamic-dir dir 将dir中所有的类都认为可能是潜在的动态的。
6.-dynamic-package pkg 将包pkg中的类都设置为可能是潜在的动态的。
1.soot 使用的配置。
package soot.pointTo; import java.util.Collections; import java.util.HashMap; import soot.PackManager; import soot.Scene; import soot.SootClass; import soot.jimple.spark.SparkTransformer; import soot.jimple.toolkits.callgraph.CallGraph; import soot.options.Options; public class SPARKBasicTest { public static String processDir = "test/testSpark"; public static void main(String[] args) { System.out.println("start ..."); soot.G.reset(); Options.v().set_src_prec(Options.src_prec_java); Options.v().set_process_dir(Collections.singletonList(processDir)); Options.v().set_whole_program(true); Options.v().set_allow_phantom_refs(true); // Options.v().set_verbose(true); Options.v().set_output_format(Options.output_format_none); Options.v().setPhaseOption("cg.spark", "on"); Options.v().set_no_bodies_for_excluded(true); // Options.v().set_app(true); enableSpark(); Scene.v().loadNecessaryClasses(); Scene.v().loadBasicClasses(); String mainClass = "Test1"; loadClass("Item",false); loadClass("Container",false); SootClass c = loadClass(mainClass,true); PackManager.v().runPacks(); CallGraph callGraph = Scene.v().getCallGraph(); System.out.println("the call graph edge number is : "+ callGraph.size()); System.out.println("done ..."); } private static SootClass loadClass(String name, boolean main) { SootClass c = Scene.v().loadClassAndSupport(name); c.setApplicationClass(); if (main) Scene.v().setMainClass(c); return c; } private static void enableSpark(){ HashMap opt = new HashMap(); opt.put("verbose","true"); opt.put("propagator","worklist"); opt.put("simple-edges-bidirectional","false"); opt.put("on-fly-cg","true"); opt.put("apponly", "true"); opt.put("set-impl","double"); opt.put("double-set-old","hybrid"); opt.put("double-set-new","hybrid"); SparkTransformer.v().transform("",opt); } }2.上面程序处理的对象如下。 Container.java
public class Container { private Item item;// = new Item(); void setItem(Item item) { this.item = item; } Item getItem() { return this.item; } }Item.java
public class Item { Object data; }Test1.java
public class Test1 { public void go() { Container c1 = new Container(); Item i1 = new Item(); c1.setItem(i1); Container c2 = new Container(); Item i2 = new Item(); c2.setItem(i2); Container c3 = c2; } public static void main(String args[]) { new Test1().go(); } }Test2.java
public class Test1 { public void go() { Container c1 = new Container(); Item i1 = new Item(); c1.setItem(i1); Container c2 = new Container(); Item i2 = new Item(); c2.setItem(i2); Container c3 = c2; } public static void main(String args[]) { new Test1().go(); } }官方全面的配置信息: 文档 关于处理阶段的说明: 处理阶段