乐趣区

浅入浅出FlowDroid一-简介基本使用

前言

说到 Android 的污点分析框架,网上的搜索结果大多指向静态的 FlowDroid 与动态的 TaintDroid。尽管由于加固、混淆等技术使得针对 Android 的静态分析越来越困难,但静态分析的无先验分析能力无法被动态分析取代,使得静态分析仍有发挥空间。后文将围绕 FlowDroid 做一些介绍。
值得注意的是,虽然 FlowDroid 还在被 Secure Software Engineering Group 维护更新,但其核心算法仍然是 2014 的版本。在各大会议上已经提出了数十种新的静态污点分析算法,相比 FlowDroid 在一些数据集或是 DroidBench 上有着更快的运行速度以及更优的精准度。但 FlowDroid 仍然是公共资源中可获取的静态污点分析工具的唯一选择,因为很多 paper 提供的源代码几乎没有注释与文档,导致使用极其困难;另外科研人员往往仅在有限的测试集上进行了运行,所以去使用这样的程序不可避免的会遇到 Bug。相比之下,FlowDroid 作为被持续维护的一款框架,其稳定性上具备了一定的保证,同时其底层的 Soot 框架强大的功能与较为完善的文档,使得 FlowDroid 上手难度相对较低。
尽管如此,FlowDroid 的使用对新手而言仍然充满了困难。网络上 FlowDroid 的教程大多是一些 cmd 命令的说明,而我需要将其作为程序的一部分,甚至还需要对源代码进行一些修改,导致我不得不花费大量的时间去阅读源代码以知悉其中的一些细节以及一些未被文档直接提及的自定义接口。因此,我希望将阅读过程中看到的东西做记录与分享,以便有需要的人可以省去一些功夫。
本系列文章基本为个人见解,难免有错误与误解,如有客观错误欢迎提出。

简介

FlowDroid 是一款使用 Java 实现的针对 Android 的静态污点分析框架,发表于 PLDI’2014(论文链接),截止撰文时间在 Google Scholar 上显示已有 1200+ 的引用,目前为 Android 静态污点分析的主流框架,代码开源并提供于 GitHub(仓库链接)。
FlowDroid 在数据流分析部分并无太大的创新,主要基于发表在 POPL’1995 上的 IFDS 算法(论文链接)实现,其主要贡献在于针对 Android 程序的 LifeCycle、Callback 等特点做了各种各样的处理,感兴趣的可以去阅读论文进行查阅。

基本使用

环境配置

首先自然是 Java 的配置,如果没有配置并且不会配置,请查找网上其他教程,本文不再赘述。
FlowDroid 的配置方法有两种,可以直接下载相关 jar 包,也可以使用 maven 配置依赖。jar 包可以去 FlowDroid 的 GitHub 上 release 页面进行下载,仅需 soot-infoflow-android-classes.jar 和 soot-infoflow-classes.jar 两个文件即可,另外去 Soot 的仓库下载包含了 heros 与 jasmin 的 sootclasses-trunk-jar-with-dependencies.jar,将上述三个包加入项目依赖便完成了 FlowDroid 的配置。关于如何将 jar 包加入依赖,如有困惑请根据 Java 编程环境自行查询。

运行

整个 FlowDroid 最顶层的类便是 soot.jimple.infoflow.android.SetupApplication,大部分的设置与运行都可以通过操作这个类的实例进行。SetupApplication 既可以在调用 runInfoflow() 时传入配置参数,也可以在初始化 SetupApplication 时或初始化后传入配置参数。SetupApplication 的初始化函数以及 runInfoflow 函数有多种不同参数类型的实现,可以查阅源码后根据情况选择,这里仅提供我自己使用的一种方式:

InfoflowAndroidConfiguration conf = new InfoflowAndroidConfiguration();
// androidDirPath 是你的 android sdk 中 platforms 目录的路径
conf.getAnalysisFileConfig().setAndroidPlatformDir(androidDirPath);
// apkFilePath 是你要分析的 apk 的文件路径
conf.getAnalysisFileConfig().setTargetAPKFile(apkFilePath);
// sourceSinkFilePath 是 source 点与 sink 点的声明文件,后文会作说明
conf.getAnalysisFileConfig().setSourceSinkFile(sourceSinkFilePath);
// apk 中的 dex 文件有对方法数量的限制导致实际 app 中往往是多 dex,不作设置将仅分析 classes.dex
conf.setMergeDexFiles(true);
// 设置 AccessPath 长度限制,默认为 5,设置负数表示不作限制,AccessPath 会在后文解释
conf.getAccessPathConfiguration().setAccessPathLength(-1);
// 设置 Abstraction 的 path 长度限制,设置负数表示不作限制,Abstraction 会在后文解释
conf.getSolverConfiguration().setMaxAbstractionPathLength(-1);
SetupApplication setup = new SetupApplication(conf);
// 设置 Callback 的声明文件(不显式地设置好像 FlowDroid 会找不到)setup.setCallbackFile("res/AndroidCallbacks.txt");
setup.runInfoflow();

关于 Source、Sink

污点分析中的 source 点表示污点分析的起始点,而 sink 点表示污点分析的结束点。换言之,FlowDroid 在“扫描”这个 apk 后,会从 source 点开始分析数据流,当数据流“流到”sink 点时将其标注。FlowDroid 中的 source 与 sink 均为类方法,在 soot-infoflow-android 下有提供一份 SourcesAndSinks.txt 的文件,是 FlowDroid 当时使用的一些可能涉及到访问隐私数据的 api,从里面很容易看出声明文件的格式:

每一行作为独立的声明,% 开头的表示注释,可以根据应用需求自行添加删减 Source 与 Sink 的声明。

关于代码中的一些其他说明

Callback

因为 Android 中系统级的 Callback 并不会出现显式地进行回调方法的调用,所以如果需要分析 Callback 方法需要在声明文件中将其声明,同样在 soot-infoflow-android 下有提供一份 AndroidCallbacks.txt 文件,里面是一些常见的原生回调接口或类,如需添加参照格式即可。

AccessPath 与 Abstraction

AccessPath 是数据流分析中一个专用术语,而 Abstraction 是 FlowDroid 用来表示污点分析在一个代码语句的结果的类。关于它们的具体说明会在后面的文章中展开,这里仅需一个宏观的了解,那两个设置的数值越小,分析可能越快但效果可能越差,反之同理。

退出移动版