Soot 静态分析框架(三)Soot 过程分析

3.1 Soot构建语法树

 

Soot通过objectweb来进行字节码构建成语法树

首先scene会去查找一些基础的JVM的类

  1. 基础的对象Object, Boolean, Void, Integer, Long, Float等
  2. 字符串操作:String, StringBuffer的类
  3. Exception, Throwable,以及一些常见的Error类
  4. 线程相关的, Thread, Runnable
  5. 序列化,Serializable
  6. GC相关, Finalizer
  7. Lambda表达式,LambdaMetafactory

接着会去查找定义的初始化的类,通过SootResolver 构建SootClass, 生成AsmClassSource使用objectweb加载Class file,生成语法树,同时加载方法生成语法树AsmMethodSource。

 

3.2 Soot构建分析

 

 

 

Soot把每一个阶段的分析都分为Pack,把每个阶段的小的子步骤成为Transform,每一个阶段都可以关闭或者打开,但分析的阶段不可以调整顺序.

 

3.2.1 核心过程的Packs

在Soot的核心过程分为PP->CG->TP->OP->AP,Soot支持多IR分析,但在核心过程中只支持Jimple, Shimple, 在Pack中可以插入自定义的Transform,这样就可以在每一个分析阶段加入自己的分析步骤,从而实现自定义分析的能力

 

3.2.1.1 JB Pack

 

任何分析首先要构建Soot的body对象,在前面步骤中的构建语法书的时候并没有构建Body,所以在Pack分析过程中首先要构建Body,

在Soot里只对Jimple的body进行了构建,Pack只对Jimple body进行分析

 

JB的Pack里包含了如下的子Transform,Transform的顺序不可调整

 

3.2.1.2  PP

Pre-processing Pack 是第一个分析的Pack,该Pack允许你自定义一些自己的transform在构建call graph之前。

在这里Jimple,和Shimple的WJPP, WSPP有所不同,WJPP里包含了

Constant reflective method invocation base transformer (wjpp.cimbt)

 

3.2.1.3 CG

CG Call Graph,调用图,调用图是静态层序分析的关键,方法调用图包含着整个函数调用的关系图。

3.2.1.3.1 Edge

 

函数调用边,边的两头是一边是调用方,另一边是调用的目标方法,同时也包含着前面一条边和下面一条边,通过链表结构构建了整个graph

3.2.1.3.2 Call Graph的结构

Call graph对象里包含了所有的Edges的集合,同时也包含了了几个关键Map

  1. src Map
  2. targetMap
  3. unitMap

这些Map的Key以SootMethod,unit 而value是Edge,为了更快的找到SootMethod或者Unit对应的Edge

 

3.2.1.3.3 构建Call Graph

Call Graph是方法的调用图,要画出方法的调用图是需要起始点的,也就是我们常说的EntryPoint

如何确定起始点呢?

a. 比较明显的是Main Class里的Main方法, 同时还要关注Main Class里的静态的初始化,包括父类的初始化

b. 我们通常会使用多线程的方法,如果只是跟踪Main函数是跟踪不到的,因为Main函数里只是会调用thread的start的方法,函数调用跟踪就断裂了,同时还包含了一些JVM自己的线程调用的Java的方法

addMethod(ret, "<java.lang.System: void initializeSystemClass()>");

    addMethod(ret, "<java.lang.ThreadGroup: void <init>()>");

    // addMethod( ret, "<java.lang.ThreadGroup: void

    // remove(java.lang.Thread)>");

    addMethod(ret, "<java.lang.Thread: void exit()>");

    addMethod(ret, "<java.lang.ThreadGroup: void uncaughtException(java.lang.Thread,java.lang.Throwable)>");

    // addMethod( ret, "<java.lang.System: void

    // loadLibrary(java.lang.String)>");

    addMethod(ret, "<java.lang.ClassLoader: void <init>()>");

    addMethod(ret, "<java.lang.ClassLoader: java.lang.Class loadClassInternal(java.lang.String)>");

    addMethod(ret, "<java.lang.ClassLoader: void checkPackageAccess(java.lang.Class,java.security.ProtectionDomain)>");

    addMethod(ret, "<java.lang.ClassLoader: void addClass(java.lang.Class)>");

    addMethod(ret, "<java.lang.ClassLoader: long findNative(java.lang.ClassLoader,java.lang.String)>");

    addMethod(ret, "<java.security.PrivilegedActionException: void <init>(java.lang.Exception)>");

    // addMethod( ret, "<java.lang.ref.Finalizer: void

    // register(java.lang.Object)>");

    addMethod(ret, "<java.lang.ref.Finalizer: void runFinalizer()>");

    addMethod(ret, "<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.Runnable)>");

    addMethod(ret, "<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)>");

 

 

 

3.2.1.4 TP

Transformation Pack 也分成2种,WJTP, WSTP

其中WJTP还包含以下Transform

 

 

3.2.1.5 OP

Optimization Pack, WJOP, WSOP

 

3.2.1.6 AP

Annotation Pack, 只有Jimple提供了Pack, WJAP

 

 

3.2.2 Body Packs

Body Packs 基于Body 的Packs分析,对不同的IR有不同的Packs

和前面的核心Packs不同的是,这里只是基于Body进行分析,每个Packs依然可以自己定义Transform,

  public Transform(String phaseName, Transformer t) {

    this.DEBUG = Options.v().dump_body().contains(phaseName);

    this.phaseName = phaseName;

    this.t = t;

  }

区别是使用不同的Transformer,在Body packs里使用的是BodyTransformer

protected abstract void internalTransform(Body b, String phaseName, Map<String, String> options);

 

internalTransform里面包含了Body 对象

 

与核心的Pack分析不同的是,当分析到Body的Packs的时候,Soot会启动多线程进行Pack的分析

接下来我们以Jimple为例子举例Body Packs

3.2.2.1 JTP

Jimple Transformation pack

 

3.2.2.2 JOP

Jimple Optimization Pack

 

3.2.2.3 JAP

Jimple Annotation Pack

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章