工具介绍
FlowDroid[1,2] 是 Arzt 等人设计的一款上下文敏感(对象敏感),流敏感,域敏感的静态污点分析工具,除此之外,与其他污点分析工具(如TAJ)不同的是其针对安卓应用,对安卓应用的特性做了很多改进和优化。
该工具基于Soot[3]和Heros[4],soot作为经典的Java语言分析框架,能提供SSA和callgraph,Heros是一个通用的IFDS/IDS分析框架,速度没有WALA快,但是比WALA更通用。
FlowDroid 在污点分析时参考了[Andromeda][http://www.cs.tau.ac.il/~omertrip/fase13/paper.pdf]的做法,有一定的别名分析,具体来说,当污点被load至一个堆区(如图中`x.f=w`)时,进行反向分析,污染别名变量(如图中的z.g.f, a.g.f),再检查污点是否进入sink(如图中b.f),具体算法后文会做分析。
使用
构建工具
1 | git checkout v2.8 # 先切换到稳定版本 |
注意:v2.8分支依赖的soot版本是4.3.0-SNAPSHOT,而github的soot仓库最高版本还是4.2.1,因此这里我手动改一下,希望不要出事Orz
使用
1 | java -jar soot-infoflow-cmd/target/soot-infoflow-cmd-jar-with-dependencies.jar -a DroidBench/apk/GeneralJava/Clone1.apk -p $ANDROID_JARS -s soot-infoflow-android/SourcesAndSinks.txt |
有如下结果
1 | $ java -jar soot-infoflow-cmd/target/soot-infoflow-cmd-jar-with-dependencies.jar -a DroidBench/apk/GeneralJava/Loop1.apk -p $ANDROID_JARS -s soot-infoflow-android/SourcesAndSinks.txt |
源码解析
首先FlowDroid项目有四个子项目:
- soot-infoflow: 数据流分析核心包(基于Soot)
- soot-infoflowandroid: 与安卓特性相关的数据流分析
- soot-infoflow-summaries:还不清楚,像是做函数摘要的类
- soot-infoflow-cmd:命令行入口
soot.jimple.infoflow.cmd.MainClass#main
先从入口开始,程序入口在soot-infoflow-cmd包下面的soot.jimple.infoflow.cmd.MainClass
,主要通过命令传入一些配置,包括但不限于:
- -apkfile:apk文件
- -platformsdir:Android SDK
- -platformsdir: Source & Sink定义
- -outputfile:输出文件
- -timeout:数据流分析超时时间
- -callbacktimeout:callback收集超时时间
与特性、算法相关:
- -nostatic:不分析静态数据流
- -nocallbacks:不分析callback
- -noexceptions:不分析exception数据流
- -notypechecking:不分析污点类型检查
- -enablereflection:允许反射特性
- -missingsummariesoutputfile:列出函数摘要缺失的类
- -outputlinenumbers:列出bytecode line number
- -taintwrapper:【TODO】这个不是很清楚,可以设置None,EASY,STUBDROID或BULTI
- -taintwrapperfile:设置污点文件
- -aplength:路径最大长度
- -cgalgo:调用图生成算法,e.g. CHA,VTA,RTA,SPARK, GEOM
- -pathalgo:返回结果算法,e.g., CONTEXTSENSITIVE, CONTEXTINSENSITIVE, SOURCESONLY
- -dataflowsolver:数据流解析算法, e.g., CONTEXTFLOWSENSITIVE, FLOWINSENSITIVE
还有很多配置等用到时再分析。
接着设置ITaintPropagationWrapper,该接口用于使用函数摘要传播污点,主要用于加速分析以及对抗源代码不存在以及native的情况
1 | // Initialize the taint wrapper. We only do this once for all apps to cache |
接着根据配置产生一个analyzer(SetupApplication,继承自ITaintWrapperDataFlowAnalysis);
1 | // Create the data flow analyzer |
最后调用analyzer.runInfoflow()启动分析主流程。
1 | // Start the data flow analysis |
soot.jimple.infoflow.android.SetupApplication#runInfoflow()
现在进入了soot-infoflow-android包,在runInfoflow()中,先调用ISourceSinkDefinitionProvider读取source-sink文件,文件可以有三种格式:xml, txt和rifl,接着调用SetupApplication.runInfoflow(ISourceSinkDefinitionProvider):
1 | public InfoflowResults runInfoflow() throws IOException, XmlPullParserException { |
在 SetupApplication.runInfoflow(ISourceSinkDefinitionProvider)中,首先初始化Soot——initializeSoot()
,包括制定指针分析方法(默认SPARK)、给一些特定调用添加CallGraph边——LibraryClassPatcher.patchLibraries(
);接着读取Android资源和配置文件,包括AndroidManifest.xml文件,这些文件用于获取分析入口;接着对entrypoint进行分析——SetupApplication.processEntryPoint
;最后收集分析结果并返回。
1 | public InfoflowResults runInfoflow(ISourceSinkDefinitionProvider sourcesAndSinks) { |