FlowDroid: 精确的上下文,流,字段, 对象敏感和生存周期感知的污染分析

原创 2015年02月16日 15:25:15

本blog是对http://sseblog.ec-spride.de/tools/flowdroid/项目的翻译和说明,参考的是主页上列的papers。

一个Android app可包含多个组件,如activity, service, content-provider 和broadcast receiver。其中activity负责成像,也就是人机交互,是我们分析的主要入口和场所。不像传统的Java程序,Android app里不带main函数,我们无法简单的像之前一样找到程序的入口和出口来画控制流图,但app里每个组件都有函数来反应此组件的生命周期(lifecycle),我们可以依托lifecycle来画出控制流图。我们先来看下一个activity里的lifecycle是什么样的,

(图片截取自AppIntent, CCS'13)

从图中可以看出activity可以从任何结点按任何顺序执行,并没有传统的单入口单出口结构。除了lifecycle函数activity里还可以带有各种event handler的callbacks,用于处理像UI交互之类的事件。callbacks可以看作居住在lifecycle函数间。

为了生成给定app的控制流图,我们可以对其生成一个虚拟main函数。通过一个例子我们能很清楚的看清背后的思想。


例子中的app只有一个activity用于把用户输在密码框中的内容通过短信发送出去。画横线的语句分别代表了source和sink。现在我们来生成它的控制流图


可以看到dummy main中把onCreatea当作入口,把onDestory作为出口,把原lifecycle图中的带分支的状态看作是抽象的模糊判断语句p,把激活callbacks的条件也同样看作是抽象的判断语句p。

说完了控制流图生成,接下来正式步入static analysis。整个analysis属于flow-sensitive(执行顺序相关),分为两部分,向前的taint analysis用于找出被污染的变量传递到了何处和向后的on-demand alias analysis用处查找source之前所有对同一被污染的heap 位置的别名。来看个小例子


1) w作为被污染了的变量,被向前传递给了heap中的x.f。2) 继续追踪x.f 3)每当heap中有成员被污染,使用向后分析找出相关对象的各种别名。如发现x和z.g是引用的heap中的同一位置 4-6)z是作为参数传递进来的,继续向后找看到caller的a即callee的z,再往后发现b也是别名。7)对b.f做前向分析,判断出其被传递到sink,从而展现了从source到sink的整个路径。

FlowDroid基于IFDS框架,得益于其path不敏感性(由于复合distributive,无论内部怎么传过来的,只要查看JOIN结点的结果即可),FlowDroid不需要考虑所有可能的在lifecycle中的执行顺序。实际上考虑所有可能执行顺序也是不可能的。

为了进一步理解,我们先看看比较formal的东西。


VarId表声明出的object,同一个Object可以有多个VarId。Object 的field(instance, FieldId)储存在heap中,heap储存在内存中。除非刻意删除或者GB, 否则在heap中的元素不会自动消失。Environments 是局部变量和其值之间的映射集合,而Heap: (Loc, FieldId) -> Val是heap中元素与其值之间的映射的集合。对象的值和对象所在位置是等价的,因为对象不像基本类型,其本身没有值,它的值反映在其所在位置下的成员field中,而且即使对于基础类型从其所在位置即可获得其的值。


semantics中的sigma表States := <E, H> E属于Env表当前environment, H属于Heaps表当前heap状态。语义反应了语句的行为带来的影响,除了第一个new,其它都相当于对同一loc增加别名的行为。

再引入一些辅助函数

arrayElem(x) : VarId -> Boolean 判断x是否引用的数组成员

static(x) : FieldId -> Boolean 判断x是否是个全局field

immut(x) : VarId -> Boolean 判断x是否是基础类型,如int, String等

source(s) : Stmt -> P (V arId) 返回被s语句污染的变量名集合

native(s) : Stmt ->  Boolean 判断s是否是调用了原生函数 (C/C++)

nativeTaint(s): Stmt -> P(VarId) 返回被s所调用native函数所污染的变量名集合

nativeAlias(s): Stmt -> P(VarId)返回被s调用的native函数所创建的别名集合

为了更精确的表示field, 引入access path概念。access path更精确的表达了对象的field,如x.f.g.h用access path x.f^3表示,表明x后长度为3的访问路径。T是被污染了的access path的集合,于是更具体的程序状态sigma用三元<E, H, T>表示。

先来谈谈前向taint analysis。FlowDroid只把函数调用(如 API call)看作是可能的source 。taint var和uninit var问题很相似,同样是以并集作为confluence operator, trans func有id, gen, kill(和复制)这么几种。不同在于在uninit var问题中与gen最直接相关的是变量声明语句,而taint是source函数调用;在uninit var中与kill最直接相关的语句是变量被初始化,而taint var则是变量与变量的重初始化(new)或sink函数调用相连。 和unit var一样,data flow的值(uninit和init, untained 和tained)是通过赋值语句在变量间传递的。IFDS框架把结点分为四类,分别是普通,call, return 和call-to-return。我们将对这四种列出相应的transfer func (flow func)。

从普通结点说起,因为source只能是函数调用,所以普通结点不可能纯产生新的污染相关的数据流事实(如a = source() ),只能是传递(= )或者"kill"(new)。

FlowDroind为了保证sound, 对数组索引并不敏感,只要数组内一个元素被污染,则整个数组皆被污染。我们来看下复制的trans func: 


对于「=」语句,1) 第一条是gen, 检查y.f^m下有没有被污染的了,有的话把要引用的x.f^n下的相应访问路径也加入T中 2) 下面是kill,当y,f^m下不包含任何污染且x.f^n不处于被污染过的数组中,则把x.f^n从T中删除(原来在T的话)3)其它情况维持不变。「=」语句右边可能是一个算术表达式,则右边任何变量被污染则左边的变量也会被污染。

接着是new的

new表示该field被重新初始化,不再保留taint,因此与kill直接相关,与复制中的kill一样。

下面讲Call(函数调用)的trans func。Call代表了caller对callee 的影响。一个函数调用的形式可以表达为c.m(a0, .., an),其中c表一个对象名(变量名),m是函数名,a0到an是实参。场景可以表达为class test {x; c.m(a0, .., an)}。FlowDriod在基于有关调用函数的污染集合Tcaller上,通过trans func为被调用函数创建污染集合Tcallee。trans fun定义如下,s表示了一个函数调用语句,pi表示与ai相对应的形参

如果被调用函数所在对象中有成员被污染了,在被调用函数的T中以this来表示;调用者所在对象中的被污染的全局变量如果出现在callee中的话,则同样传递给callee所关联的集合中。


Return 与call相对于,代表了被调用函数对caller的影响。它trans func需要对基本类型(String, int)特殊处理,因为这些类型储存在临时stack内而不是heap中,在被调用函数体内污染并不会影响到调用者。因此对于b = c.m(a0, .., an)语句s相应的trans func为

r表示callee返回的变量。


Call-to-return 用来1)处理native call 2) 遇到source生成纯新的tainted 变量 (之前都是传递) 3) 传递与call无关的污染信息


On-demand Aliasing Analysis:处理别名,即向后找出source出现前的对同一(被source污染了的)heap位置的引用(变量);每当找到一个别名,则触发向前的taint分析,找出此别名的污染传递。实际上与taint analysis的transfer func基本一致,我就贴出来但不细说了。






版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

FlowDroid获取APK的函数调用图

使用FlowDroid这种工具最糟心的就是看不懂的API文档和稀有的编程实例,事实上这个工具的功能很强大,但是工具的开发者并没有告诉用户如何去用。毕竟这个工具源自实验室,科研的产物大多缺乏工业产品式详...

Android污点分析工具flowdroid源码简析

flowdroid是一款对Android app进行风险分析的应用,下面深入其源码对其工作的流程进行相关的探究。 1、准备 a)下载相关源码(包括soot、heros、jasmin、soo...

使用FlowDroid生成Android应用程序的函数调用图

提到Android应用程序静态分析,就不能不提Flowdroid。该工具是目前使用很广泛的Android应用程序数据流分析工具。它基于强大的Java分析工具Soot开发,提供了许多有用的功能。具体的介...

均衡发展才是硬道理——三星

3G手机策略分析   对手机终端市场来说,2011年注定是不平静的一年。据贝叶思咨询监测显示,目前3G手机终端销量在总体手机销量的比例处于快速上升中,由2011年1月的27%上升到6月的38%...

FlowDroid工具的构建与运行

今天早上Aaron收到一封邮件,从我的博客联系到我,问我如何运行flowdroid,着实感到开心。这是我博客搭建起来之后第一次有人联系到我,感觉自己可以做一点事情很开心。本文是以我对该邮件的回复为基础...

FlowDroid 环境配置(mac OS)

FlowDroid环境配置(macOS) 1  环境 平台版本:mac OS 10.12.3 (16D32); MacBook Pro (Retina, 13-inch, Early 2015);2....

类对象的生存周期

让我们来从代码中看下对象的生存周期:class Test { public: Test(int a=10, int b=10) { ma...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)