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

 

 

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