Soot 静态分析框架Soot 过程分析
Posted raintungli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Soot 静态分析框架Soot 过程分析相关的知识,希望对你有一定的参考价值。
3.1 Soot构建语法树
Soot通过objectweb来进行字节码构建成语法树
首先scene会去查找一些基础的JVM的类
- 基础的对象Object, Boolean, Void, Integer, Long, Float等
- 字符串操作:String, StringBuffer的类
- Exception, Throwable,以及一些常见的Error类
- 线程相关的, Thread, Runnable
- 序列化,Serializable
- GC相关, Finalizer
- 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
- src Map
- targetMap
- 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
以上是关于Soot 静态分析框架Soot 过程分析的主要内容,如果未能解决你的问题,请参考以下文章