利用静态阐发对基于权限的系统停止平安阐发: 对安卓仓库的利用
亚历山大-巴特尔(Alexandre Bartel)
摘要
近年来,挪动设备,如智妙手机,已经以指数级的速度开展。在那些设备上运行的最常用的系统是安卓软件栈,几乎占了全世界智妙手机市场份额的80%。该系统运行用户从利用市场下载的安卓利用法式。该系统被称为基于权限的系统,因为它通过查抄利用法式能否有需要的权限来限造对受庇护资本的拜候。用户利用他们设备上的利用法式存储和操做小我信息,如联络人名单或图片,并相信他们的数据是平安的。阐发利用法式和它们所运行的系统是评估数据能否得到优良庇护的客看办法。
在那篇论文中,我们旨在从平安的角度阐发Android利用法式,并答复以下具有挑战性的问题: 若何阐发安卓利用? 安卓利用的权限能否得到很好的定义?利用法式能否泄露受庇护的数据?动态阐发若何能填补静态阐发?为了答复那些问题,我们的论文围绕四个目标展开。
第一个目标是用静态阐发东西来阐发Android利用法式。我们面对的挑战是,Android利用法式是用Dalvik字节码打包的,在许多方面与Java字节码差别。我们开发了Dexpler,那是一个将Dalvik字节码转化为Jimple的东西,Jimple是Soot的一种可理解的格局,是最常用的基于Java法式的静态阐发框架之一。有了Dexpler,我们如今能够阐发Android利用法式了。
第二个目标是查抄开发者能否给他们开发的安卓利用供给了太多的权限。 削减权限的数量能够削减歹意用户操纵利用法式的进攻面。 我们阐发利用法式的代码,以查抄它们实正需要哪些权限。 那需要深进阐发安卓框架,提取API办法(安卓利用法式挪用)和所需权限之间的映射。我们提出了一品种似于安徒生的范畴灵敏办法,利用新的范畴特定的优化来从安卓框架中提取映射。
权限能庇护灵敏数据。然而,拥有准确权限拜候数据的利用法式可能会泄露数据。例如,歹意软件或与积极的告白库打包的利用法式就是那种情状。第三个目标是静态阐发Android利用法式,以检测那种泄露。Android利用法式与传统的Java利用法式差别。最重要的区别之一是,Android利用法式是由组件构成的。阐发Android利用法式以发现泄露,需要将一路通信的组件联络起来,并对每个组件停止建模。我们开发了IccTA来检测隐私泄露。它在代码层面毗连组件,以施行组件间和利用间的数据流阐发。
静态阐发Android利用法式能够发现平安问题,如GPS坐标从设备中泄露出来。然而,静态阐发其实不间接在用户的设备上运行,因而没有考虑到设备的上下文。本论文的最初一个目标是深进领会动态办法若何填补静态阐发。我们初次提出了一个东西链,用于动态检测体内的Android利用,即间接在设备上检测。我们提出了两个对利用法式停止检测的用例,以表白动态办法是可行的,它们能够操纵静态阐发的成果,而且从平安和隐私的角度来看,它们对用户是有益的。此中一个用例是一个内粒度的权限系统原型,利用户可以随意禁用或启用利用法式的权限。
那四个奉献已经通过严厉的尝试得到了尽可能完全的验证。
通过那篇论文,我们供给了利用静态阐发来阐发安卓利用的处理计划,查抄利用的权限集,在安卓利用中ind私有数据泄露,以及阐发基于权限的框架。通过火析出错的处所,我们能够改进挪动利用的平安和隐私。
喊谢
展开全文
起首,我要感激我的导师,Yves Le Traon。可以成为他的SERVAL团队中的第一个博士生,我感应十分荣幸。我很感激他花时间与我讨论新的设法和奉献。当碰着手艺问题时,他对峙让我退一步,看一看全局,那确实有搀扶帮助。Yves告诉我好的软件工程研究是若何完成的。
然后,我想感激我的日常参谋,雅克-克莱因。是他启动了第一批安卓研究项目,他把安卓设备带到我的办公桌上,引导我找到了准确的研究问题。他老是心绪很好,和他一路工做实的很愉快。他教会了我若何集中思惟,若何在笼统的层面长进行推理,以清晰地提出新的设法。
Martin Monperrus是我在里尔大学的长途参谋。我想感激他对我工做的建立性和有洞察力的反应,以及关于论文写做和时间治理的伟大定见。他老是鼓励着我勤奋工做,以到达顶级会议和期刊的程度。
在博士期间,我与卢森堡大学的许多人停止了十分有趣的手艺讨论,特殊是与凯文-阿利克斯(Kevin Allix)、特加文德-弗朗索瓦-迪塞斯-比桑德(Tegawendé François D'Assise Bissyande)和李力(Li Li),我特殊要感激他在IccTA方面的超卓工做。
我有时机与美国宾夕法尼亚大学和德国达姆施塔特手艺大学的研究人员协做并拜候他们。 我想感激宾夕法尼亚大学的Damien Octeau和Patrick McDaniel,他们倡议并指导了我们在EPICC上的胜利协做。我还要感激达姆施塔特手艺大学的Eric Bodden、Steven Arzt和Siegfried Rasthofer,感激他们在FlowDroid上的超卓工做以及我们在污点阐发上的富有效果的协做。
我想感激Lionel Briand,他让我有幸成为论文辩论的主席。我感激我的口头论文辩论委员会成员,Andreas Zeller,Benjamin Livshits和Eric Bodden,感激他们的时间和有见地的问题。关于那篇论文,我还要感激我的读者Jacques Klein, Yves Le Traon, Martin Monperrus, Li Li和Panuwat Trairatphisan,感激他们的时间、兴致和有益的评论。
我要感激我的博士生同事和伴侣,他们让我在卢森堡大学渡过了愉快的光阴。我感激Panuwat Trairatphisan、Wei Dou、Lamia Bekkour、Li Li、Phu-Hong Nguyen和Rustam Mazitov的难忘的羽毛球和网球角逐。我感激凯文-阿利克斯(Kevin Allix),感激我们在十分普遍的主题长进行的有趣讨论。更普遍地说,我感激所有我有时机见到的SERVAL团队和SnT的人,特殊是Christopher Henard, Donia El Kateb, Anestis Tsakmalis, Iram Rubab, Jabier Martinez, Thomas Hartmann, Jorge Meira, and Grégory Nain。
我感激卢森堡国度研究基金(FNR),它是我的资金来源,使我的博士工做在三年半的时间里成为可能。
最初,我想感激我的家人,感激他们的鼓舞和爱。 感激我的父母,他们在我进修期间不断撑持我。最重要的是感激我的老婆克莱尔,她在博士期间对我的撑持,我十分感恩。谢谢你。
亚历山大-巴特尔
卢森堡大学
2014年9月
第一章
引言
近年来,挪动设备,如智妙手机,已经以指数级的速度开展。在那些设备上运行的最常用的系统是安卓软件仓库,几乎占了全世界智妙手机市场份额的80%,然而,跟着普及,为安卓系统定造的进攻也越来越多。
在那篇论文中,我们声称静态阐发能够搀扶帮助避免那种进攻。我们利用静态阐发从一个基于权限的框架1中提取权限。那使得我们可以查抄在基于权限的框架之上运行的利用法式能否遵守了最小权限原则,而且没有声明太多的权限。此外,为了评估资本和用户数据能否得到了很好的庇护,我们对利用法式停止静态阐发,以发现可能表白歹意行为的可疑泄露。最初,我们表白,从框架的静态阐发中提取的信息能够在运行时操纵,以从隐私的角度加固利用法式。例如,我们施行了一个用户驱动的动态政策施行,利用户可以启用或禁用任何利用法式的权限。
为了更好天文解Android权限系统,让我们回到拜候掌握的前提下。事实上,自从多个用户能够拜候统一台计算机以来,人们就需要利用拜候掌握来庇护他们的数据不受其他用户的影响,不管他们是歹意的仍是鸠拙的。在那一章中,我们介绍了拜候掌握的概念,并鼓励我们抉择对一个名为Android的基于权限的系统停止阐发。第1.1节和第1.2节介绍了拜候掌握的概念,从第一台引进密码的计算机到最新的基于权限的系统Android。
第1.3节阐了然基于权限的系统的缺点。第1.4节阐了然我们在研究和阐发基于权限的系统时所面对的挑战。最初,第1.5节列出了那项工做的奉献。
1.1 拜候掌握的简史
最早容许多个用户同时工做的计算机之一是1963年的兼容时间共享系统(CTSS)[32]。 每个用户都能够拜候计算机,并能够通过一个末端发送死令给它,还能够得到一个小我目次来存储文件。只要有一个以上的用户在统一台机器上存储信息,就会呈现关于隐私、平安和保障的问题。任何人都应该可以看到谁创建了一个ILE吗?假设有人错误地删除了另一个用户的ile怎么办?能否应该容许任何人看到任何用户的任何ile?
在20世纪60年代,CTSS的用户担忧其他用户会修改他们的档案。
为领会决那个问题,CTSS可能是第一个引进那个设法的操做系统,密码被用来验证用户。一旦用户被系统认证,她将只被受权拜候他/她的文件,而不是任何其他用户的文件[32, 112, 133]。该系统确保iles只被受权用户拜候。换句话说,它庇护了系统的资本,避免歹意或鸠拙的用户拜候或窜改它们。 一个用户能够与其他用户共享ile,容许他们在本身的目次中放置一个称为link的特殊ile,引用共享ile。那是拜候掌握的第一种办法。 图1.1表达了一个拜候掌握的通用模子。 每当一个主体(如用户)试图拜候一个对象(如链接)时,系统就会查抄拜候掌握战略以容许或回绝该拜候。
1965年推出的CTSS的后继者,称为MULTICS(多路信息和计算办事)[33, 112],从一起头就以信息庇护为目标。与CTSS一样,每个用户都有一个标识符,并利用密码对系统停止验证。 然而,MULTICS引进了用户组的概念和拜候掌握列表(ACL)的概念。ACL是一个可调整的用户列表,那些用户被容许读取、写进、施行或逃加一个对象(例如,一个法式)。对象被组织在一个由目次构成的单一条理构造树中。 假设一个用户有修改目次的权限,她能够修改该目次下所有对象的ACL。 因为用户能够改动属于他们的对象的拜候权限,所以拜候掌握被称为自在决定的拜候掌握(DAC)。
受MULTICS的启发,UNIX [108]在20世纪60年代末70年代初呈现。在UNIX中,ILE-系统是一棵由ILE和目次构成的树。每个ILE和目次都属于一个用户和一个组。此外,每个ILE和目次都有权限位,容许所有者为拥有该ILE的用户、该ILE所属的组或其他用户激活或取缔读、写或施行的权限。
在接下来的几年里,计算机已经在可以承担得起的公司和戎行中普及和利用。那引起了人们对计算机平安,特殊是拜候掌握的兴致。人们勤奋将拜候掌握正式化为数学模子。Bell-LaPadula拜候掌握模子[16]是在1973年设想的,重点是保密性,那在军事利用中特殊有用。在那个模子中,主体(如用户)能够看察、改动或修改对象(如档案)。为主体和客体分配一对,决定类别和分类,称为平安级别(例如,类别 "密码学 "和分类 "未分类",类别 "核 "和分类 "奥秘",类别 "化学 "和分类 "更高奥秘",......)。 施行Bell-LaPadula模子的系统必需确保一些属性是成立的(例如,一个分类为 "奥秘 "的用户不克不及阅读 "更高奥秘 "的文件)。那些拜候规则是由治理员在一个集中的政策中确定的,用户不克不及修改或绕过。那种拜候掌握被称为强逼性拜候掌握(MAC)。
Bell-LaPadula偏重于保密性,因而只限造对数据的拜候,但对庇护数据的损坏没有任何感化。简而言之,它不克不及确保数据的完全性。1977年,另一个模子被设想来处理那个问题:比巴模子[21]。那个模子确保一个主体不克不及毁坏数据,其平安级别高于主体的级别。
在20世纪70年代末、80年代初,最后的UNIX系统降生了许多基于不异理念的版本。最闻名的系统可能是GNU/Linux、基于BSD和MAC X的操做系统。它们的根本拜候掌握类型是DAC,但也存在MAC的实现,例如SELinux[121]是Linux内核的MAC扩展。
1.2 普通化的拜候掌握
确定一个系统的平安战略(即所有拜候掌握规则的聚集)是一项复杂的使命,需要对系统的拜候掌握模子有深进的领会。 今天,计算机无处不在,新手和专家都在利用。确定拜候掌握战略不是一件随便的事,以至可能被那些只想让系统工做而不关心平安问题的新手用户所漠视。
在欧洲,手机的生齿笼盖率几乎到达100%[73]。 它们已经从运行一个次要目标是打德律风和接德律风的系统的设备开展到了完全边沿化的计算机。那些设备可以毗连到互联网,看看高辨认率的片子和玩最新的3D游戏,并与德律风利用绑缚在一路。那些电脑,或称智妙手机,运行用户从互联网上的利用市场下载的利用法式。关于智妙手机来说,利用法式在对系统资本停止操做时(例如,GPS、互联网拜候......),凡是遭到开发商为其规定的一系列权限的限造。
当下载一个利用法式时,用户能够看到该利用法式所需的权限列表,并能够决定容许该利用法式被授予列表中的所有权限并安拆该利用法式,或者抉择底子不安拆该利用法式。那种拜候掌握的权限模子利用户处于治理员的地位:他/她必需在每次安拆新的利用法式时更新设备的拜候掌握战略。 我们称那种系统为基于权限的系统。我们在那项工做中研究的基于权限的系统是Android。
1.3 基于权限的系统阐发的动机
下面三节(1.3.1, 1.3.2 和 1.3.3)介绍了一些例子,鼓励我们阐发运行在基于权限的系统之上的利用法式。那些例子代表了基于权限的系统设想中的一个环节,因而与正在研究的基于权限的系统无关。 此外,第1.3.4节阐了然如许一个事实:因为文档不完全,开发者可能会无意中在他们开发的利用法式中产生破绽。那促使我们对基于权限的系统自己停止阐发,以改进文档和/或利用法式的开发过程。最初,第1.3.5节强调了安卓系统在权限方面赐与用户的自在的局限性,并提出了一个替代计划,该计划依靠于安卓基于权限的系统的阐发成果。
1.3.1 紊乱的副手
利用法式能够一路交换。 假设一个利用法式被付与一个权限,另一个利用法式能够操纵那个利用法式来滥用其权限。 那种进攻被称为紊乱的副手进攻,如图1.2所示。那种进攻经常发作,因为紊乱的副手利用法式错误地认为只要一个有限的和受相信的利用法式能够拜候它的接口。因为那个原因,它的接口没有得到很好的庇护,能够被意识到那个破绽的歹意利用法式所滥用。在图1.2的例子中,紊乱的副法式拥有收集权限,因而可以启用或禁用收集。 它错误地认为只要受相信的利用法式才气拜候其接口,因而没有准确地庇护它。进攻者操纵那个不受庇护的接口,让紊乱的副手利用其权限代表进攻者禁用收集。
1.3.2 利用法式通同
利用法式被授予权限,能够一路通信。因而,没有什么能阻遏一个利用法式从授权限庇护的资本中获取数据(例如GPS坐标),并与另一个可能没有权限拜候受庇护资本的利用法式分享那些数据。当多个利用法式为了一个配合的歹意目标而协做时,它们就会通同起来。
图1.3阐了然利用法式通同的情状。 进攻者必需在目标设备上安拆两个(或更多)利用法式。 一旦利用法式被安拆,它们就会一路交换,分享它们的权限。在安拆单个利用法式时,用户只能看到每个利用法式的有限权限。在图1.3的例子中,第一个利用只要GPS的权限,第二个利用只声了然互联网的权限。
然而,利用1能够与利用2分享它通过GPS权限获得的数据。利用法式2能够拜候互联网,它能够将GPS坐标发送到互联网上的一个长途主机。互联网上的一个长途主机。
1.3.3 数据泄露
图1.3的例子阐了然两个利用法式共享GPS坐标并将其发送到互联网上。我们说,GPS数据从App1中检索GPS坐标的语句(源)泄露到App2中发送坐标到互联网的语句(汇)。那种特殊的数据泄露发作在两个利用法式之间,那在歹意软件利用法式中其实不常见。为了更有效,大大都歹意软件在一个单一的利用法式中泄露数据。
1.3.4 不完全的文件
一个Android利用法式包罗一个权限列表,描述了该利用法式能够拜候哪些资本(例如,拜候GPS)。安卓利用的开发者负责编写那个权限列表。为了实现那一目标,他们依靠文档,但遗憾的是,文档其实不完全[53]。此外,他们还依靠在论坛或网站上找到的带有权限列表的代码片段[53]。然而,权限表可能包罗了超越需要的权限。 因而,开发人员可能会编写一个包罗比利用法式所需更多权限的权限列表,增加利用法式的进攻面(即进攻者能够进进系统并可能形成损害的所有体例[85])。事实上,假设一个进攻者毁坏了利用法式,她就能够拜候更多的资本,而不是在削减权限列表的情状下拜候。
在本论文中,权限缺口被定义为一个利用法式声明但不利用的一组权限。为了检测权限差距,我们起首要计算出所有API办法的权限聚集。然后,通过查看利用法式挪用的API办法,能够从利用法式代码中主动计算出一个权限列表。映射到那些API办法的权限构成了利用法式需要的权限列表,以便一般工做。那个主动计算的权限列表和利用法式的开发者编写的权限列表之间的差别被称为权限差距。
1.3.5 对用户数据的细粒度庇护
用户往往自愿或不自愿地在他们的设备上存储大量他们认为是隐私的信息,如图片、联络信息、GPS坐标、电子邮件或日历信息。一方面,他们认为那些信息是私有的,遭到设备的庇护。 另一方面,他们期看从互联网上的长途存储库(可信和不成信)安拆利用法式,并切确掌握那些利用法式的权限列表。然而,他们没有可能设置装备摆设一个细化的权限政策。
在那项工做中,我们切磋了在用户设备上间接实现如许一个系统的挑战。新的软件修改了安卓利用法式的字节码,并在代码中编织了拜候掌握战略。该战略能够在运行时由用户决定,例如,禁用所有安拆的利用法式的权限。
总而言之,我们在本节中看到:(1)紊乱的副手、利用法式通同和数据泄露的例子促使在利用法式中停止泄露检测;(2)不完全的文件表白应该对框架自己停止阐发;(3)为了改进数据庇护,应该让用户对设备的平安战略有更多掌握。
在那篇论文中,我们旨在从平安的角度阐发Android利用法式和Android框架。从鼓励性的例子中,我们将答复以下具有挑战性的问题:若何阐发Android利用?每项使命都是为安卓利用设想的吗? 利用法式会泄露受庇护的数据吗? 动态阐发若何填补静态阐发? 下一节将描述我们在答复那些问题时面对的手艺挑战。
1.4 基于权限的系统阐发所面对的挑战
在那一节中,我们将介绍在阐发Android框架和Android利用法式以答复第1.3节所列研究问题时面对的手艺挑战。
第1.4.1节阐了然Android利用法式利用一种特殊的字节码,需要将其转换为可阐发的表达。第1.4.2和1.4.3节别离描述了阐发Android框架和Android利用法式的困难。最初,第1.4.4节强调了间接在设备上运行阐发Android利用法式的挑战。
1.4.1 Dalvik字节码
Android利用法式是用Java编写的,然后编译成Java字节码,最初编译成Dalvik字节码。现有的静态阐发东西能够在利用法式的源代码或Java字节码可用时阐发Android利用法式。然而,那种情状其实不常见,因为大大都利用法式是通过市场分发的,而市场只供给最后的Dalvik字节码。 例如,在官方的Google Play市场上有超越一百万的利用法式2,而在F-Droid(免费和开源的安卓利用法式)网站上只要大约一千个利用法式3。那就促使我们利用一个软件模块将Dalvik字节码转换为可阐发的表达。
在本论文起头的时候,也就是2010年,还没有可用的东西来对Dalvik字节码停止复杂的静态阐发。为了可以阐发Android利用法式,我们开发了一个名为Dexpler的模块,将Dalvik字节码转换成可阐发的表达。 我们操纵了一个现有的名为Soot的东西,其内部的代码表达被称为Jimple。如图1.4所示,Soot可以阐发Java源代码和Java字节码,将它们转换为Jimple表达法。 Dexpler将Dalvik字节码转换为Jimple,以便Soot可以阐发Dalvik字节码。
当把Java字节码转换为Dalvik字节码时,一些关于变量类型的信息会丧失。关于字节码中每个有那种信息丧失的办法,Dexpler通过火析该办法的代码将那些信息找回来。
1.4.2 框架的阐发
静态阐发最后是用在法式或利用法式上,而不是API上。关于一个法式,凡是有一个单一的进口点,阐发从那里起头。然而,关于一个框架或API来说,没有进口点:我们必需为所有的进口点构建包拆代码。封拆代码的感化是构建进口点办法被挪用的对象,以及被挪用的进口点办法的参数。 此外,构建封拆代码并非一件随便的事,因为我们必需考虑到若何挪用API的办法以及若何初始化其参数。
对一个框架的静态阐发从构建封拆代码的挪用图起头。在Android的情状下,API代码是系统运行的其他法式或利用法式的接口。仅仅从封拆代码中构建挪用图是不可的,因为系统法式(负责查抄权限)没有被准确初始化。因为系统法式是在安卓设备启动时启动和初始化的,所以初始化代码是无法从进口点办法中抵达的。 我们摘用的处理计划是将所有的系统法式独立出来,从进口点挪用图中零丁初始化它们,而且每当在进口点挪用图中碰着它们时,就引用初始化的法式。
图1.5展现了一个有三个进口点(如ep1、ep2和ep3)的框架。阐发那个框架需要对那些进口点停止包拆。那是通过处置进口点初始化和参数实例化的 "进口点包拆器 "节点实现的。在构建挪用图时,ep3挪用了 "srv1 "办事的代码。 那个办事已经被零丁初始化了(图1.5,右),挪用图的构建参考了初始化的办事。假设没有办事的初始化,挪用图是不完全的,因为该办事应该是不存在的。
1.4.3 利用法式的阐发
阐发Android利用法式与阐发Java利用法式差别,后者有一个单一的进口点(即主办法)。Android利用法式的特征是,每个组件都有一个由Android系统治理的生命周期。图1.6a代表了一个喊做activity的Android组件的生命周期的简化视图。那个生命周期有四个形态,s1到s4,在事务产生后从一个形态挪动到另一个形态(e1到e7)。事务触发了组件的指定办法(m1到m7)。组件的生命周期在Android利用法式中是不存在的。Android系统处置Android利用法式的组件的生命周期。因为为每个利用法式阐发Android系统以考虑到组件的生命周期,成本太高,所以我们利用生命周期的模子来取代。
此外,任何组件都能够被统一利用法式或另一利用法式的另一个Android组件挪用。一个安卓利用没有单一的进口点,但至少有和组件一样多的进口点。一个利用法式的组件被列在利用法式的清单中。在图1.6b中,没有源组件的黑色箭头代表利用法式一的组件C1和C3以及利用法式二的组件C5和C6的进口点。
有些组件能够在利用法式的组件代码中定义,而不是在清单中定义。因而,仅仅阐发清单是不敷的,还必需查抄组件的代码以确定动态注册的组件。此外,组件之间能够彼此通信。组件是松懈耦合的,因为它们之间的毗连是在运行时完成的,它们之间的通信依靠于被称为Intents的笼统动静。在图1.6b中,利用一的组件C1和C2之间以及C2和C4之间有利用内通信,利用一的C3和利用二的C5之间有利用间通信。
简而言之,当利用静态阐发来阐发一个Android利用法式时,我们必需对组件的生命周期停止建模,并计算组件之间的通信链接。
1.4.4 间接对设备停止阐发
固然在设备外对利用法式停止阐发和转换很有趣,但间接在设备长进行阐发会更有趣。例如,用户将间接受益于容许他们拥有细化权限政策的软件(即容许对权限停止细化调整的政策。例如,INTERNET权限不容许完全的收集拜候,而是能够将收集拜候限造在用户自定义的URL列表中)。次要的挑战是可以在对可用内存和处置才能有限造的设备长进行一些阐发,以及对一个历程的可用堆有硬编码限造。 在桌面上需要100MB堆的阐发不克不及在原则的安卓设备上运行,因为安卓设备的堆限造是80MB或更少。
1.5 奉献
在本节中,我们提出了我们的奉献,以答复第1.3节中提出的研究问题,并处理第1.4节中提出的相关挑战。 在那项工做中,有七个次要的奉献,鞭策了Android和基于权限的系统研究的更先进程度:
- 一种转换Dalvik字节码Jimple的算法。 因为Jimple是静态阐发框架Soot的内部代表,Dexpler使Soot可以静态地阐发Android利用法式。我们在一组2.5万个利用法式上评估了Dexpler。Dexpler准确地转换了99.9%的利用法式的办法。
- 一种将API办法映射到权限的算法。我们提出了一种算法,起首从API办法中生成进口点,然后从基于权限的框架的API办法中成立一个挪用图,最初利用深度优先搜刮来停止权限查抄并提取权限名称。
- 对Android基于权限的系统停止实证阐发。我们已经实现了我们的算法,将API办法映射到权限,并对其停止了定造,以阐发Android框架。 安卓特有的修改包罗办事重定向、办事身份反转、系统办事和治理者初始化。
- 对权限差距的实证阐发。 该阐发是在两组Android利用法式长进行的。在第一组中,有18%的利用法式来自官方的安卓市场,第二组来自另一个市场,有12%的利用法式存在权限差距。
- 一个检测Android利用法式内部和之间泄露的东西。我们的东西喊IccTA,在Jimple级别上链接Android组件。那容许检测组件间和利用间的数据泄露。
- 对IccTA停止实证评估,以检测组件间的泄露。我们在DroidBench上评估了IccTA,那是一套专门为测试组件内和组件间泄露的东西而设想的Android利用法式。 我们的算法优于现有的东西,切确度为95%,召回率为82%。 我们还在一组3000个安卓利用中评估了我们的算法。它在此中450个利用法式中检测到了泄露。
- 第一个关于体内仪器化的实证阐发。那项研究展现了间接在设备上对安卓利用停止检测的可行性。我们还提出了两个用例:第一个用例是将告白从利用法式中移除,第二个用例是容许用户造定一个细化的权限战略,那在当地安卓系统中是不成能的。 那些案例表白,该办法是可行的,停止高级阐发的次要限造是系统施加的堆大小。
1.6 本论文的道路图
本论文的组织构造如下。在第二章中,我们介绍了静态阐发的根本原理、挪用图的构建、Android利用法式和基于权限的Android系统。在第三章中,我们讨论了Dexpler,一个将Dalvik字节码转换为Jimple的软件,以便阐发Android利用法式和Android系统。在第四章中,我们阐发了Android框架,将权限映射到进口点办法。我们操纵那些常识来识别那些声了然太多权限的利用法式,那增加了末端用户的进攻面。在第五章中,我们描述了一种在安卓利用中识别私家数据泄露的手艺。接下来,在第6章中,我们介绍了关于体内安卓利用东西和阐发的第一个成果。 最初,在第八章中,我们总结了论文,并讨论了将来的工做和开放的研究问题。
第二章
手艺布景
本章介绍了理解本博士论文所需的次要手艺布景。本章分为三个部门。第2.1节介绍了安卓系统:包罗安卓利用法式及其组件、系统办事和答应拜候掌握。 然后,第2.2节向读者介绍了静态阐发,特殊是基于Java法式的挪用图构造和法式间数据流阐发。
2.1 安卓仓库简介
Android是一个为智妙手机、平板设备以及更普遍的任何品种的小我设备开发的软件系统。它最后是由安卓公司在2000岁首年月开发的[78]。谷歌在2005年收买了该公司以进一步开发该系统。第一个公开可用的设备呈现在2008年[79],运行的是安卓1.0。从那时起,大约每三个月就有一个新的版本发布。在写那篇文章的时候(2014年)
最新的安卓版本是4.4。
在本节中,我们起首在第2.1.1节中对安卓系统停止了概述。然后,我们在第2.1.2节中介绍了Android利用法式的构造。最初,在第2.1.3节中,我们详尽介绍了系统办事,那是Android系统的一个次要部门。
2.1.1 整体构造
Android是一个软件栈,意味着它有四个次要的软件层,如图2.1所示(从上到下):利用层、框架层、运行时和当地库层以及内核层。
顶层的特征是Android利用法式。典型的安卓利用有:主页利用,它是第一个运行的利用,展现启动其他利用的图标;联络人利用,治理联络人列表;德律风利用,拨打德律风;阅读器利用,拜候收集资本。运行安卓系统的设备的用户能够在他们的设备上安拆更多的利用法式,凡是是通过从FDroid1或名为Play Store2的谷歌官方市场上下载。 利用法式次要用Java编程语言编写,但也能够包罗当地代码。 利用法式依靠框架层与系统停止通信。
框架层是利用法式和系统其他部门之间的一个用Java编写的接口。它供给了从系统资本中检索信息的设备(例如,利用法式能够通过LocationManager检索GPS坐标)或要求系统在有新事务时回调它们(例如,要求TelephonyManager在有德律风时通知利用法式)。
第三层有两个差别的实体:Android运行时间和当地库。
- Android运行时由Dalvik虚拟机和Android核心库构成,前者施行Android利用法式的Dalvik字节码3,后者根本上是利用法式能够操纵的Java类(例如,利用法式能够利用当地库,那取决于情况的设置装备摆设。
- 本机库4供给了能够被利用法式、框架层或核心库利用的根本构建块。利用法式能够有间接利用当地OpenGL库停止快速图形处置的当地代码。框架层能够利用当地SQLite库来存储数据。
更低的一层是Linux内核。从上层的软件层来看,它能够被看做是硬件(CPU、内存......)的一个界面。事实上,它负责在CPU上运行法式5,它有许多驱动来处置差别的硬件,如展现器、收集和治理收集通信的驱动。它还具有一个特殊的驱动,用于有效的历程间通信,称为Binder驱动[116]。
正如我们所看到的,那些层并没有明白分隔。 一个Android利用法式能够利用框架层、核心和当地库中的元素,也能够间接与内核通信。安卓系统实现了平安功用,以避免利用法式拜候系统的每个部门。简而言之,开发者给他们编写的每个利用法式供给了一个权限列表。那个列表规定了利用法式被容许在系统上做什么,而且必需在安拆时由用户停止验证。当一个利用法式被安拆时,它被付与一个用户ID(UID)。每个安卓利用都能够被看做是一个Linux用户。此外,安卓系统有一个列表,将每个权限映射到一个组ID(GID)。关于利用法式声明的每一个权限,系统城市将该利用法式(或更切当地说,响应的Linux用户)添加到响应的GID中。因而,假设一个利用法式没有GPS权限,并想通过LocationManager或GPS的Linux驱动来检索GPS坐标,Android系统会检测到该利用法式不在GPS组中,并阻遏它拜候GPS数据。
2.1.2 Android利用法式的构造
一个安卓利用法式是一个用开发者的私钥K签名的压缩zip文件。它包罗利用法式的Dalvik字节码(由Java源代码编译而成)、利用法式需要的数据(图片、声音......)以及描述利用法式构造和利用法式所需权限的清单文件。简而言之、
Application = Sign(Zip(DalvikBytecode, Manifest, Data), K)。
安卓利用是用开发者的私钥签名的,那确保了利用只能由统一个开发者签名的代码来更新,并且用统一个密钥签名的利用有可能共享权限和UID。然而,它其实不包管利用法式做者的实在性,因为证书能够是自签的(例如,任何人都能够声称是无名氏)。
组件
Android利用法式是由组件构成的。有四种组件:活动、办事、内容供给者和播送领受器。活动组件用于图形用户界面(GUI)。它们展现图形元素,如按钮、列表或图片。办事组件用于计算密集型使命或需要长时间的使命,如播放音频文件。 内容供给者被用来在利用法式之间共享数据。例如,联络人列表被实现为一个内容供给者,如许任何利用法式都能够拜候它(假设它有恰当的权限)。最初,播送领受器组件领受来自系统或其他利用法式的动静(例如,系统已经收到了一条短信)。详细来说,每个组件都是一个Java类,它继续自一个特定的超类,如活动、办事等。图2.2表达一个由三个活动和一个播送领受器构成的Android利用法式。
意图图和URI停止通信
Android利用法式的组件凡是利用特殊的系统办法停止通信,那些办法称为组件间通信(ICC)办法。 大约有40个ICC办法,一个组件能够用来与另一个组件通信。 最常用的ICC办法是startActivity(Intent)。 那个办法用来告诉系统启动一个由该办法的参数描述的新活动组件。
企图。 组件能够利用一个喊做Intent的笼统对象彼此通信。
通信能够发作在单个利用法式的组件之间或多个利用法式的组件之间。当组件A想与组件B通信时,它初始化一个Intent并将组件B设置为目标地。那种通信被认为是显式的,因为目标组件是明白规定的。通信也能够是隐式的,在那种情状下,源组件用它想施行的动做来初始化Intent(例如,查看pdf文档)。当组件发送Intent时,系统会查抄在其企图中能否有该动做的组件。目标组件的抉择能够由系统主动完成,假设有多个组件能够处置该动做,则可能需要用户干涉。例如,假设图2.2中的Activity3发送了一个带有 "查看txt "动做的Intent,系统就会启动Activity2,因为它是独一具有 "查看txt "企图的组件。Intent能够将数据以键/值对的形式封拆在称为Bundles的对象中。 Intents被用于活动、办事和播送领受者之间的通信。
URI。 URI,即同一资本识别器,用于识别笼统或物理资本[19]。简而言之,URI被用来与内容供给者通信。它们也可用于初始化针对特定资本的企图。以下面的URI为例:.content://comandroid calendar/events。它能够被切割成三个部门。第一部门,内容,称为计划,确定了若何拜候资本。读者可能已经晓得通过如许的途径来识别网页资本。在我们的例子中,那就是内容供给者的数据库表事务。
清单(The Manifest
清单以组件的形式描述利用法式的构造。 一个组件能够被导出,以便其他利用法式能够利用它。它还能够声明企图过滤器,以便向系统指定它所处置的动作或数据的品种。 清单还列出了利用法式要求的所有权限(如INTERNET、GPS)。图2.3展现了一个清单的例子。它声了然一个有一个内容供给者、一个办事、一个活动和一个播送领受器的利用法式。 该办事只承受带有动做SyncAdapter的企图,活动企图带有动做MAIN和类别UNIT_TEST,播送领受器企图带有动做BOOT_COMPLETED。该清单为利用法式声了然一个权限:INTERNET权限。
2.1.3 安卓系统的构造
启动过程
安卓系统的启动过程如图2.4所示。当安卓设备被翻开时,CPU起首施行启动加载法式,初始化RAM(随机存取存储器)和硬件,然后加载内核并跳转到它。内核初始化驱动法式,挂载根系统并启动第一个历程:init。init历程挂载所有ile-系统,设置ile-系统的权限,并启动当地守护法式。 当地守护法式是在后台运行的法式。那些法式包罗治理所有蓝牙设备的bluetooth d(蓝牙守护历程)和Rild(无线电接口层守护历程),它是无线电设备(例如全球挪动通信系统的无线电设备)的接口。 一个当地守护历程,app_process,启动Dalvik虚拟机的一个实例,并初始化Zygote,一个用于分叉新的Android利用法式的法式。当Zygote启动时,它启动了系统办事器,那是一个初始化所有系统办事的历程6(例如GPS的系统办事),并启动活动治理器。最初,活动治理器启动主页利用法式。
在那一点上,用户面临的是主利用法式的图形界面。 那个图形界面展现设备上安拆的Android利用法式的图标。当用户点击一个图标时,主利用法式挪用startActivity办法。 活动治理器处置那个办法挪用,并要求Zygote分叉本身,以创建和启动与用户点击的图标相对应的新的Android利用法式。
启动后的历程。
当启动挨次完成后,Android系统已经被初始化,其内核正在运行图2.5中所示的历程。 右边是一个历程的仓库,上面是bluetoothd历程。在bluetoothd历程的右边是办事治理器历程,它被提早利用,因为它被系统办事器用来注册系统办事。那些都是由init历程启动的当地守护历程。在中间的是Zygote,用于启动新的Android利用法式的历程。Zygote启动的第一个历程是系统办事器,它初始化、向办事治理器注册,并运行所有的系统办事。最初,在图的右边是一个代表Android利用法式的仓库。第一个运行的Android利用法式是Home利用法式。通过Home利用的界面,用户能够启动其他的Android利用。
Zygote、系统办事器和Android利用法式仓库正在运行一个带有Dalvik虚拟机的历程,施行Dalvik字节码。 该虚拟机也能够通过Java当地接口(JNI)施行当地代码或共享库。另一方面,当地办事不运行一个Dalvik虚拟机。
当地办事和Zygote以根用户的身份运行。系统办事器以系统用户的身份运行,以遵守最小特权原则[113](例如,做为一个通俗用户,系统用户不克不及拜候其他用户的数据)。正如在第2.1.2节中已经提到的,Android利用法式做为通俗用户运行,每个利用法式分配一个用户ID。
安卓拜候掌握
Android系统运行Android利用法式。那些利用法式能够拜候系统资本,如GPS、联络人列表或摄像头。安卓系统用权限来庇护系统资本。假设利用法式没有恰当的权限,系统就会阻遏它们拜候某个资本。
图2.6阐了然一个安卓利用若何拜候GPS资本。 GPS资本需要特定的硬件,因而需要一个内核驱动来向硬件发送死令。一个Android利用法式在Dalvik虚拟机中运行,能够通过JNI施行当地代码。理论上,利用法式能够利用当地库,通过恰当的内核驱动法式与设备间接通信。 图2.6中的虚线表达从利用法式到设备驱动的那种通信。然而,那种间接通信是Android系统所不容许的,因为利用法式是做为通俗用户运行的,而驱动只能由系统用户读写。
相反,利用法式必需通过绑定器驱动法式与系统办事器停止通信(关于利用法式拜候绑定器的手艺细节被Manager类所隐躲)。 因为绑定器是做为内核模块运行的,它能够向系统办事器证明挪用利用法式的用户ID(也就是说,利用法式不克不及伪造它的ID)。然后,系统办事器查抄挪用法式能否有权拜候该资本(即有准确的Android权限)。假设没有,那么系统办事器就会抛出一个反常,通信完毕。假设它有,系统办事器就会与驱动法式对话,获取信息并将其送回给挪用者利用法式。因为系统办事器是以系统用户身份运行的,所以容许对驱动法式停止拜候。
安卓权限
权限被分为四类或权限级别:一般、求助紧急、签名和签名或系统。一般权限庇护对用户来说风险较低的资本(例如,读取电池形态的权限)。求助紧急权限庇护的是那些一旦被窃取就会对用户形成损害的资本(如联络人列表)或使其缺失的资本(如发送短信)。安卓系统只授予利用法式一个签名权限,假设它的签名与声明该权限的利用法式所利用的签名具有不异的认证。安卓系统只授予利用法式签名或系统权限,前提是它与声明权限的利用法式的签名证书不异,或者该利用法式在安卓系统镜像中。
Android 4.2定义了200个权限。此中,29个权限级别为一般,47个权限级别为求助紧急,63个权限级别为签名,61个权限级别为标记或系统。在理论中,大大都时候,开发者只处置一般和求助紧急权限(29+47=76个权限)。
2.2 静态阐发简介
时髦的编程语言,如Java,利用类和办法来表达现实世界的概念,并别离操做那些概念(即改动其形态)。对利用类和办法构建的法式停止静态阐发,能够利用法式内办法(即逐个办法)或法式间办法(即把办法毗连在一路,把法式做为一个整体停止阐发)。后面的办法需要毗连办法。那能够通过计算法式的挪用图来实现。
在本节中,我们将介绍挪用图的构造,并着重介绍面向对象的语言,特殊是Java语言,因为我们在第四章和第五章平分析了那种语言的代码。
2.2.1 挪用图
在面向对象编程中,法式是由类构成的。每个类代表一个概念(如汽车),有一组表达其他对象(如车轮)的单位和一组包罗操做对象的代码的办法(如驱动汽车前进)。 代码能够挪用其他办法来创建对象的实例或把持现有对象。
一个法式凡是以一个喊做主办法的单一进口点办法起头。 通过火析主办法的代码,我们能够找出它在挪用哪些办法。然后,通过火析被挪用办法的代码,我们能够找出它/它们在挪用什么办法。只要有办法挪用其他办法,那个过程就能够反复停止。
其成果是一个有向图,称为挪用图,它将办法联络在一路。 该图从代表主办法的节点起头,通过被挪用的办法向下扩展。
图2.7阐了然一个Java法式的挪用图生成过程(a)。 有两个Java类,MyObject和MyOtherObject。法式的起点是MyObject中的main办法。那个主办法也是挪用图的起点(b)。主办法起首通过挪用MyOtherObject的构造办法(Java中的init办法)创建一个实例。 然后它在新创建的对象上挪用办法method1和method2。办法1不挪用其他办法,只挪用本身。办法2只挪用大小。办法3不克不及从主办法中抵达,因而没有呈现在挪用图中。
切确性
继续和多态 面向对象的语言,如Java[61],利用了诸如继续和多态的概念。图2.8阐了然那两个概念。继续是对一个笼统概念(那里是笼统的动物类)停止建模,然后将那个笼统概念扩展到那个笼统概念的详细元素(那里是人类和猫类)的才能。那个笼统概念通过行走办法定义了一个行为。人类和猫咪都在行走,但它们以差别的体例在本身的行走办法中描述。
假设我们用Java语言成立一个由猫和人构成的世界。我们将把对猫和人的每一个引用存储在一个动物的容器中。 动物通过迭代容器中的元素并对其挪用行走办法来停止行走。当施行那段代码时,假设动物是人类,对动物的行走办法挪用将被重定向到Human .walk,假设动物是猫,则重定向到Cat .walk。为差别品种的实体供给一个单一的接口被称为多态性。在阐发一个Java法式时,处置多态性的体例对挪用图的精度有间接影响。
流程灵敏度 流程灵敏度阐发考虑到了语句的挨次。以图2.9a的代码片段为例。在第二行,一个新的Human实例被创建,并被动物引用a引用。在第三行,办法walk被挪用到a上。那意味着在施行时只要办法Human .walk在第三行被挪用。 在第四行,a如今引用了一个新的猫的实例。在第三行,一个ow-sensitive阐发给出了a只指向一个Human对象,而不是一个Cat对象。 因而,ow-sensitive挪用图包罗一条通往Human .walk的边。另一方面,一个不灵敏的阐发给出了a可能指向Human或Cat对象,因为它不考虑语句的挨次。关于一个不灵敏的阐发,在第二行和第三行之间有第四行的法式会得到同样的成果。因而,ow-insensitive挪用图包罗两条边:一条指向Human .walk,另一条指向Cat .walk。
途径灵敏性 途径灵敏性阐发将施行途径考虑在内。 以图2.9b的代码片段为例。 在第二行,动物引用a指向没有对象。假设第三行的前提为实,a指向一个新的人类对象(第四行)。假设第三行的前提为假,a指向一个新的猫对象(第六行)。对那个例子停止途径灵敏的阐发会产生两条途径:途径1 , l2 -l3 -l4 -l8,和途径2 , l2 -l3 -l6 -l8。在第八行,path1有一个指向Human对象的指针,因而办法Human .walk在挪用图中。途径2有一个指向猫对象的指针,因而办法Cat .walk在挪用图中。对途径不灵敏的办法不考虑途径,在第八行会有一个指向Human对象和Cat对象的指针。因而,对途径不灵敏的挪用图将包罗Human .walk办法和Cat .walk办法。 一个对途径灵敏的办法能够为每一个可能的途径产生一个图。途径的数量会呈指数级增长,那种办法也就不具有可扩展性。
场灵敏度 场灵敏度办法对每个对象的每个场停止建模。以图2.9c的代码片段为例。 在第二行,c1指向一个新的C对象。 那个对象包罗两个动物字段。在第三行,第一个字段,f1,指向一个新的人类对象。在第四行,第二个字段,f2,指向一个新的猫对象。 一个对字段灵敏的阐发为每个对象的每个字段建模。因而,在第i行,f1的模子只能指向一个Human对象,而且只要Human .walk办法在ield灵敏的挪用图中。基于字段的办法只对每一类对象的每个字段停止建模。 那意味着在那个例子中,ield c1 .f1和c2 .f1有不异的模子。因而,在第ive行,f1指向一个Human对象和一个Cat对象,Human .walk和Cat .walk那两个办法都在ield-不灵敏的挪用图中。 最初,请重视,一个不灵敏的办法只对 "对象 "停止建模。所有的元素都被聚合到它们响应的对象上。不灵敏的办法不太可能用于Java如许的语言,而只能用于具有类型不平安的指针操做的语言,如C。
上下文灵敏度 上下文灵敏度办法对办法被挪用的每个上下文停止建模。 对上下文停止建模的次要体例有两种:对挪用地点停止建模,那在本段中有所描述;对办法挪用的分配地点停止建模,也称为对象灵敏,鄙人一段中有所描述。以图2.9d的代码片段为例。在第二行,一小我类对象被实例化了。 变量h指的是那个对象。 在第三行,一个猫对象被实例化。变量c指的是那个对象。在第四行,用c挪用办法,该办法返回存储在a中的动物引用。在第五行,用h挪用办法,该办法返回存储在a中的动物引用。也就是说,关于第一个办法的挪用,参数模子指向c,返回值模子指向c;关于第二个办法的挪用,参数模子指向h,返回值模子指向h。另一方面,关于一个给定的办法,上下文不灵敏的办法只要一个参数模子和一个返回值模子。在上下文不灵敏的办法中,参数模子指向c和h,返回值指向c和h。因而,上下文不灵敏的办法在挪用图中既有Human .walk办法,也有Cat .walk办法。
对象灵敏度 对象灵敏度办法是一种上下文灵敏度办法,它区分了对差别对象停止的办法挪用。以图2.9e的代码片段为例。在第二行和第三行,两个Contains对象被实例化了。变量c1和c2指的是那些对象。Contains类有一个动物类型的实例ield animal和一个实例办法setAnimal,用于将一个值与ield animal联络起来。在第四行,办法setAnimal被挪用到c1,参数为Human对象。在第5行,办法setAnimal在c2上被挪用,参数是猫对象。最初,在第六行,办法walk被挪用到对象c1的animal ield。在第四行和第五行,一个对对象不灵敏的办法会认为c1和c2是统一个领受器。其成果是,第四行和第六行的办法挪用不克不及区分领受器,并将c1和c2做为一个特殊的含有类型的对象cu的模子。因而,在第六行对对象cu挪用的办法walk在挪用图中由两个办法表达: Human .walk和Cat .walk。另一方面,一个对对象灵敏的办法将为setAnimal的每次挪用别离成立c1和c2的模子。因而,第六行的挪用在挪用图中只由办法Human .walk表达。
不成知性 利用静态阐发来确定哪些指针在运行时能够指代哪些对象的问题是不成知的[77]。那意味着关于所有的法式来说,都无法计算出切确的处理计划(即,既合理又完全)。然而,存在许多守旧的处理计划。那些处理计划是合理的,因为它们计算的是 "实在 "成果的超近似值。正如我们在上面的段落中所看到的,它们在精度上是差别的(也就是说,有些办法比其他办法产生更多的假阳性成果)。例如,一般来说,上下文灵敏的办法比上下文不灵敏的办法更切确。
计算Java挪用图的算法
Java是一种面向对象的语言,撑持多态性。因而,在停止法式静态阐发时,办法被挪用的对象确实切类型(那种对象也被称为领受器)可能其实不为人所知。鄙人面的段落中,我们将介绍一些静态地构建Java法式挪用图的算法。
CHA 第一种办法喊做类条理阐发(CHA),由Dean等人提出[39]。该办法长短常守旧的,它假定关于一个给定的领受器,领受器的声明类型T以及T的所有子类型(例如所有子类)在运行时都是可能的类型。例如,当在一个法式上运行CHA时,该法式有一个对动物类型的领受器r的办法挪用walk(),CHA假定动物、人类和猫在运行时是r的可能类型。即便在阐发的法式中没有实例化的猫对象,情状也是如斯。
RTA 后来,Bacon等人提出了一种喊做快速类型阐发(RTA)的办法[10]。那种办法与CHA类似,但是只要在被阐发的法式中创建了T类型的对象时,才会将T类型视为可能的类型。例如,当对一个有办法挪用walk()的法式运行RTA时,RTA假设动物、人类和猫在运行时是r的可能类型,当且仅当人类和猫的对象在阐发的法式中的某个处所被创建。
VTA Sundaresan等人[126]后来提出了另一种办法,称为可变类型阐发(VTA)。那种办法比CHA或RAT更切确,因为它只考虑能抵达领受器的类型做为可能的类型。
Andersen Andersen算法[2]的Java扩展[83, 110]停止了对字段灵敏的基于子集的点到阐发。点到阐发描述了一个指针表达式可能指向哪些内存位置(即部分变量、全局变量和动态分配的内存)。一个挪用图几乎能够间接从点到阐发的成果入彀算出来。如上所述,一个对字段灵敏的办法对每个创建的对象的每个字段停止零丁建模。给定一个语句,如a = b,一个子集办法增加了以下约束:a ⊇ b。那意味着b的点到集是b的点到集的一个子集。该算法搜集了所有如许的约束,并利用一个工做表来处理那些约束并为所有指针构建点到集。在现实的Java法式上,类似Andersen的指针阐发的最坏情状下的复杂度是四次方的[122]。
Steensguard 与Andersen的算法相反,Steensguard的算法[124]是基于平等的。那意味着,它利用的不是子集约束,而是平等约束。 那个约束意味着a的点到集与b的点到集不异。那个办法不如Andersen的切确,但更具有可扩展性(接近线性时间复杂度[124])。
其他办法 其他点对办法已经被开发出来[135, 119, 134, 64, 65],以进步Andersen引进的基于子集的点对阐发的效率,或者进步Steensguard引进的基于平等的点对阐发的精度。有兴致的读者能够参考[80],领会那些办法的概略。
2.2.2 数据流阐发
法式内阐发
数据流阐发[1]是一种在法式的每一个点上计算一组可能的值的手艺。 那组值取决于利用数据流阐发所要处理的问题的品种。 例如,在到达定义问题中,人们想晓得在每个法式点上可到达的定义(例如,int x = 3;如许的语句)的聚集。 在那个特定的问题中,法式点P的可能值聚集是抵达P的脱式聚集(即变量在抵达P之前没有被赎回)。以图2.10为例。第二行的定义抵达第三和第四行,但没有抵达ive,因为变量x在第四行被从头定义。第三行的删除抵达第四行和ive。第4行的删除抵达第ive行。
数据流阐发利用一个方程系统来计算每个法式点或语句的信息。 每个语句都有一组可能的值,称为in,它代表了语句之前的有效信息。每条语句都有一组可能的值被喊出来,那代表了语句之后的有效信息。每个语句都有一个方程,描述语句对in集的影响。语句Stmt能够创建由Stmt.gen表达的新的可能值,并杀死现有的值,由Stmt.kill表达。
图2.11表达图2.10第4行的语句。那个语句S有一个in集,包罗两个deinitions x = 1; 和y = 2; 那是抵达第四行的语句的deinitions。请重视,关于一个有多个前置语句的语句,in集被定义为所有前置语句的out集的结合: S.in = ∪p 2 predecessorsp.out。语句S产生了一个新的定义,x = 3;,并杀死了in聚集中的变量x的定义。 语句S的那种行为用等式S.out = S.gen ∪ (S.in / S.kill)表达。函数f S.out = f(S.in)被称为转移函数(也能够称为ow函数或数据-ow函数)。
前向和后向 达成定义的问题是用前向阐发来处理的。那意味着阐发从法式的第一条语句起头,不断向前走,曲到抵达法式的起点。其他问题则摘用后向阐发法处理,即从最初一条语句起头阐发,并向后逃溯到第一条语句。
法式间阐发
到目前为行,我们不断在研究法式内(即在单个办法内)的数据运算阐发。法式间阐发则是对相连的法式(或Java中的办法)停止阐发。正如我们在第2.2.1节中所看到的,计算一个挪用图能够得到关于办法是若何毗连的信息。
为了阐明法式间阐发,我们依靠法式间有限散布子集(IFDS)框架[106]。IFDS框架通过将问题转化为图-可达性问题,在多项式时间内处理问题。用于处理该问题的算法被称为 "造表 "算法。它比以前的办法,如 "迭代 "或 "挪用字符串 "算法[87]有所改进,后者在最坏的情状下可能需要指数时间。
IFDS 以图2.12为例。 那个例子来自[106],阐了然法式间可能未初始化的变量的数据流问题。 在那个例子中,我们假设办法read(a)是一个系统办法,读取一个整数并将其存储在部分变量a中,办法print(a,b)是一个系统办法,在屏幕上打印出整数a和b的值。图2.12b别离表达办法main和p的掌握ow图。
图2.12代码的挪用图展现,办法main在第6行挪用办法p,办法p在第13行挪用本身。每个办法的挪用由两个节点表达:挪用节点c和返回点节点r。通过添加三条边来毗连那些办法:一条从c到r的法式内边,一条从c到被挪用办法起头节点的法式间边,一条从被挪用办法退出节点到r的法式间边。图2.12中的例子的超图表达在图2.13中。
可能未初始化的变量的数据流事实集是每个办法中可用的部分和全局变量集。办法main有部分变量x和全局变量g。办法p有部分变量a和全局变量g。每个语句对数据流事实集的影响由图中每条边的函数表达。例如,read(x)的效果是初始化变量x,该函数用λS表达。(S-{x})。那意味着数据流事实的输出集是输进集S,此中元素x被移除。事实上,因为x如今被当前语句初始化了,它能够从潜在的未初始化的变量聚集中删除。类似地,语句a = a - g由函数λS表达。假设((a∈S)或(g∈S)),那么(S∪a),不然(S -{a})。那意味着,假设a或g在输进集中,输出集就是输进集加上元素a(即a也是无因的)。不然,输出集是输进集,此中的元素a被移除(即a和g都没有被剔除,所以a的新值不克不及被剔除)。
IFDS框架将每个ow函数f表达为一个包罗以下边集的图: {(0, 0)} ∪ {(0, y) | y∈f(∅)} ∪ {(x, y) | y∈f(x) and y f(∅)}。 上一段描述的两个函数在表2.1中被表达为图形。一旦所有的函数都被表达成紧凑的图,它们就能够被组合起来构成爆炸的超图。图2.14阐了然爆炸的超等图。该图将IFDS问题转换为图-可及性问题。 简而言之,假设爆炸超图的一个节点能够从主办法的进口节点抵达,那意味着与之相关的数据流事实成立。例如,办法main中语句p(x)的变量g的节点能够从main办法的enter节点的0处抵达。那意味着在main办法中的语句p(x),变量g有可能是未初始化的。
IDE IFDS框架处置的问题是:数据流事实集D是有限的,数据流函数在2D→2D中。那个框架足以处理诸如 "到达定义"、"可用表达式 "或 "可能未初始化的变量 "等问题。然而,有些问题如 "线性常数传布 "问题不克不及用IFDS框架来编码,因为数据流事实的聚集是无限的。
法式间散布式情况(IDE)框架[111]处理了法式点上的数据流信息由 "情况 "表达的问题。换句话说,数据流事实是从一个有限的符号集D到一组值L的映射。那种映射被称为情况,并被称为Env(D, L)。数据流函数被称为 "情况转化器",其形式为Env(D, L) Env(D, L)。
IDE框架是IFDS框架的归纳综合:所有IFDS问题都能够表达为IDE问题,但并不是所有IDE问题都能够表达为IFDS问题。一个IDE问题能够由一个超图G(关于一个给定的法式,IDE超图与IFDS超图不异)、一组法式符号D、一个半晶格L和一个情况变更器对G的边的分配来表达:M:E→(Env(D, L) Env(D, L))。
2.3 结论
在本章中,我们起首介绍了Android系统和Android利用的构造。那些范畴的常识关于足够理解第4、5和6章是需要的,那些章节的办法老是利用于Android框架或Android利用。然后,我们介绍了静态阐发的概念,如挪用图构建或法式间阐发。挪用图构建是第四章中介绍的Android框架阐发的根底,而第五章则次要依靠于法式间阐发。
第三章
Dexpler:将Dalvik字节码转换为Jimple以实现Android利用法式的静态阐发
本章的目标是使Android利用法式的静态阐发成为可能。 本章介绍了Dexpler那个软件模块,它将Dalvik字节码(即Android利用法式的代码)转换为Jimple。Jimple是Soot的内部代码表达,是最时髦的基于Java法式的静态阐发东西之一。将Dalvik字节码转换为Jimple可以对Android利用法式停止静态阐发和转换。
本章是基于已经颁发在以下论文中的工做:
- Alexandre Bartel, Jacques Klein, Yves Le Traon, and Martin Monperrus. Dexpler:将安卓dalvik字节码转换为jimple,用于soot的静态阐发。 在ACM SIGPLAN的Java法式阐发手艺形态国际研讨会(SOAP@PLDI)上,2012年。
3.1 简介
Android利用法式是用Java编写的。然而,它们不是以Java字节码的形式发布的,而是以Dalvik字节码的形式发布的。阐发Android利用法式的一种可能性是利用Dalvik反汇编法式,如Smali [62] 或Androguard [41]。然而,它们并非为施行高级静态阐发而设想的,好比数据流阐发,并且它们凡是利用本身的字节码表达,那使得它们无法利用现有的东西来施行阐发。 此外,用现有的Java静态阐发东西来阐发Android利用法式意味着必需有Android利用法式的Java源代码或Java字节码。
大大都时候,安卓利用的开发者其实不分发他们利用的源代码,使得现有的Java法式阐发东西无法对安卓利用停止阐发。那对歹意软件的利用来说出格如斯,因为它们的源代码几乎是不成用的。
阐发Android利用法式的另一种可能性是起首将Dalvik字节码转换为Java字节码,利用Ded[47]、Dex2jar[99]或undx[115],然后利用Java定造的静态阐发东西,如Soot[131]、BCEL[35]或WALA[70]。产生Java字节码的东西能够操纵现有的Java字节码阐发器。然而,从Dalvik到Java字节码的转换需要时间,能够通过间接将Dalvik字节码转换为东西的内部表达来制止。
为了征服那些限造,我们引进了Dexpler1,那是Soot的一个模块,它间接读取Dalvik字节码,将其转换为Jimple,即Soot的内部代码表达法,并对Jimple表达法的部分变量停止完全类型化。然后,任何静态阐发和/或转换都能够利用于Jimple表达。 利用那种办法消弭了从Dalvik到Java字节码的中间转换步调,能够利用更快更简单的东西链停止静态阐发。
本章的奉献如下:
- 我们描述了一个喊做Dexpler的Dalvik到Jimple的转换东西
- 我们描述了一种对Dalvik字节码停止分类的算法
- 我们在超越2.5万个Android利用法式上评估了Dexpler。
本章的提醒内容组织如下。第3.2节是对Dalvik字节码的概述。在第3.3节中,我们描述了Dexpler,那个软件使Soot可以阐发Dalvik字节码。在第3.4节中,我们在超越2.5万个Android利用法式上评估了Dexpler,介绍并讨论告终果。第3.5节阐了然我们东西目前的局限性。最初,我们在第3.6节中总结了本章并讨论了开放的研究挑战。
3.2 Dalvik字节码和它的特殊性
一个Android利用法式是一个包罗利用法式字节码的压缩包,描述利用法式构造的An- droid清单,它需要的组件和答应,以及数据文件(例如,图片,声音)。 在本节中,我们存眷的是包罗利用法式的Dalvik字节码的ILE,参照ILE名称的扩展,也称为dexILE。即便原始的Android利用法式是用Java编写的,在Android利用法式中也找不到Java字节码。Java代码起首被编译成Java字节码,然后由dx东西2转化成Dalvik字节码。利用Dalvik字节码背后的原因是,它是基于存放器的,并为运行在内存和处置才能不敷的设备长进行了优化。 dex ile的构造在第3.2.1节中描述。第3.2.2节介绍了Dalvik指令。然后,在第3.2.3节中阐了然Dalvik字节码的规格。
3.2.1 整体构造
在本节中,我们起首描述了Java类的构造。然后,我们描述从Java类中生成包罗所有Dalvik类的dex ile的过程。
Java类 如图3.1a所示,每个Java类只要一个贮存常量值的处所(常量池)。在Java中,常量池是异量的,因为差别类型的对象是混合的(例如,类,对办法的引用,整数,字符串)。 每个Java类都包罗一个常量池。
Dalvik类 一个Dalvik可施行文件是由dx编译器处置的N个Java字节码类生成的。产生的Dalvik字节码被存储在一个.dex ile中,如图3.1b所示。dex ile包罗对Dalvik类的描述(名称、元素、办法...)和Dalvik字节码(代表详细办法代码的构造)。此外,dex ile包罗四个同量常量池:字符串、类、字段和办法。所有的Dalvik类都共享那四个常量池。此外,一个.dex ile包罗多个Class Dehni- tions,每个都包罗一个或多个Method dehnition。每个Method dehnition都与存在于数据部门的Dalvik字节码指令相联络。
3.2.2 Dalvik指令
Java虚拟机是基于仓库的。那意味着操做数是根据指令的语义从仓库中推送和弹出的。另一方面,Dalvik虚拟机是基于存放器的。那意味着大大都指令指定了它们所操做的存放器的名称。那使得Dalvik字节码在语法上接近于Jimple代码,因为Jimple也利用基于存放器的代码表达。图3.2.a表达Java字节码,此中值被推到仓库,而图3.2.b表达Dalvik字节码,此中值被分配到存放器v0和v1。
在Dalvik操做码常量列表中,有237个操做码。然而,12条odex(opti- mized dex)指令不克不及在Android利用法式的Dalvik字节码中找到,因为它们是在Android系统中生成的不平安指令,用于优化Dalvik字节码。 此外,还有8条指令从未在利用法式代码中被发现[94]。根据那些数字,在现实利用中很可能只要217条指令。
那组指令能够分为供给其操做的存放器类型的指令(例如,sub -long v1, v2, v3增加两个长存放器并将成果存储到一个长存放器)和不供给类型的指令(例如,const v0, 0xBEEF在存放器v0中存储一个不决义类型的值)。此外,null和0之间没有区别,它们都被表达为0值。
3.2.3 基元和空值
在那一节中,我们强调了Dalvik字节码的特征,那些特征对字节码存放器的类型解析有影响。请重视,当我们提到Dalvik字节码变量时,我们利用术语存放器,当提到Jimple变量时,我们利用术语部分或变量。
基元
在Java字节码中,基元变量是由一条指令初始化的,该指令规定了它的类型(例如,int, oat, long, double)。但在Dalvik中却不是如许,常量的初始化没有类型信息。图3.3中的代码片段凸起了Java和Dalvik字节码之间的差别。在Java中,类型能够在每条指令中确定:整数常量是通过整数的特殊指令初始化的,而燕麦常量是从常量池中加载的,它们被标识表记标帜为恰当的类型(例子中的燕麦)。然而,在Dalvik中,类型信息无法在常量初始化指令中确定。然而,关于算术操做,Dalvik利用指令来指定操做数的类型。存放器的类型也能够在它做为办法参数时被确定,因为每个被挪用的办法的符号城市展现其参数的类型。简而言之,当阐发Dalvik字节码时,只要当存放器被利用时才气确定由常量初始化的存放器的类型。
此外,在Dalvik中,Oat和整数常量都是以32位编码的。如图3.4所示,假设一个存放器被32位常数初始化,那么该存放器的利用仍然需要被阐发以确定存放器的类型。同样的,long和double常量都是以64位编码的。因而,一个64位的常数分配给一个存放器其实不能间接给出存放器的类型。然而,阐发存放器的利用体例将给出存放器的类型。
空值
Null被分配给一个对象的引用,表达它没有引用。在Java字节码中,Null是通过一个特殊的加载常量指令(见图3.2.b)和两条if指令来处置的,以查抄一个对象引用能否为null或非null。在Dalvik字节码中,没有如许的指令:null被表达为整数值0。查抄一个对象引用能否为空或者非空包罗查抄对象引用能否是一个等于零或者差别于零的整数。图3.2表白,在Java源代码(a)和字节码(b)中,0和null之间有明显的区别,而在Dalvik字节码(c)中,底子没有区别。正如我们将在第3.3节中看到的,在将Dalvik字节码翻译成Jimple时,欠缺类型和null的表达办法就成了问题。
3.2.4 反常
在Dalvik和Java字节码中,字节码包罗反常处置法式。处置法式是办法的字节码中的一组特殊指令,现代码的某个部门抛出反常时,虚拟时机挪用它。不处置Dalvik反常的特殊性就会招致代码无法打码。 那就是为什么我们在类型化过程中利用Dalvik的特殊反常模子,而不是原始的Java反常模子。
在构建办法的CFG时,我们必需从可能抛出反常的指令中添加边,以获得准确的反常处置法式的第一条指令。在Dalvik中处置反常的体例几乎与Java不异,但也有一些区别。在Java中,从一个办法返回的指令能够抛出一个反常,但在Dalvik中却不克不及。存储一个类常数和一个字符串常数的指令在Java中能够抛出反常,但在Dalvik中不克不及。关于数组,Dalvik只在索引超出范畴或在数组引用上有一个空指针的情状下抛出数组指令的反常。
反常处置能够被认为是一个手艺细节。然而,假设处置不妥,就会毁坏代码中变量的类型。 考虑一下图3.5中的代码。假设在label1和label2之间的指令能够抛出一个反常,就会挪用label handler的处置指令。throw v4指令就是那种情状。假设Dalvik的返回指令被当做Java字节码的返回指令来处置,在CFG中就会有一条从返回指令之前的指令(即v1=Object getObject)到反常处置法式的边沿。那个边在图3.5中以虚线箭头表达。在那种情状下,当存放器v1在处置法式中被利用时,其类型可能是int(来自getInt办法)和Object(来自getObject办法)。我们不成能获得那段代码的类型。
3.3 从Dalvik到类型化的Jimple代码
本节介绍Dexpler,Dalvik到Jimple的转换东西。 它操纵Smali反汇编法式中的dexlib2库[62]来解析Dalvik字节码,并操纵Soot快速打字,那是一个实现类型推理算法的Jimple组件[17],来给部分变量打字。然而,类型推理算法在从Dalvik字节码天然生成的Jimple代码上不起感化。我们在第3.3.1节中描述了那个类型化问题。然后,我们在第3.3.2节中描述Dexpler若何处理那个问题。
3.3.1 翻译的要求
图3.6表达Dalvik字节码的类型网格。 请重视,因为Dalvik字节码中的常量类型不为人所知,所以存在32位和64位的ab-stractions: 32位常量能够是Oat、char、short、byte、boolean或int类型(回忆图3.3,初始化指令不供给类型信息),64位常量是double或long类型。图3.7表达Java字节码的类型网格。在Java字节码中,oat、double、long和int的常量是通过指令指定其类型来初始化的。此外,在只能分配给对象的null和能够分配给int-like类型的值int 0之间有明显的区别。
我们的目标是将Dalvik字节码转换为Jimple,然后消弭类型的模糊性,以便现有的类型化算法可以完全对代码停止类型化。 为了实现那一目标,我们考虑了图3.8所示的Dalvik类型网格的简化版本。 现有的类型化算法,如[18],能够对对象和int的子类型停止类型化,所以我们没有在简化的网格中完全表达它们。 我们想从图3.8中的格子(代表Dalvik字节码中的类型)到图3.9中的格子,在那里类型之间不克不及有歧义。
更切当地说,我们要区分(1)做为null的0和做为整数值0的0,(2)做为整数的32位常量和做为燕麦的32位常量(3)做为双数的64位常量和做为长数的64位常量。
一旦变量的类型与图3.9所示的格子相婚配,类型的局限性就被消弭了,完全的类型化算法就能够用来对变量停止完全类型化。
图3.10阐了然将Dalvik字节码转换为Jimple代码并停止类型化的过程。 起首,原始的Dalvik字节码(1)被dexlib23库解析,每个指令都被反汇编(2)。 从那个中间表达法中,生成不决型的Jimple语句,并将其毗连起来,构成掌握流图(CFG)(3)。下一步(4)是处理模糊的类型。 最初,在步调(5)中,利用Bellamy等人[18]提出的有效的部分类型推理算法对所有Jimple部分停止类型化。步调(5)被用来验证我们的办法。下一节将详尽描述步调(4)。
3.3.2 模糊的类型解析
我们在第3.2.3节中看到,以下指令欠缺类型信息:零值常量初始化指令(是零仍是空?)和常量初始化指令(32位:整数仍是燕麦?,64位:长仍是双?) 下面通过看那些指令在代码中的利用情状来阐明我们若何对那些指令的存放器停止打字。
空值初始化 图3.12用图3.11的Java代码生成的字节码片段阐了然那个问题。 存放器v0在第01行被初始化为0。 在那一点上,我们不晓得v0是一个整数、一个燕麦或一个对象的引用。在第02行,我们仍然没有得到谜底。我们必需比及第04行的指令才晓得v0的类型是Coordinate。 在那一点上,为01产生的Jimple指令必需被更新为一个空常数,而不是默认的数值为0的整数常数。 假设那一点没有得到准确处置,打字组件就会失败。 事实上,存放器v0不成能既是一个整数又是一个坐标类型的对象。
数字常量的初始化 同样地,Oat常量的初始化不克不及与int常量的初始化区分隔来,双倍常量的初始化不克不及与long常量的初始化区分隔来。因而,我们通过Jimple语句的图形来领会常量的利用情状,并在需要时纠正Jimple语句的初始化。例如,假设一个oat/int常量(在Jimple语句中默认初始化为int)后来被用于一个oat加法,常量的初始化就会从int常量变成oat常量。
算法
我们的算法能够分为三个步调,依次施行:
1. 阵列类型传布步调
2. 空与零的区分步调
3.整数版本的微分和长数与双数的步调
第1步:数组类型传布 关于每一个不决型的常数,我们要看的是用一个常数值初始化的部分变量的利用。部分能够存储在一个字段中,做为一个办法参数利用,并存储在一个数组中。 关于字段和办法,常量的类型是已知的,因为字段签名和办法签名供给了足够的类型信息。另一方面,关于一个数组来说,类型信息其实不老是已知的。一个典型的例子是当数组被别号时(即分配给另一个部分)。
为了传布类型信息,我们从数组初始化语句起头。 关于每一个如许的语句,我们都要确定命组的利用位置。假设数组被别号,我们将类型信息从数组转移到新的部分。 当抵达一个ix点时,所有当地引用的数组都被类型化了。
第二步:null和Zero 关于那一步,我们设想了第50页的算法1。该算法从办法nullOrZero(第1行)起头。 该算法起首搜集语句,用一个值为0的整数来初始化部分变量(第3行)。 然后,关于部分变量的每一次利用,办法forEveryUse为部分变量的类型集(第5-6行)增加一个类型,要么是 "做为对象利用",要么是 "做为整数利用"。假设一个部分变量的所有类型纷歧致(即它们不都是一样的),那么在该办法的字节码中就会呈现类型纷歧致的情状,使其无法对字节码停止打字。在那种情状下,算法以错误代码完毕(第8行),施行算法的代码会用一个默认的代码块来替代办法代码,那将抛出一个运行时反常。 另一方面,假设所有的类型都是一致的,那么部分变量的定义也会响应地被更新:假设常量被用做对象,那么零值会被替代为null(第10行)。
更切当地说,forEveryUse办法起首搜集了当地变量定义d的所有利用(第16行)。关于每一次利用,它查抄利用类型能否是一个对象或不是一个对象。假设能够确定利用类型,该类型将被添加到之前定义的类型聚集中(第19行)。 假设不克不及确定利用类型,有三种可能性。 第一种可能性是,正在考虑的语句是一个别号语句。在那种情状下,别号部分变量被获取,forEveryUse办法被再次挪用。第二种可能性是所考虑的语句是一个if语句。假设if语句的前提包罗另一个部分,办法collectDefinitionsWithAliases就会被挪用,同时挪用另一个部分。望文生义,那个办法搜集了做为参数的部分的所有定义。它查抄所有定义的类型,也查抄那些定义的所有用处。最初一种可能是,算法没有为语句找到任何有效的类型。在那种情状下,类型被设置为未知类型。在利用语句的轮回完毕之前,会挪用搜集办法--DefinitionsWithAliases。 那在没有足够信息对当前阐发的部分变量停止类型的情状下很有用。 事实上,算法能够通过查看部分变量的所有定义,以及查看那些其他定义是若何被利用的,来获得更多关于其类型的信息。
办法collectDefinitionsWithAliases是以一个部分变量为独一参数挪用的。它起首搜集当地变量的所有定义(第38行)。关于每个定义,它查抄部分能否被定义为一个对象(第40行)。假设找到了一个类型,就把它添加到类型聚集中(第42行)。不然,它将查抄该定义能否是一个别号誉明。假设是,它检索别号并递回挪用带有别号的collectDefinitionsWithAliases(第44-45行)。不然,假设该语句是一个零常数定义,则不添加类型,因为此时零常数的类型是未知的(第47行)。在所有其他情状下,未知类型被添加到类型聚集中。最初,该办法挪用forEveryUse来查抄所有定义的所有用处的类型(第51行)。
第3步:Float vs. Int和Long vs. Double 在第1步和第2步之后,假设零整数常量被用做对象,它们已经被转换为空。在那一点上,我们仍然要准确输进32位常量(Oat和int)和64位常量(long和double)。那个办法与第2步十分类似。算法1能够在稍做改动后反复利用。办法getZeroDefs被办法getNumDefs代替,后者返回部分变量被分配了一个数字常数的定义(第3行)。办法isObjectOrNot_Use和isObjectOrNot_Def别离被办法checkNumType_Use和checkNumType_Def代替(第19行和第40行)。那两个新办法别离返回部分变量的use类型和def类型。办法areTypesConsistent查抄所有类型能否不异,要么是全燕麦、全int、全long或全double(第7行)。最初,办法correctDefs根据准确的利用类型来更新定义。
第4步:完全类型解析 一旦常量定义之间的歧义得到处理,就能够运行Java代码的传统类型化算法。 我们利用Bellamy等人[17]所介绍的算法。在那个过程完毕时,一个办法的代码就完全类型化了。
3.4 评估
我们在27,846个从Google Play下载的Android利用法式上评估Dexpler。那些利用法式总共有135,289,314个办法。此中,37,720,245(28%)个办法有一个数字零常数的定义语句。图3.13表达每个利用法式中含有数字零常数的办法的比例。总共有27,682个(99.41%)利用法式包罗数字常数。那一成果表白,在阐发Android利用法式时,处置数字常数是必需的。
那27,846个利用法式散布在卢森堡大学高性能计算(ULHPC)的100个节点上[132]。处置时间加上元数据(如每个办法的大小,每个办法的处置时间)在数据库中的存储需要36小时。
Dexpler为135,288,415(99.99%)个办法准确输进了变量。因为Soot产生的反常,Dexpler未能对56个(0.20%)利用法式和它们的所有办法停止阐发。关于135个办法,步调(5)没有胜利运行。
3.4.1 关于失败利用的讨论
在27,682个利用法式中,56个(0.20%)没有被Dexpler准确处置。13个(23%)是由我们的利用法式爬虫中的错误或由无效的魔法数字产生的非有效的Android利用法式。五个(9%)是因为内存不敷的反常。6个(11%)是因为无效的ield引用,32个(57%)是因为字节码包罗无效的指令(例如,virtualinvoke而不是interface-invoke或interface-invoke而不是virtual-invoke 4)。
没有通过步调(5)的135个办法有一个类似的特征:它们都有在多个分收中利用差别类型的变量。例如,一个初始化为0的变量能够在第一个分收中做为一个整数利用,而在第二个分收中做为一个空引用利用。处理那个问题的办法之一是沿分收传布变量的定义,并删除原始定义。那将产生两个变量,每个变量都有本身的类型。
3.5 局限性
虽然我们的算法在我们阐发的2.5万个利用法式中99%以上都能工做,但是它还不克不及处置一些情状(除了第3.4.1节中的情状)。
3.5.1 无效字节码从未被施行,也从未被虚拟机查抄过
Dalvik虚拟机(DVM)只在运行时需要时查抄类的有效性。因而,进攻者能够创建一个包罗无效字节码办法的假类。那个类不会被利用法式自己利用,所以它不会被DVM查抄,利用法式能够胜利安拆在设备上。然而,阐发利用法式字节码的东西,如Dexpler,将阐发无效的字节码,因为它不晓得那个类在运行时能否被利用。假设Dexpler不ind一个办法的有效类型,它就会用指令替代代码,抛出一个反常。
3.5.2 绕过虚拟机验证的无效的Dalvik字节码
Bremer[24]已经证明,有可能编写不被DVM查抄的Dalvik字节码。那个概念证明操纵了DVM中的一个错误,该错误不查抄字节码,假设该类有一个特定的ag开启。那种字节码关于凡是由DVM施行的类型约束来说可能是无效的。那个错误影响到所有4.3以下的Android版本。其后果是,可能无法准确输进那种字节码。在我们的尝试中,我们查抄了该bug中利用的特定类ag,没有发现任何利用该bug的利用法式。
3.5.3 隐躲的字节码
在字节码之外。 一个Dalvik法式能够在运行时动态地加载Dalvik字节码。然后,进攻者能够将字节码隐躲在一个ile(如图片)中,并在运行时加载它。 因为那个字节码不存在于dex ile inding中,所以在哪里转换它。Dexpler只转换负责加载隐躲字节码的那部门代码。静态地确定隐躲字节码的位置已经超出了范畴。
在字节码内。 Schulz [117]提出了一种将Dalvik字节码隐躲在Dalvik字节码阵列中的手艺。 那可能会稠浊线性字节码阐发器,它们可能不会将数组内容准确阐明为有效的Dalvik字节码。 我们为每条分收指令查抄目标能否是有效的指令,而不是数组中的数据。我们历来没有发现一个分收指令指向数组中的数据的情状:在用于评估Dexpler的任何利用法式中,都没有利用那种稠浊的办法。目前Dexpler其实不处置那种稠浊的字节码。
3.6 结论
Dalvik字节码不克不及被现有的Java东西所阐发。在那一章中,我们介绍了Dexpler 5,那是一个Soot修改,能够将Dalvik字节码转换为Jimple,并容许静态阐发Android利用法式。Dexpler操纵Dalvik反常的模子来构建办法代码的切确掌握ow图,并操纵一种算法来处理类型不明白的变量。 该算法从识别具有模糊类型的变量起头,然后通过查看代码中那些变量的利用情状来揣度其现实类型。Dexpler已经对来自27,846个Android利用法式的135,289,314个办法停止了评估,并对99.9%的阐发办法的变量停止了完全类型化。
第四章
觅觅和消弭权限差距,削减Android利用的进攻面
本章的目标是查抄开发者能否给他们开发的安卓利用供给了太多的权限。削减权限的数量能够削减歹意用户操纵利用法式的进攻面。我们操纵Dexpler来阐发利用法式的代码,以查抄他们实正需要的权限。那需要深进阐发安卓框架,提取API办法(安卓利用法式挪用)和所需权限之间的映射。我们提出了一品种似于安徒生的、对范畴灵敏的办法,利用新的范畴特定的优化来从Android框架中提取映射。
本章基于已经颁发在以下论文中的工做:
- Alexandre Bartel, Jacques Klein, Martin Monperrus, and Yves Le Traon. 通过削减进攻面主动庇护基于权限的软件: 对An- droid的利用。在第27届IEEE/ACM主动软件工程国际会议(ASE)论文集,2012。短文。
- Alexandre Bartel, Jacques Klein, Martin Monperrus, and Yves Le Traon. 静态阐发提取大规模框架的答应查抄: 阐发Android的挑战息争决计划. 在IEEE Transactions on Software Engineering (TSE), 2014.
4.1 简介
挪动操做系统Android和黑莓的平安架构以及其他系统,如谷歌Chrome阅读器扩展系统,都利用类似的平安模子,称为基于权限的平安模子[11]。基于权限的平安模子能够松懈地定义为如许一种模子:1)每个利用法式都与一组容许拜候某些资本的权限相联系关系1;2)用户在安拆过程中明白承受权限;3)当资本被恳求时,在运行时间查抄权限。
在Android中,权限模子被嵌进到 "Android框架 "中。该框架公开了一个利用编程接口(API),此中包罗了供开发者与系统资本互动的类和办法。例如,API包罗一个getGPSLocation2办法,假设有的话,它能够供给智妙手机的当前GPS位置。那个API办法,以及其他许多办法,在平安或隐私方面是灵敏的。因而,在响应对getGPSLocation的挪用时,该框架会查抄挪用者能否已被明白授予GPS权限。
那种权限模子对利用法式的开发过程有影响。为了编写一个利用法式,开发人员必需为他们利用的每个API办法确定必需声明的权限,以便利用法式可以准确工做。他们需要一个API办法和所需权限之间的映射。
在安卓系统中,那种映射由官方文档供给。然而,那些文档其实不老是最新的或清晰的,因而,问答网站上充满了关于利用权限的问题3。那招致开发者经常低估或高估所需的权限。贫乏一个权限会招致利用法式瓦解。添加太多的权限则不平安。在后一种情状下,被注进的歹意软件能够操纵那些已声明但未利用的权限来到达歹意的目标。我们称那些未利用的权限为 "权限缺口"。任何权限缺口城市招致不平安的、可疑的或不成靠的利用法式。
总而言之,在Android如许一个基于权限的系统中,有一个清晰而切确的映射,将API办法和所需的权限联络起来,长短常有价值的。它使开发者可以轻松地声明他们现实需要的权限:不多也很多。
为了提取那个地图,我们在本章中切磋了利用静态阐发来提取每项使命的查抄。在Android那种规模和复杂性的框架中,利用现成的静态阐发的无邪办法会惨遭失败。本章讨论了为提取API办法和权限之间有价值的映射而必需组合在一路的构件,有两种阐发办法:基于类条理构造(CHA)和类似于安徒生[2]的场灵敏的阐发办法,即Spark[81]。 在手艺上,我们描述了在Android中提取每项使命查抄所需的五个组件。第一个是通用的字符串阐发,但关于权限不是静态常量而是动态字符串的安卓系统是必不成少的。其余的是专门针对Android的。在那四个组件中,最初两个组件是专门针对Spark的。办事重定向(Service Redirec- tion)将对办事的挪用重定向到一个准确初始化的办事(Android公用)。办事身份反转(Service Identity Inversion)制止阐发对办事的不相关的系统挪用(Android-speciic)。办事初始化准确地初始化办事以征服空值(Spark speciic)。 进口点初始化初始化所有进口点办法及其参数(Spark speciic)。那项研究的次要困难在于,因为安卓系统的规模和复杂性,没有任何一个构件能零丁产生可承受的成果。最末,我们表白Spark能够产生一个很好的API办法到权限的映射,并与相关工做[53, 6]停止了比力。
总而言之,本章的奉献是:
- 体味证明,现成的静态阐发其实不能处理像Android如许的框架的权限查抄的额外问题;
- 三个静态阐发组件(通用和Android公用)被组合在一路,以便在Android上利用类条理阐发(CHA);
- 两个静态阐发组件,容许人们利用场灵敏静态阐发(Spark [81])来阐发Android的权限;
- 将我们的成果与PScout[6]停止比力,PScout是一个与我们平行设想的静态阐发,与Felt等人的基于动态阐发的成果停止比力[53];
- 在两组1421个实在的Android利用法式上利用提取的映射,展现129个(9%)利用法式存在权限缺口,即它们拥有超越需要的权限。
本章的提醒内容组织如下。在第4.2节中,我们阐了然为什么削减进攻面很重要,并提出了一个撑持我们曲觉的简短研究。在第4.3节中,我们提出了一个基于答应的软件的形式化。在第4.4节中,我们描述了An- droid系统和它的拜候掌握机造。然后,在第4.5节中,我们利用静态阐发从Android系统中提取权限图。在第4.6节中,我们停止了尝试,并对成果停止了讨论。在第4.7节中,我们提出了一个通用的办法来推导出准确的利用法式权限集。最初,我们在第4.8节中总结了本章,并讨论了开放的研究挑战。
4.2 权限差距问题
如今让我们详尽介绍一下第1节中介绍的权限差距问题。我们还提出了简短的体味事实,表白那个问题在理论中确实存在。
权限差距的可能后果 让我们考虑一下appwrong,一个Android利用,它可以与外部办事器通信,因为它被授予了INTERNET权限。 此外,appwrong还声了然CAMERA权限,但它并没有利用任何与相机有关的代码。 CAMERA权限容许利用法式在没有用户干涉的情状下停止摄影,也就是说,权限差距由一个权限构成: CAMERA。不幸的是,appwrong利用了一个当地库,比来发现了一个缓冲区溢出的破绽。
因而,进攻者能够通过操纵缓冲区溢露马脚,在appwrong的过程中施行其抉择的代码。进攻者在appwrong中施行的代码被授予appwrong、INTERNET但也包罗CAMERA中定义的所有权限。那有效地增加了进攻者的权限。在那个特殊的例子中,进攻者将可以(1)编写代码来利用相机,拍摄照片并将照片发送到互联网上的长途主机,(2)通过操纵缓冲区溢露马脚在目标利用法式中施行那些代码。Davi等人[36]对那种进攻停止了详尽描述。
相反,假设appwrong不声明CAMERA,那种进攻就不成能发作,而缓冲区溢露马脚的后果也会得到缓解。正如Manadhata[85]所指出的,削减进攻面其实不意味着没有风险,而是削减风险。为了阐明那个错误设置装备摆设的利用法式的例子不是假的,我们如今讨论一个简短的实证研究,关于1000多个Android利用法式的两个权限的声明。
权限 "相机 "和 "灌音 "的声明和利用 我们对1000多个Android利用法式停止了一个简短的实证研究。
我们对从Freewarelovers利用市场下载的1000多个Android利用停止了简短的实证研究4。关于权限CAMERA和RECORD_AUDIO,我们搜刮了An- droid框架的源代码,以接近需要此中之一的办法集。那两组办法被称为MCAM和MREC_AUDIO。然后,我们计算了所有声明CAMERA或RECORD_AUDIO的利用法式的列表A。接下来,我们把每个利用app∈A零丁拿出来,通过火析利用的字节码,查抄该利用能否至少利用了MCAM和MREC_AUDIO的一个办法。假设没有,那意味着该利用法式没有利用响应的权限。当那种情状发作时,我们修改了声明该权限的利用法式清单,并再次运行该利用法式,以确保我们的搜刮近似值没有产生误报。
有7/82的利用法式声了然CAMERA,但没有利用它。 同样地,有3/35的利用法式声明但没有利用RECORD_AUDIO。那些成果证明了我们的曲觉:声明的权限列表其实不老是必须的,并且权限缺口确实存在。开发者将受益于一个能主动揣度出所需权限集和近似权限缺口的东西。
4.3 定义
基于权限的软件在概念上分为三层:1)核心平台(运行系统),它可以拜候所有的系统资本(例如,改动收集战略);2)中间件,负责为操做系统资本供给一个清洁的利用编程接口(API),并在利用法式要拜候它们时查抄它们能否有准确的权限;3)成立在中间件之上的利用法式。他们必需明白地声明他们所需要的权限。第2层和第3层是 "基于权限的软件 "那一通用标签的动机。因为中间件也隐躲了操做系统的复杂性并供给了一个API,它有时被称为 "框架",如Android的情状。如今让我们来定义一下那些术语。
框架 框架F是一个层,使利用法式可以拜候平台上的可用资本。我们将其建模为一个双向图,此中API办法节点聚集中的每个节点都毗连着资本节点聚集中的一个节点(该聚集还包罗一个 "无资本 "节点)。例子: 在图4.1中,该框架由九个办法构成(此中四个是公共的)。利用法式通过四个API办法拜候该框架。在Android的例子中,F是由4,071个类和126,660个办法构成的Android 4.0.1 Java框架。要拜候一个资本,Android利用法式必需通过F停止办法挪用。
权限 权限是一个利用法式拜候特定资本所需的令牌。例子: 在图4.1中,利用法式声了然两个权限。框架定义了三个权限,但只查抄两个。我们对权限不做任何假设,我们认为它们是独立的(既不是分组的,也不是分层的)。
基于权限的系统 一个基于权限的系统至少由一个框架、一个权限列表和一个受庇护资本列表构成。每个受庇护的资本都与一个固定的权限列表有关。
进口点 一个框架的进口点是一个利用法式能够利用的办法(例如,公共的或笔录的)。构造者也被认为是进口点。我们把EntryF表达为F的所有进口点的聚集。
例子: 在图4.1中,有四个进口点(e1到e4)。 一个利用法式能够挪用框架的任何公共办法。一些拜候系统资本的办法(如账户)遭到一个或多个权限的庇护。在安卓4.0.1的情状下,有50029个进口点。
声明的权限 一个利用法式的声明的权限是一个在
在利用法式的权限列表中. 一个利用法式的所有声明权限的聚集被称为Pd(app)。
例子: 在图4.1中, 利用法式声了然p1和p2. 在安卓系统中, 一个利用法式的权限被声明在一个喊做清单的文件中.
所需权限 一个利用法式的所需权限是与该利用法式至少利用一次的资本相关的权限。 一个利用法式的所有需要权限的聚集被称为Preq(app)。
揣度权限 一个利用法式的揣度权限是一个阐发手艺发现的利用法式需要的权限。
根据所利用的阐发手艺,揣度出的权限列表可能是对所需权限列表的过度或不敷的近似。当开发者编写清单时,他们会根据文档和试错来揣测Preq(app),从而编写Pd(app)。在第4.7节中,我们定见主动揣度出权限列表Pifrd(app),以制止那种人工和随便出错的活动。
4.4 Android概述
本节概述了Android的架构。它起首提醒读者重视第2.1节,然后重点介绍与权限有关的部门。
4.4.1 软件栈
Android是一个具有差别条理的系统。它由一个修改正的Linux内核、C/C++库、一个喊做Dalvik的虚拟机、一个编译成Dalvik字节码的Java框架和一套利用法式构成。Android的利用法式是用Java编写的,并被编译成Dalvik字节码。Dalvik字节码颠末优化,能够在内存和处置才能不敷的设备上运行。一个安卓利用被打包成一个安卓包,此中包罗Dalvik字节码、数据(图片、声音......)和一个喊做 "清单 "的元数据。
4.4.2 Android权限
利用法式赐与商为每个利用法式造定了一套权限。 为了安拆一个利用法式,用户必需整体上批准利用法式开发者在利用法式清单中声明的所有权限。假设所有的权限都被批准,利用法式就会被安拆并获得构成员资格。构成员资格被用来在运行时查抄权限。例如,一个利用法式Foo在安拆时被付与两个构成员资格net_bt和inet,别离具有BLUETOOTH和INTERNET的权限。换句话说,原则的Unix ACL被用来做为查抄权限的实现手段。
安卓2.2版在android .Manifest$permission系统中定义了134个权限,而安卓4.0.1版定义了166个权限。那给了我们一个在Android框架中能够查抄的权限数量的上限。
Android有两种权限:高层和低层权限。 高级权限只在框架层面上查抄(也就是在Android SDK的Java代码中)。Android 2.2声了然八个初级权限,那些权限要么在C/C++当地办事中查抄(例如RECORD AUDIO),要么在内核中查抄(例如在创建套接字时)。
在本章中,我们重点讨论只在Android Java框架中查抄的高级权限。
4.4.3 办事和权限
一个Android利用法式是由以下组件构成的:一个做为用户界面的活动;一个在后台运行的办事;一个监听 "企图"(一种用于历程间通信的动静)的BroadcastReceiver(或Receiver);一个用于存储和共享数据的数据库ContentProvider。大大都权限是在办事层面查抄的。
Android利用法式利用一种特殊的办事与操做系统停止通信,那种办事称为系统办事。系统办事是在一个特定范畴(称为 "系统办事器")内运行的特殊办事,容许利用法式拜候系统资本(例如:GPS坐标)。那些资本可能遭到安卓权限的庇护,以避免未经受权的利用法式拜候。与办事相关的权限查抄大部门是用Java实现的。因而,本章的范畴包罗阐发在Java框架的办事中施行的Android权限。那一重点的影响将在第4.6节讨论。
领会系统办事的内部工做对设想优良的静态阐发十分重要(那将在第4.5.2节中介绍)。我们如今描述利用法式若何与系统办事停止通信。利用法式通过一个喊做Binder的机造与系统办事停止同步通信,如图4.2所示。与长途办事通信的第一步是通过挪用Con - text .getSystemService()动态地获得该办事的引用(接口)(图4.2中的步调1)。下一步是挪用对象引用r上的接口的办法(图4.2中AccountManager办事的getPassword办法)(图4.2中的第2步)。一个被称为 "绑定器 "的特殊组件负责拦截并将该办事挪用重定向到施行现实操做的长途办事(图4.2中的步调3)。 系统办事负责施行权限查抄(图4.2的第4步)。为了查抄挪用者的利用法式能否在其清单中声了然权限(第4.4.1节),该办事挪用附录(表4.1)中列出的办法之一,并把要查抄的权限做为参数(图中未展现)。法式中的那个特定点被称为权限施行点或PEP。在图4.2中,假设利用法式有准确的权限,密码将被返回给挪用的利用法式(步调5)。
4.4.4 Android启动过程
在用Spark停止切确的静态阐发时,晓得若何初始化系统办事是很重要的(4.5.3节)。 假设办事没有被准确初始化,阐发可能是不完全的。
让我们回忆一下2.1.3节,并进一步详尽阐明Android的启动过程。 在设备上运行的第一个法式是引导法式,它为加载、恢复或更新系统镜像供给撑持。用于加载Linux内核的早期启动代码十分依靠于硬件:它起首初始化情况,然后才通过跳转到start_ kernel()函数来启动独立于架构的Linux内核C代码。 然后,高层的内核子系统被初始化(调度器、系统挪用、历程和线程操做......),根文件系统被挂载,init历程被启动。
init历程创建挂载点和挂载iles系统,设置iles系统的权限并启动daemon,如收集daemon、zygote或办事治理器。zygote是一个核心历程,新的Android历程从它那里分叉出来。 zygote的初始化会启动系统办事器,而系统办事器又会初始化系统办事和治理器。系统办事包罗输进治理器办事和wii办事。治理器包罗处置用户界面(活动)的活动治理器。
Android的启动过程表白,系统办事和治理器在启动时被实例化和初始化了。
4.4.5 安卓通信
正如第2.1.2节详尽介绍的那样,组件通过绑定器、Android特有的历程间通信(IPC)机造和长途办法挪用(RMI)系统彼此通信。组件其实不间接与绑定器停止通信,而是依靠于三种高级此外通信笼统,即企图、查询和代办署理。图4.3着重介绍了Android框架中Java层面的通信。它展现了一个利用法式通过代办署理和存根(在绑定器之上的笼统)与系统办事器(以及系统办事)停止通信。
Intent Intents描述了要施行的操做。它们被用来启动一个新的用户界面屏幕(Activity),触发一个监听企图的组件(BroadcastReceiver)或与办事停止交换。
查询/Uri 查询用于与内容供给者组件(例如,通过数据库共享数据)停止通信。查询利用同一资本标识(URI)来指示必需在其上施行查询的目标供给者组件。
代办署理/存根 系统办事扩展了存根类,描述了它们必需实现的办法。 系统办事次要被利用法式用来拜候系统资本。 它们被其他组件通过它们的公共接口(称为代办署理)拜候。系统办事在系统办事器中运行,并被注册到办事治理器中。一个利用法式能够通过办事治理器获得对已注册办事的引用,然后能够通过其代办署理(利用绑定器)与该办事停止通信。
4.5 Android框架的静态阐发
我们的目标是设想静态阐发来提取权限查抄。从素质上讲,每个阐发都从字节码中构建一个挪用图,输进权限查抄办法并提取权限名称。
获得一个有意义的挪用图是一个挑战。 我们运行了默认的Soot的CHA-Naive
(Class Hierarchy Analysis)对Android 4.0.1的50; 029个进口点办法。它花了一个多礼拜的时间,输出了31;458(64%)个没有权限的办法,一个有单一权限的办法5和18;381(36%)个进口点(办法),每个都需要超越100个高级权限。那并没有什么意义。原因是安卓系统是用面向对象的范式实现的,有许多核心类的子类(例如,办事6、活动7等)。 根据构造,CHA的输出是那些类的所有客户端都挪用它们的所有子类。 那就招致了挪用图中边的爆炸,从而招致了所需权限的爆炸。 设想静态阐发以提取权限查抄的次要挑战是若何获得一个切确的挪用图。
我们的目标仍然是利用CHA,但我们需要为Android定造它。我们还诡计利用Soot的Spark[81],一个类似Andersen的点对点阐发。我们运行CHA的动机如下。 起首,它使我们可以识别关键的安卓特有的阐发组件。 那些组件能够在更复杂的阐发中被重用,如Spark。第二,它为我们供给了一个评估Spark所带来的改进的基线。第三,它给出了一个没有权限的API办法列表,那些办法不需要被Spark阐发。最末,Android特有的阐发组件和Spark的更佳组合使我们可以获得一个切确的权限图。
图4.4代表了操做框架字节码的安卓公用组件,并生成和初始化进口点。 CHA-Android,为Android定造的CHA版本,需要生成进口点,在第11节中介绍,办事重定向,在第11节中描述,以及办事身份反转,在第11节中详述。 除了那些组件,Spark-Android,Android定造版的Spark,需要准确的进口点初始化以及办事和治理器初始化。那些组件将在
4.5.3节中描述。
在我们的尝试中,挪用图是由Android API 4.0.1版本中的50,029个进口点产生的。 所有的阐发都利用Soot[76],一个普遍利用的Java法式静态阐发框架。 尝试在Intel(R) Xeon(R) CPU E5620 @ 2.40GHz上运行,运行GNU/Linux Debian 3.11;Java虚拟机1.7.0被付与4Gb的堆内存。尝试中利用的Android版本是4.0.1,除非另有阐明。
第4.5.1节介绍了修改字节码和从挪用图中提取每个使命的差别组件。 第4.5.2节描述了CHA-Android阐发,第4.5.3节描述了Spark-Android阐发。
4.5.1 CHA和Spark的通用组件
在那一节中,我们介绍了CHA和Spark都需要的三种手艺。 字符串阐发被用来从挪用图中提取权限名称。办事重定向使挪用图构建算法可以绕过ICC胶水代码,将办事挪用者与办事自己联络起来。最初,办事身份反转从挪用图中删除了做为系统办事自己施行的代码,因而从进口点挪用者的角度来看是不相关的。
从答应施行点提取答应的字符串阐发
根本的挪用图只能给出权限查抄的数量,而不克不及给出被查抄权限的现实名称,因为欠缺从字节码中提取权限名称的字符串阐发。正如第4.4.3节所阐明的,权限施行点(PEPs)是对类Context和ContextWrapper的6个办法的办法挪用(PEPs的列表见附录中的表4.1)。那些办法挪用能够被静态地处理。然而,被查抄的现实权限是由一个字符串参数或有时是一个字符串数组动态设置的。因而,当在挪用图中发现一个查抄权限的办法时,根本阐发只能晓得发作了一个权限查抄,但不晓得哪个切当的权限被查抄,因为挪用图自己其实不处置字面和变量的解析。
为了征服那个问题,我们将字符串阐发做为一个Soot插件来实现,其伪代码展现在算法2中。 一旦发现PEPs,它就会提取响应的权限(第5行)。那个插件施行办法内阐发并治理以下情状:(1)权限间接做为字面参数给出,或者(2)权限值被初始化在一个变量中并做为参数给出,或者(3)一个数组被初始化为几个权限并做为参数给出。 在每一种情状下,我们城市利用Soot的单位图对办法的字节码停止逆向阐发,该单位图描述了一个办法的语句之间的关系。 在只要单一权限的情状下,单位图中包罗对有效的Android权限字符串的引用的语句被提取出来,并将该权限添加到阐发中的办法所需的权限列表中。在数组的情状下,所有对Android权限字符串的引用的权限都被添加到列表中。
可能发作的情状是,在当前办法Mi的主体中找不到权限字符串。那种情状发作在用当前办法的一个参数P初始化的部分变量引用权限字符串时。在那一点上,阐发通过Mi 1的语句来觅觅对M的挪用。当找到一个挪用时,参数P被提取出来,字符串阐发从那里起头。
办事重定向: 处置基于粘合剂的通信
权限大小爆炸 对办事办法的挪用凡是要颠末一个治理器,该治理器得到对一个喊做代办署理的系统办事的引用。 它老是对代办署理的办法停止挪用,招致数据从代办署理通过绑定器转移到存根,存根上有实正的系统办事办法。 代办署理和存根之间的所有数据传输都通过transact()办法停止,该办法挪用onTransact()办法。那个办法根据一个整数值来挪用系统办事端的准确办法。那个整数值在做静态阐发时是不确定的。因而,如图4.5所示,系统办事的所有办法都被添加为挪用图中的边。此外,因为所有的系统办事都实现了一个存根,当利用CHA构建挪用图时,所有的系统办事存根的onTransact()办法都是来自代办署理对象上的每个办法挪用的潜在办法挪用,因而被添加到图中。如许做的后果是我们在运行CHA时看察到权限集大小的爆炸。简而言之,当从办事的角度做一个无邪的阐发时,任何系统办事的办法挪用确实有边到每个系统办事的所有办法。
办事重定向 图4.2阐了然一个利用法式和一个办事之间的通信。该通信是通过绑定器完成的。正如上一段所阐明的,问题在于阐发基于绑定器的通信会招致权限数量的爆炸。图4.5所示的处理计划是绕过绑定器(代办署理/存根)机造,将对办事办法的挪用间接毗连到长途办事的响应办法。在图4.2中,从办法r .getPassword()到绑定器以及从绑定器到办事办法getPassword()的边被移除。只要从挪用办法到被挪用办法的间接边(图中未展现)被保留。如图4.4所示,那是在Android框架的字节码上做的第一次转换。
办事身份反转
在Android中,办事能够用初始挪用者的身份(通过de-fault)或者用办事自己的身份挪用其他办事。在后一种情状下,长途挪用是在clearI - dentity()和restoreIdentity()办法挪用范畴内。当利用办事本身的身份时,权限查抄不是针对挪用者的声明权限,而是针对办事的声明权限。因为我们的目标是计算一个利用法式(而不是系统办事)的权限差距,我们能够平安地舍弃所有在挪用clearIdentity()和restoreIdentity()之间发作的权限查抄。
例如,让我们假设办事S需要并声了然利用法式A没有声明的权限。假设A挪用S,S的代码就会以A自己的身份施行,那就需要A声明. 为了制止那种情状,需要的那部门代码是以S的身份施行的。当我们碰着对clearIdentity()或restoreIdentity()的挪用时,我们利用法式内ow-sensitive阐发来丢弃那些挪用之间发作的权限查抄。
图4.4展现,办事身份反转步调是在办事重定向转换之后完成的。
CHA的进口点处置
在API的情状下(如Android API),问题是没有 "main",而是有N个类共M个进口点办法。我们的处理计划是通过为框架的每个公共类(关于Android,android .*和com .android .*)创建一个假的办法mclassi(i∈(1,. ., N))来为Android API的每个公共办法成立一个挪用图。办法mclassi的感化是创建一个classi的实例o,并在o上挪用classi的所有办法。我们还成立了一个特殊的artiicial main来挪用所有mclassi办法。那个main办法是阐发的独一起始点。如图4.4所示,进口点是用Android API的办法构建的。
安卓API中的办法来构建进口点。
第4.5.2节介绍了CHA-Android,它操纵了办事重定向、办事标识反转和进口点构建组件。
4.5.2 CHA-Android
我们用CHA停止地图构建,因为它使我们可以识别关键的Android特定的阐发组件,那些组件能够在更复杂的阐发中反复利用,如Spark,它为我们供给了一个评估Spark改进的基线,更重要的是,它供给了一个超越30K的API办法的列表,那些办法没有权限,不需要被Spark阐发。
CHA-Android是一个基于CHA的静态阐发,用于提取An- droid框架的权限查抄。它利用了第4.5.1节中提出的字符串阐发,第11节中的办事重定向(Binder),以及第11节中阐明的办事身份反转。我们用一个我们如今描述的优化来丰富它。
唤喊图谱搜刮优化
第4.5.1节描述了若何提取权限名称。 本节阐了然答应名称是若何通过图从PEPs中传布的。算法3在图中传布权限集。 它分三步停止。 第一步(第2行)利用深度优先搜刮遍历图,并跟踪已拜候的办法。 在遍历过程中,它发现了查抄权限的处所并提取了权限名称(见上面的字符串阐发)。那第一步使阐发比无邪的办法快得多,因为没有办法被阐发过一次。第二和第三步确保已经阐发过的办法的权限在图中得到传布。在第二步(第3-4行),我们利用Tarjan的算法[tarjan:connectedComponents],用一个节点替代图中的强毗连组件(SCC)。那本色上是消弭了图中的轮回,简化了权限名称的表述。在那一步调中,我们必需重视不要删除图中的重要部门,如查抄权限的办法,因为权限在那一阶段没有被传布。详细来说,假设一个查抄权限的办法是SCC的一部门,它就不克不及被删除,不然映射到那个办法的权限就不会被传布,从而丧失。第三步也是最初一步(第5行)将权限传布到整个图中。
那个算法在节点和边的数量上有一个线性的复杂性。在第一步中,图是利用深度优先搜刮的,办法不会被阐发两次:那一步与边和节点的数量呈线性关系。Tarjan的算法在节点和边的数量上是线性的。最初一步是通过对图的深度优先搜刮来传布权限,此中SCC被替代。
体味成果
权限字符串解析 如今让我们阐发一下字符串阐发的有效性。表4.2列出了字符串阐发的成果散布。我们看察到91.89%的权限字符串阐发只查抄一个权限,83.25%的阐发中权限字符串能够间接确定为一个字面参数。因而,在Android的Java代码库中,常见的做法是:(1)庇护一个只要一个或两个权限的办法;(2)在统一个办法体中参考权限字符串并挪用查抄权限办法。那些成果展现,关于99.08%的权限查抄,利用字符串阐发能够找到权限字符串。
有时(0.92%),不成能处理权限字符串:在12种情状下,权限与URI有关;在两种情状下,权限是从Binder(包裹)中读取的。
施行时间 在Android上,CHA-Android在4分钟的用户时间或10分钟的实不时间内阐发了50029个进口点。那表白CHA-Android可以在大规模的实在世界框架长进行扩展。
进口点权限集 运行CHA-Android得到的表4.3展现了进口点的每个使命集大小。因为CHA-Android准确地模仿了系统办事通信,不需要权限的进口点的数量从64%增加到65.1%(31,458到32,429)(一些办事办法不授权限庇护),具有一个和两个权限的进口点的数量别离从不到0.01%增加到0.08%(1到39)和从0%增加到0.12%(0到55)(办事办法重定向制止了挪用图中边数的爆炸,从而制止了权限的数量)。
然而,34%(17,011)的进口点仍然有一个过度近似的权限集。那是由CHA的点对点聚集的不切确性形成的。那招致了权限数量的爆炸。 一个改进是开发其他范畴特有的优化:处置其他Android特有的点(如内容供给者、处置法式和动静)与处置办事通信类似,不会对本章的奉献产生影响。
下面的4.5.3节介绍了基于Spark的阐发。该阐发处理了Spark特有的问题,如进口点初始化或Android特有的问题,如办事初始化。
4.5.3 Spark-Android
我们在上下文不灵敏,途径不灵敏,ow不灵敏,ield不灵敏的形式下运行Spark来生成挪用图。回忆第2.2节,在上下文不灵敏形式下,对统一办法的每个挪用都被合并为一条边,与上下文(领受方和参数值)无关。对途径不灵敏的阐发漠视了前提性分收,因而考虑到了办法体的所有途径。挪用图的构造是不灵敏的,因为它不考虑指令的施行挨次。它也是范畴灵敏的,因为它利用和传布初始化数据(例如构造函数挪用)来削减边的数量。
我们起首在第4.5.3节中运行一个无邪的Spark-Android版本,以阐明需要对挪用API办法的对象以及办法的参数停止准确的初始化。
第4.5.3节描述了我们若何初始化进口点。它还阐了然另一个Spark的微妙之处:为什么以及若何对系统办事停止初始化。
Spark的无邪用法
至于CHA,我们 "无邪地 "运行现成的Spark来初步领会阐发Android API时呈现的次要问题。那给了我们一个关键的启迪,Spark放弃了96%的要阐发的API办法。 原因是Spark是,ield-sensitive,它只处置静态办法,不处置在未初始化的引用上挪用的办法(例如,默认以null初始化)。那意味着,假设不准确地初始化进口点,就不成能运行基于Spark的阐发。 即便是对CHA停止关键的Android特有的静态阐发,对Spark的无邪利用也完全失败。因而,我们需要Spark特定的阐发组件。
Spark的特殊阐发组件
处置时间 我们的第一次尝试表白,Spark的规模与An- droid框架的规模不相当。因为我们体验到Spark在处置一些进口点时很耗时,我们清空了某些类的speciic办法,以便可以在现实的时间内(即少于一天)计算出权限集。
阐发耗时的进口点老是招致窗口系统类。窗口系统是Android组件的核心,如活动。 它负责GUI(图形用户界面)的治理,并与浩瀚的GUI笼统有关系,如按钮或文本栏和启动Android组件的办法,如其他活动。当挪用图碰着窗口系统的一个组件时,因为点到集的不切确性,它可能会以如斯浩荡的比例增长,以致于此中的搜刮会触发超时。
我们假设,负责GUI衬着和窗口系统治理的类不与任何权限查抄相联络。因而,我们删除了他们办法的代码,并再次启动尝试。删除那些代码意味着(1)Spark不会为那些代码构建挪用图,因而(2)挪用图的遍历会快良多。通过那些修改,权限图的计算时间要快得多,在不到11个小时的时间内末行,而且不会触发任何超时。
Spark的进口点处置 Spark-Android操纵了为CHA生成的人工办法(见第11节)。然而,它必需初始化Android API的50,029个进口点办法的参数。每个挪用Android API办法的领受对象o以及每个办法参数p都别离通过挪用generateo()和generatep()停止初始化。 那个量身定做的办法产生了所有可能的P类型的实例(即过度近似)。参数初始化是需要的,因为人们其实不预先晓得参数对权限查抄的影响。因为Spark对字段灵敏,非初始化的参数会招致挪用图中的边丧失。
办事初始化对Spark的重要性 基于Spark的办法确实需要对Android框架的阐发模块停止恰当的初始化。原因是,如图4.6和4.7所示,跳过初始化阶段可能会招致重要的边,例如,包罗对系统办事的引用,只能指向null。Spark不会为那些只能指向null的引用的办法挪用生成边缘。
图4.6是一个代码片段,它检索了一个AccountManager对象,并对其挪用了getPassword()办法。 在那一点上,AccountManager的办事引用mServ只能指向null。 因而,mServ .getPassword()不克不及被施行,也不会被表达在一个对字段灵敏的挪用图中。换句话说,Spark为AccountManager对象生成了一条边,但没有为此中的办事办法挪用生成边,因为办事引用(mServ)指向null。
那个AccountManager对象是由Context类创建的,如图4.7所述。为了简化,只要AccountManager对象在办法getSystemService()中被创建。要创建一个AccountManager对象,需要对AccountManagerService的引用。那个引用是通过挪用getService()来获取的。然而,因为ServiceManager还没有被初始化,ServiceManager的sCache map是空的。 因而,getService()老是返回null。
静态阐发的办事初始化 正如附录中所详述的,系统办事在SystemServer类中被初始化。那个类的办法不存在于Android API进口点产生的挪用图中,因为它们只在系统启动时被挪用。
为了模仿系统办事的初始化,我们为每个详细的系统办事创建一个静态对象和一个初始化办法。那些对象是通过向挪用图中的办事初始化办法添加边来初始化的。此外,原始字节码被修改为用对新创建的静态对象的引用来取代对getService的挪用。
静态阐发的治理器初始化 Android利用法式有两种可能性与系统办事停止通信
- 第一种可能性是通过办事治理法式间接获得对办事的引用8,然后挪用办事的长途法式。
- 另一种可能性是利用另一个喊做Manager的接口。 治理器是由系统的Context类创建的,它自己有一个对办事的引用,能够间接与之通信,并做为利用法式的代办署理(如图4.6所示)。
治理器是简化与系统办事通信的包拆器。我们将对getSystemService(String s)的挪用重定向到我们本身的办法。为了做到那一点,我们用字符串阐发法计算了给getSystemService的字符串和初始化响应治理器的代码之间的映射。对getSystemService的每次挪用都停止阐发,以提取字符串参数,从而晓得必需将其重定向到哪个办法。 每个字符串对应一个治理器,因而有一个办法的感化是初始化治理器。
我们还供给了我们本身的getService()办法,如第4.5.3节所述,返回准确初始化的办事。所有对原始getService()的挪用都被重定向到我们本身的办法。 办法getSystemService返回一个治理器,而办法getService()返回一个办事的接口。
Android框架的原始字节码被修改以反映办事和治理器的初始化。 由此产生的字节码能够由任何静态阐发东西停止阐发,而不是专门针对Soot的。
实证成果
Spark-Android的运行时间为11小时。 表4.4中描述了运行Spark-Android时进口点的权限集大小。具有单一权限的进口点的数量是471个。此外,48个进口点的权限集为2,10个为3,3个有3个以上的权限。因为笼统类不克不及用Spark初始化,所以进口点的总数比CHA的少。在进口点办法集中没有与那些类相关的办法被代表。
4.5.4 总结
我们已经介绍了我们在实现我们的办法时碰着的核心手艺问题。我们认为那些问题可能会呈现在安卓以外的其他基于权限的平台上,确定那些问题和它们的处理计划对将来的工做有很大搀扶帮助。最初但并不是最不重要的是,那些问题关于复造我们的成果至关重要。
第4.6节评估了基于CHA和Spark的阐发。
4.6 讨论
与其他阐发比拟,第4.5节中介绍的6个阐发的表示若何? 它们的局限性是什么?本节答复那些问题。
4.6.1 CHA与Spark的关系
图4.8是一个进口点办法的数量与权限集大小的累积图。我们所说的累积是指在每一个权限集的大小上,办法的数量被添加到前一个权限集大小的办法的数量上。它起首表白,阐发越切确,零权限的进口点集就越大。那个成果反映了如许一个事实:跟着精度的进步,"假阳性 "的边沿会从图中移除。然后,图表(Spark-Android)强调,当只处置系统办事通信时,Spark产生了更好的成果,因为它比其他所有的阐发输进了更多具有1、2或3权限集的办法。此外,Spark从未以比CHA更多的权限插进一个进口点。它为91个进口点输进了与CHA不异的权限集(有一个或多个权限)。Spark为428个进口点输进了一个较小的权限集。
4.6.2 与PScout的比力
PScout [6] 依靠基于CHA的办法,为Android框架中的类生成一个权限列表。我们只考虑Android 4.0.1 API的类。在PSCout的成果中,有593个办法有一个以上的权限,有468个办法同时呈现在PSCout和Spark中。在那468个办法中,289个(61.75%)在PSCout和Spark中具有不异的权限大小,176个(37.60%)在我们的办法中具有较小的权限集大小。
例如,关于KeyguardManager .exitKeyguardSecurely()办法,PScout有多个权限,而Spark只要一个,DISABLE_KEYGUARD。正式的文档表白只需要一个权限,而Felt [53] 的运行时数据也是如斯。Spark也漏掉了AudioManager .setMicrophoneMute(boolean)办法的一个权限。那是因为我们没有处置C/C++原生代码的权限查抄。 表4.5总结了那种比力的成果。我们的阐发产生了比地道的基于CHA的办法更切确的成果。
有趣的是,我们还发现了三个办法(0.64%),我们的Spark办法比PSCout的办法发现了更多的办法。我们手动查抄了Vibrator类,此中涉及的办法被定义,而且有一个办法查抄权限WAKE_LOCK的途径。PScout可能没有准确地将那些特定的进口点办法链接到它们能够抵达的所有办法,因而错过了WAKE_LOCK权限。
4.6.3 与Felt等人的比力
如今让我们把我们通过静态阐发得到的成果[15]与Felt等人通过测试得到的成果[53]停止比力。两者都为Android 2.2框架的每个办法提取了一个所需的权限列表。安卓2.2具有134个权限,此中8个是我们没有阐发的初级权限。Felt等人的成果包罗了673个映射到高条理权限的办法。我们只阐发了671个办法,因为有2个办法与Felt的办法中供给的利用法式特定对象有关,而我们的静态阐发办法中没有。
关于一个给定的办法,我们要么摘用不异的权限集,要么摘用更大的权限集。 我们的办法从未错过Felt等人所描述的权限,那是我们办法合理性的一个证据。
更切当地说,我们为552个办法(占常用阐发办法的82.3%)的每个办法签名揣度了不异的权限集。119种办法有一个额外的权限(118种办法有一个额外的权限,1种办法有两个)。没有任何办法我们错过了一个权限,表4.6总结了那些成果。 如今让我们来讨论一下我们的成果之间的差别。
额外的权限是因为阐发了不相关的代码或者Felt等人的办法中贫乏输进数据。例如,MOUNT_UNMOUNT_FILESYSTEMS只在MountService .shut - down()办法中被查抄,假设媒体(存储设备)是 "目前没有安拆并通过USB大容量存储共享"(来自API文档)。另一个权限,READ_PHONE_STATE,只要在参数中传递的德律风号码是语音邮件号码时,才需要在CallerInfo .getCallerId()办法中查抄。那些测试用例不是由Felt的测试办法生成的。在现实利用中,测试生成手艺不克不及包管对输进空间的全面摸索。
对我们来说,在比力静态阐发办法和测试办法时,那些迹象是典型的:静态阐发有时会遭到阐发所有代码的影响(包罗调试和死代码,或在特定运行情况中运行的代码),但在笼统输进数据方面很强。另一方面,测试必需尽可能地模仿消费情况,但被咒骂老是错过十分特殊的利用场景。
那些成果强调了静态阐发和测试在权限推理方面的互补性。 我们认为,静态阐发办法是对测试办法的填补。事实上,测试办法产生的近似值不敷,遗漏了一些权限查抄,而静态阐发办法产生的近似值过高,那些遗漏的权限查抄被发现。将那两种办法连系起来利用,能够使开发者获得权限差距的下限和上限。特殊是,关于一个给定的Android利用法式,假设测试和静态阐发办法都产生不异的权限列表,那强烈地表白那个列表是所需权限的 "准确 "列表。因为测试可能会遗漏权限,而静态阐发可能不会模仿所有的安卓系统特征,那并非一个强有力的说法。
4.6.4 健全性
我们在本章中已经表白,Android框架有许多可能威胁到静态阐发的健全性的特征。 在那种情状下,合理性是指没有错误的否认(没有遗漏的权限查抄)。 此外,健全性的概念指的是一个特定的范畴:在我们的案例中,对Android办事内部的高级权限的查抄。
关于基于CHA和Spark的阐发,如PScout、CHA-Android或Spark-Android,基于范畴特定的常识(如字节码重定向和窗口系统办法清空)对挪用图的操做,当且仅当所有的情状都被包抄时,才是健全的。鉴于像Android如许的框架的复杂性和规模,那种完全性是很难证明的。
关于基于Spark的阐发,当且仅当对象和静态域被准确初始化时,阐发是合理的。因而,阐发可能对某些进口点是准确的,而对其他进口点则是不准确的。关于像Android如许的框架,没有神谕来正式答复那些问题。 然而,关于那些基于CHA的成果和基于Spark的成果不异的进口点,那是一个强有力的合理性证据。关于其他的,需要与文档或运行时数据停止比力。
最初,只要静态阐发的任何部门(如进口点初始化和字节码重定向)以及我们编写的胶水和丈量代码的实现没有严峻的错误,我们的成果就能成立。
4.6.5 办事身份反转的影响
一个合理的问题是,办事身份反转能否会对产生的权限集产生影响。为了答复那个问题,我们在运行Spark-Android的时候,有的时候没有停止办事身份反转。在没有超时的进口点中,当办事身份反转被封闭时,有两个进口点有更大的权限集。例如,办法an - droid.net.ConnectivityManager boolean requestRouteToHost (int,int) 在办事反转被禁用时有一个更多的权限CONNECTIVITY_INTERNAL。根据官方文档9,那个权限对进口点来说是不需要的,它验证了办事身份反转构建块的有用性。
办事反转可能只影响几个进口点,但不考虑它就会招致错误的权限设置。
4.6.6 限造
当地代码
安卓框架是一个现实世界的大规模框架,具有用差别语言编写的异量层。关于Android 2.2来说,大大都Android权限(126/134)只在Android Java框架中查抄。我们的办法对那126个权限是完全的,但对在当地C/C++代码中查抄的8个权限则不完全。那八个权限是
BLUETOOTH_ADMIN, BLUETOOTH, INTERNET, CAMERA, READ_LOGS, WRITE_EX-TERNAL_STORAGE, ACCESS_CACHE_FILESYSTEM 和 DIAGNOSTIC.
框架中的反侦查
假设框架利用reection,那么挪用图的构培养不完全。幸运的是,Android框架只在7个类中利用了reection。 我们手动阐发了它们的源代码。那些类中有五个是调试类。视图类利用reection来处置动画。最初,VCardComposer在一个只为测试目标而施行的分收中利用reection。 在所有情状下,那些代码都与系统资本无关,因而
没有做任何权限查抄。那其实不影响Android框架的静态阐发。
动态类加载
Java语言有可能动态地加载类。静态阐发不克不及处置那个问题,因为加载的类只要在运行时才晓得。 我们发现Android系统中有8个类在利用loadClass办法。 颠末人工查抄,此中6个是系统治理类,要么与权限查抄无关(例如:对利用法式停止检测),要么必需通过办事拜候。有两个是与webkit包有关的。它们被用于LoadFile和PluginManager类中。在那两种情状下,都是在加载类之前查抄权限,而不是在加载的类中查抄权限。 因而,也不存在遗漏的权限施行点。
火花
我们的安卓框架模子专注于办事,而错过了其他的初始化
Android组件(例如,内容供给者)的初始化。换句话说,Spark的声音与我们的Android组件模子有关。
4.7 计算权限差距
我们如今有静态阐发来计算安卓API办法和它们所需的权限之间的映射。本节起首介绍了一种有效计算所需权限集和响应的权限缺口(已声明但未利用的权限)的办法,假设有的话。然后,我们提出了一个实证研究的成果,表白在野外存在着权限差距。
4.7.1 权限阐发的微积分
本节将权限差距推理描述为布尔矩阵代数之上的一个微积分。 权限推理素质上是一种可及性阐发(利用法式能否到达权限查抄?
让app是一个利用法式。利用法式的拜候向量是一个布尔向量AVapp,代表研究中的框架的进口点。因而,向量AV的长度是框架F的进口点的数量。假设利用法式挪用了响应的进口点,向量的一个元素被设置为实。不然,它被设置为假。让我们考虑一个有四个进口点(e1 , e2 , e3 , e4)的框架,以及一个抵达e1、e2和e3但没有抵达e4的利用法式foo。AVapp读取:
AVfoo = (1, 1, 1, 0)
我们把权限拜候矩阵M定义为一个布尔矩阵,表达框架的进口点和权限之间的关系。行代表框架的进口点,列代表权限。假设一个单位格Mi,j被设置为实,则响应的进口点(在第i行)拜候由第j列所代表的权限庇护的资本。不然它就被设置为假。关于一个有四个进口点(e1,e2,e3和e4)和三个权限(p1,p2和p3)的框架,权限拜候矩阵如下:
. .意味着e1和e2需要权限p1,e3不需要权限,e4需要权限p2。
让app和F别离为一个利用法式和一个框架。揣度出的权限向量IPapp是一个布尔向量,代表利用法式app的揣度出的权限聚集。 通过利用布尔运算符AND和OR,而不是矩阵计算中的算术乘法和加法,我们有:
单位IPapp(k)等于true意味着索引k处的权限是app所需要的。利用前面例子中的AVapp和M,揣度出的利用法式的权限向量是:
. ......意思是说,利用法式应该声明而且只声明权限p1.
4.7.2 M和AV的提取
权限拜候矩阵M是基于对框架F的静态阐发. 如第4.5节所示, 我们起首计算框架的每个进口点的挪用图, 然后探测
然后检测权限查抄能否存在于挪用图中。一个答应施行点
(PEP)是一个挪用图的顶点,其签名对应于一个查抄权限的系统办法。
权限(s)。每个PEP都与一个所需的权限列表permsP EP相关。矩阵
M的构造如下:它是一个大小为(|进口点|×|高层权限|)的矩阵;M的所有元素初始化为假。
M的所有元素都被初始化为false;关于每一个到达一个或多个PEP的Ei
到达一个或多个PEP,以及permsP EP中的每个
permsP EP中的权限j,M(i, j) = true。换句话说,M是一个浓缩版本的
可达性信息的浓缩版,它潜躲在挪用图中。
让我们以第4.3节中的图4.1为例。它展现了一个有四个进口的框架
点(e1, e2, e3, e4),以及三个权限(p1, p2, p3)。关于每一个进口点,都构建了一个挪用
图被构建。此中三个挪用图有一个PEP节点:e1和e2有PEP ck1,它查抄权限p1,e4有PEP ck1。
查抄权限p1,e4有PEP ck2,查抄权限p2。在图中,一个虚线
箭头将每个PEP与它所查抄的权限毗连起来。然后,框架矩阵是上面的矩阵
M(见4.7.1节)。
提取AV仅仅意味着列出一个由利用法式挪用的框架F的进口点列表。
利用法式挪用的框架F的进口点列表。图4.1中的利用实例利用一个进口点,AVex =
(1, 1, 1, 0).
4.7.3 计算权限差距
权限差距是指从IPapp提取的权限和声明的权限Pd(app)之间的差别。
公布的权限Pd(app)之间的差别。在图4.1中,利用矩阵Mex和向量AVex的例子
框架和利用法式,我们得到一个只包罗p1的揣度权限列表。假设
利用法式声了然p1和p2,那么权限差距就是{p2}。
我们在两个安卓利用的数据集上运行我们的东西。第一个数据集来自于另一个
安卓市场10,包罗1329个安卓利用。关于第二个数据集,我们考虑的是
关于第二个数据集,我们考虑了官方安卓市场合有34个顶级类别中的前50个下载利用,以及所有利用中的前500个。
以及所有利用的前500名和新利用的前500名(在2月23日
2012). 在往除反复的利用(呈现在多个排名中的利用)后,第二个
数据集包罗2057个利用。
替代的安卓市场: 我们舍弃了587个利用反射和/或类
拆载。在剩下的742个利用法式中,有94个声了然一个或多个权限,但它们并没有利用。
不利用的权限。因而,我们确定了94个安卓利用的权限缺口。我们定义
进攻面的面积 "与权限差距有关,是指没必要要的
权限。总的来说,在存在权限差距的利用法式中,76.6%的利用法式的进攻面为1个权限。
进攻面为1个权限,19.2%的进攻面为2个权限,2.1%为3个权限
和2.1%的4个权限。
官方安卓市场: 我们舍弃了1378个利用反射和/或类
负载。在剩下的679个利用法式中,有124个声了然一个或多个权限,但它们并没有利用。 总的来说,在存在权限差距的利用中,64.5%的利用有1个权限的进攻面,23.4%的利用有2个权限的进攻面,12.1%的利用有3个或以上的权限。
总而言之,那些成果表白,权限差距是存在的,我们的办法容许开发者在声明的权限列表中加进权限,以削减基于权限的软件的进攻面。
4.8 结论
在那一章中,我们利用静态阐发来提取Android框架中的权限。为了利用类条理阐发(CHA)和字段灵敏静态阐发(Spark)来阐发Android的权限,至少有三个静态阐发组件必需放在一路。它们是:(1)字符串阐发;(2)办事身份反转;(3)进口点和办事
初始化。
该办法已在安卓系统中全面施行,安卓系统是一个基于权限的挪动设备平台。我们的原型实现可以主动识别9562个查抄权限的Android框架工做进口点。同时停止的工做,如PScout[6]和Felt[53]证明了我们的成果。
该办法已经完全实现了Android,一个基于权限的挪动设备平台。关于末端用户的利用,我们的评估展现,从安卓利用商铺挠取的94/742和35/679个利用确实存在着权限破绽。
一般来说,基于权限的软件,特殊是安卓系统的平安架构是复杂的。在本章中,我们笼统了平台的几个特征,如初级权限。
第五章
Android利用法式中的数据泄露
我们在上一章中看到,权限能够庇护灵敏数据。然而,拥有准确权限拜候数据的利用法式可能会泄露数据。例如,歹意软件或带有进攻性告白库的利用法式就属于那种情状。本章的目标是静态阐发Android利用法式,以检测那种泄露。Android利用法式与传统的Java利用法式差别。最重要的区别之一是,Android利用法式是由组件构成的。阐发Android利用法式以发现泄露,需要将一路通信的组件联络起来,并对每个组件停止建模。我们开发了IccTA来检测隐私泄露。它在代码层面毗连组件,以施行组件间和利用间的数据流阐发。
本章是基于以下手艺陈述中颁发的工做:
- Li Li, Alexandre Bartel, Jacques Klein, Yves Le Traon, Steven Arzt, Siegfried Rasthofer, Eric Bodden, Damien Octeau and Patrick McDaniel: I know what leaked in your pocket: uncovering privacy leaks on Android Apps with Static Taint Analysis, ISBN 978-2-87971-129-4, 2014.
5.1 引言
跟着安卓系统的日益普及,在安卓官方市场(Google Play)以及一些替代市场上,天天都有数以千计的利用法式(也喊利用)涌现。截至2013年5月,Google Play商铺已经安拆了480亿个利用法式,而截至2013年9月3日,已有10亿台安卓设备被激活[3]。研究人员表白,安卓利用经常在未经用户事先附和的情状下将用户的私家数据发送到设备之外[141]。 那些利用法式被说成是泄露私家数据。 Android利用法式是由差别的组件构成的;大大都隐私泄露是简单的,并在单一组件中操做。比来,跨组件和跨利用法式的隐私泄露已被报导[136]。零丁阐发组件其实不足以检测此类泄露。因而,有需要对利用法式停止组件间阐发。 安卓利用阐发人员能够操纵如许的东西来识别泄露隐私数据的歹意利用。为了使该东西发扬感化,它必需高度切确,并在陈述泄露私家数据的利用法式时尽量削减假阳性率。
隐私泄露。在本章中,我们利用静态污点阐发手艺来识别隐私泄露,即从灵敏数据(称为源)到向利用法式或设备外发送数据的语句(称为汇)的途径。一个途径可能是在一个单一的组件内,或逾越多个组件和/或利用法式。
依靠静态阐发来检测安卓利用的隐私泄露的更先进的办法次要集中在检测组件内的灵敏数据泄露。例如,CHEX[84]通过跟踪灵敏源和汇之间的污点,利用静态阐发来检测组件劫持破绽。 DroidChecker[29]利用法式间掌握流图(CFG)搜刮和静态污点查抄来检测Android利用法式中可操纵的数据途径。FlowDroid[5]也在Android利用法式的单个组件中停止污点阐发,但精度更高。 在本章中,我们不只存眷组件内的泄露,并且还考虑基于组件间通信(ICC)的隐私泄露,包罗利用间通信(IAC)的泄露。
其他办法利用动态跟踪来识别隐私泄露。例如,TaintDroid[45]操纵Android的虚拟化施行情况,在运行时监控Android利用法式,它跟踪利用法式若何泄露私家信息。CopperDroid[105]动态地看察Android组件和底层Linux系统之间的互动,以重构更高级此外行为。
动态办法必需在运行时向利用法式发送输进数据以触发代码施行。输进的数据可能是不完全的,因而不克不及施行代码的所有部门。此外,一些代码可能只要在运行时称心切确的前提时才会被施行,如数据。在本章中,我们将重点放在静态阐发上以制止那些缺点。与静态阐发相对应的是,它可能会产生一个过度的近似值,因为它阐发了所有的代码,即便是那些永久不会被施行的代码。
Android的静态污点阐发是很困难的。 虽然Android利用法式次要是用Java编程的,但现成的Java静态污点阐发东西其实不能用于Android利用法式。那些东西需要停止调整,次要有三个原因。第一个原因是,如前所述,Android利用法式是由组件构成的。组件之间的通信涉及两个次要的工件: Intent Filter和Intent。 一个Intent Filter被附加到一个组件上,并 "过滤 "能够抵达该组件的Intent。一个企图被用来启动一个新的组件,起首动态地创建一个企图实例,然后通过挪用一个特定的办法(例如startActivity,startService),并将之前创建的企图做为参数。该企图能够通过指定要挪用的新组件明白地利用,也能够通过隐含地利用,例如只指定要施行的动做1。 组件的启动是由Android系统施行的,它在运行时 "处理 "企图和企图过滤器之间的婚配问题。那种由安卓系统完成的动态解析在安卓利用法式的掌握流中引起了不持续。 那种特殊性使得静态污点阐发具有挑战性,因为它需要对代码停止预处置以处理组件之间的联络。
第二个原因是与安卓利用以用户为中心的性量有关,在那种情状下,用户能够通过触摸屏停止大量的互动。对用户输进的治理次要是通过处置特定的回调办法来完成的,如当用户点击按钮时挪用的onClick办法。静态阐发需要一个切确的模子来刺激用户的行为。
第三个也是最初一个原因是与组件的生命周期治理有关。在传统的Java法式中没有主办法。相反,Android系统通过挪用回调办法,如onStart、onResume或onCreate,在组件的生命周期中切换形态。然而,那些生命周期的办法在代码中没有间接的联络。对Android系统停止建模能够将回调办法与代码的其他部门联络起来。
我们的定见。 上述挑战将不成制止地招致掌握-流量图中的一些不持续现象。为了征服那些问题,我们提出了一个名为IccTA2的组件间通信污点阐发东西。IccTA容许对ICC和IAC链接停止健全和切确的检测。那种办法是通用的,能够用于任何数据流阐发。在那一章中,我们重点讨论利用IccTA来检测隐私泄露。
IccTA是基于三个软件工件: Epicc-IccTA、FlowDroid-IccTA和ApkCom-biner。
Epicc-IccTA扩展了Epicc[92],它计算了Android组件之间的ICC链接。Epicc-IccTA操纵Epicc将计算出的ICC链接增量存储到数据库中,以便利阐发大量的利用集。FlowDroid-IccTA扩展了FlowDroid[5]。FlowDroid只发现Android利用法式单个组件内的隐私泄露,而不是组件之间的隐私泄露。
FlowDroid-IccTA利用由Epicc计算的ICC链接来改进FlowDroid。基于那些计算出的链接,FlowDroid-IccTA修改Android利用法式的代码,间接毗连组件,以实现组件之间的数据流阐发。通过如许做,我们成立了整个安卓利用的完全掌握流图。那容许在Android组件之间传布上下文,并产生一个高度切确的数据流阐发。据我们所知,那是第一个为数据流阐发切确毗连组件的办法。
最初,ApkCombiner搀扶帮助阐发多个安卓利用,当那些利用之间存在数据流时,将多个利用合并为一个。那将招致拥有合并后的利用法式的完全掌握-流量图。那不只容许在单个利用法式的组件之间传布上下文,也容许在差别利用法式的组件之间传布。
为了验证我们的办法,我们在3000个实在世界的安卓利用和26个包罗我们开发的基于ICC的隐私泄露的利用上运行IccTA。我们将那26个利用添加到DroidBench[43],那是一个开放的测试套件,用于评估污点阐发东西的有效性和准确性。
该测试套件用于评估专门针对Android利用法式的污点阐发东西的有效性和准确性。那26个利用法式涵盖了表5.1中展现的前8个利用的ICC办法。
奉献。总结一下,我们在本章中提出了以下原创性奉献:
- 一种新的办法,通过在代码层面上间接毗连Android利用法式的不持续性,来处理ICC问题。
- IccTA,一个用于组件间数据流阐发的东西。
- DroidBench的改进版,有26个新的利用法式,用于评估检测基于ICC的隐私泄露的东西。
- 一项实证研究,在DroidBench测试套件的加强版(可在线获得3)和3000个实在世界的Android利用法式上评估IccTA。
本章的其余部门组织如下。第5.2节阐了然Android平安的需要布景。第5.3节给出了一个鼓励性的例子,第5.4节介绍了一些根本定义。在第5.5节中,本文讨论了Ic- cTA的实现细节,而第5.6节则评估了IccTA。第5.7节描述了IccTA的局限性。最初,第5.8节对本章停止了总结。
5.2 布景
5.2.1 安卓ICC办法
正如第2.1节所阐明的,一个Android利用法式是由根本单位构成的,称为组件,在一个特殊的ile中描述,称为Manifest,存储在利用法式中。 有四品种型的组件:a)代表用户界面的活动,是Android利用法式的可见部门;b)在后台施行使命的办事;c)从头领受来自其他组件或系统的动静的播送领受器,如来电或文本动静;以及d)做为原则接口的内容供给者,在利用法式之间共享构造化数据。
一些特殊的Android系统办法被用来触发组件间的通信。我们称它们为组件间通信(ICC)办法。那些办法以一种特殊的对象为参数,称为 "企图",它指了然目标组件。我们停止了一项简短的研究来计算ICC办法的利用率。我们阐发了从Google Play和其他第三方市场随机抉择的3000个Android利用法式。表5.1展现了前8种最常用的ICC办法。第三列表达至少利用过一次响应ICC办法的利用法式的数量。最常用的ICC办法是startActivity,用于启动一个新的活动组件,占检测到的ICC办法总数的59.2%。
所有的ICC办法4的参数中至少有一个Intent来指定目标组件。 有两种办法来指定ICC办法的目标组件。 第一种是通过Intent设置目标组件的名称来明白地指定它们。第二种是通过设置Intent的action、category和data ields来隐式地指定它们。为了领受隐式Intent,目标组件需要在其利用法式的清单中指定一个Intent Filter。请重视,Intent能够在组件之间传输数据。
同样,我们对3000个利用法式停止了简短的研究,以计算startActivity ICC办法的显式和隐式Intent之间的比例。在55802个startActivity办法挪用中,有27978个利用显式Intents,27824个利用隐式Intents。
图5.1代表了三个由活动组件构成的Android利用法式。在利用1中,有一个从Activity1到Activity2的显式ICC。在利用1中有两个从Activity2到Activity3的隐式ICC,在利用1和利用2之间有从Activity2到Activity4的隐式ICC。请重视,隐式ICC的目标组件,Ac - tivity3和Activity4,有一个Intent Filter,其动做和类别值与Activity2中利用的Intent不异。 每次有ICC时,组件之间可能会有数据的欠款,并可能有隐私泄露。
5.2.2 FlowDroid
FlowDroid[5]是一个用于Android利用法式的上下文,ow-,ield-,对象灵敏和生命周期感知的静态污点阐发东西。 FlowDroid的上下文、ow-、ield-、object-sensitives由Soot[75]的切确挪用图和Heros[22]的基于IFDS[106]的数据流阐发包管。FlowDroid利用的源和汇是由SuSi[4]供给的,它也是一个开源的东西,用于完全主动地对Android源和汇停止分类和回类。
生命周期的切确建模
Android利用法式的组件能够独立启动并并行运行。FlowDroid对途径不灵敏(见第2.2.1节),并假设利用法式中的组件能够按任何挨次运行。 一个特殊的主办法,考虑到Android组件的生命周期(例如,当响应的Activity组件暂停时施行的办法onPause())、回调(例如,当用户点击按钮时施行的办法onClick())和进口点(例如,当Activity组件启动时施行的办法onCreate())的所有组合,被生成为利用中的数据流模子。
IFDS问题
FlowDroid停止污点阐发并利用IFDS框架。阐发起头于将源办法(例如,getDeviceId())的成果分配到一个变量中的语句。那个变量是有污点的,因为它包罗来自源办法的数据。然后阐发利用Andomeda[129]介绍的一个设法,向后阐发被污染变量的别号。在前向阐发过程中,假设别号到达了源办法的原始赋值,它们也会被玷污。最初,假设一个被污染的变量抵达一个汇进办法,那么就会检测到一个泄露。正如第2.2.2节所述,该阐发依靠于利用于语句的ow函数来计算数据流的事实。在那个阐发中,数据流事实是每个法式语句中被污染的变量聚集。例如,利用于语句x=y的一般ow函数,假设x被污损,y没有被污损,则杀死x;假设y在语句之前被污损,则将y的污损递增到x。
尝试成果
在DroidBench上检测数据泄露时,FlowDroid实现了93%的召回率和86%的精度。FlowDroid次要用于阐发单个组件中的数据泄露。然而,只要稍加修改,FlowDroid也可用于涉及多个组件的情状,即用于ICC阐发。事实上,能够用FlowDroid来计算所有单个组件的途径,然后将所有那些途径连系在一路,无论那些组件之间能否存在实正的联络。那种办法的一个次要缺点是,它产生了许多假阳性成果。下一节将介绍Epicc,一个静态处理ICC链接的东西。
5.2.3 Epicc
Epicc[92]是一个静态阐发东西,也是基于Soot和Heros的,它计算ICC(组件间通信)链接。 换句话说,它将ICC办法的链接输进到其目标组件。
集成开发情况问题
ICC办法需要一个喊做Intent的对象做为参数。那个Intent对象描述了设想国的组件。Epicc对利用法式的代码停止静态阐发,在每个挪用ICC办法的语句中从头构建那些对象。Epicc将Android中ICC的发现简化为法式间散布情况(IDE)问题的一个实例[111]。一个IDE问题会传布情况。在Epicc的例子中,情况能够被看做是代表正在重建的对象的一个变量与该重建对象的当前值之间的映射。例如,当一个新的Intent对象被创建时,指代那个新对象的变量将被映射到一个空的Intent。 在阐发过程中,情况转化器(在超图的每条边上)将更新情况。例如,语句i .setAction("A1")的情况转换器通过将字符串 "A1 "做为响应的重构对象的动做值来改动变量i的情况。在Intent对象中利用的其他对象,如ComponentName或Bundle对象,也是通过同样的过程来重构的。
尝试成果
尝试表白,当利用于一组1200个Android利用法式时,Epicc识别了93%的所有ICC链接,并发现了ICC破绽,其误报率远远低于次好的东西。在本章中,我们利用Epicc生成的链接来进步FlowDroid ICC阐发的精度。下面一节介绍了我们对ICC泄露的处置办法。
5.3 鼓励性的例子
本节鼓励我们的办法,并通过一个详细的例子阐明我们处理的问题。那个例子详见图5.2,它展现了图5.1中介绍的利用法式1的代码。该利用法式有三个活动组件,别离由Activity1、Activ - ity2和Activ 3类代表。它还具有ButtonOnClickListener,一个用于处置按钮点击事务的监听器类。 Activity1为to2按钮注册了一个按钮监听器(第6-11行),Activity2为to3按钮注册了一个(第15行)。
当按钮to2和to3被点击时,onClick办法被施行,用户界面将别离改动为Activity2和Activity3。在那两种情状下,包罗设备ID的Intent(第7行和第32行)被认为是灵敏数据,通过起首用putExtra办法(第9行和第35行)将数据附加到Intent上,然后通过挪用startActivity或startActivityForResult(第10行和第36行)在两个组件之间发送。请重视,图5.2是利用显式和隐式企图的例子。 在第 8 行,通过明白指定目标类(Activity2 )来创建企图。在第34行,只规定了企图的动做,而没有明白地提到目标。
在那个例子中,当Activity2或Activity3被加载时,sendTextMessage被间接施行,因为onCreate是一个Activity生命周期中的第一个办法。它将从Intent中获取的数据做为SMS发送到指定的德律风号码。
在那段代码中,发作了两个隐私泄露:一个是当按钮to2被点击时,另一个是按钮to3被点击时。当to2被点击时,设备ID从Activity1传输到Activity2(第10行),然后Activity2将其发送到利用法式之外(第18行)。
当按钮to3被点击时,设备ID被从Activity2转移到Activity35(第36行)。现实上,设备ID(源)是在Activity2实例化的ButtonOnClickListener类中获取的。 最初,Activity3将设备ID发送到利用法式之外(第27行)。
上面描述的灵敏数据泄露逾越了两个组件:它们不克不及间接被检测到,因为在startActivity和onCreate(第10行和第13行)或startActivityForResult和onCreate(第36行和第24行)之间没有实正的代码毗连。第5.5节描述了我们毗连组件的办法,以阐发组件之间以至是利用法式之间的途径。
5.4 分词
为了更好地描述我们的办法,需要对一些Android和污点阐发的相关概念停止定义。
掌握流图(CFG) 我们通过火析安卓利用法式的掌握流图来检测数据泄露。一个利用法式的CFG由一个办法CFG的聚集构成,根据它们彼此挪用的体例毗连在一路。
源办法。一个源办法从用户的角度返回被认为是私有的数据到利用法式代码中。例如,办法getDeviceId(第76行)是一个返回设备ID的源办法。
水槽办法。一个水槽办法将数据从利用法式中发送出往。例如,办法send - TextMessage(第27行)是一个sink办法,利用SMS向另一个手机发送数据。我们利用SuSi东西[4]为Android计算的源和汇。
ICC办法。一个ICC办法被用来触发两个组件之间的通信。例如,办法startActivity(第10行)是一个ICC办法,它触发了从Activity1到Activity2的组件通信。
受污染的语句(Tainted Stmt)。一个有污点的语句至少包罗一个有污点的数据。例如,i .putExtra("sensitive",id)(第9行)是一个包罗污点数据id的语句。
受污染的语句序列。受污染的语句序列是一个受污染的语句的ow-sensitive序列。例如,第9行和第10行的语句构成一个污点语句序列。
污染的途径。 污点途径是一个污点语句序列,此中1)在污点途径中存在一个以上的语句;2)第一个语句包罗一个源办法;3)最初一个语句包罗一个汇办法。图5.3阐了然污点特写、污点特写序列和污点途径。
在Android中,有三品种型的污点声明途径:基于组件内通信(Intra-Component Communi- cation)、组件间通信(ICC)和利用间通信(IAC)的污点途径。
组件内污点途径。 组件内的污点途径是一个组件内的污点途径。 在我们的鼓励性例子中,没有组件内的污点途径。 但是假设startActivity的挪用被替代为sendTextMessage的挪用,将设备ID从利用法式中发送出往,就会有一个组件内的污点途径(第7-10行)。
基于ICC的污点途径。 基于ICC的污点途径是两个或多个组件之间的污点途径,也就是说,途径中至少有一个ICC办法。在我们的例子中,有一条基于ICC的污点途径,从Activity1的源办法getDeviceId到Activity2的汇办法sendTextMessage,通过startActivity ICC办法(第10行)。
基于IAC的污点途径。基于IAC的污点途径是两个或多个利用法式之间的污点途径,也就是说,它在差别利用法式的两个组件之间至少有一个ICC办法。在我们的鼓励性例子中没有基于IAC的污点途径。但是,假设图5.1中的Activity4将从Activity2转来的设备ID送出利用,那么就有一个基于IAC的污点途径从利用1到利用2。
隐私泄露。假设检测到一个有污点的途径,就意味着发现了一个隐私泄露。换句话说,从源办法获得的一些隐私数据能够通过污点途径ow到汇办法。
5.5 IccTA
在那一节中,我们描述了IccTA,我们用于检测Android利用法式中的隐私泄露的东西。它利用静态污点阐发来检测隐私泄露。 那方面的次要挑战是处理Android系统引进的不持续问题。
我们在图5.4中展现了IccTA的架构,此中新的或修改的组件被虚线包抄。IccTA是Epicc-IccTA和FlowDroid-IccTA的组合。Epicc-IccTA依靠Epicc来增量计算Android利用法式的ICC链接。 FlowDroid和Epicc都是基于Soot[75]和Heros[22]。Soot是一个阐发基于Java的利用法式的框架。它利用Dexpler[14]插件将Android的Dalvik字节码转换为Soot的内部表达,称为Jimple,并依靠Spark[82]来成立切确的挪用图。Heros是IFDS[107]和IDE[111]的可扩展实现,那两个框架用于施行数据流阐发。 阐发多个利用法式是利用ApkCombiner停止的。 它将多个利用法式合并为一个,以简化IccTA的阐发。
图5.5是IccTA和FlowDroid的比力。FlowDroid(5.5起)起首在步调(1.1)中将Android字节码转换为Jimple。然后,在步调(1.2)中,它阐发Jimple代码以检测单个Android组件中的污点途径。
IccTA(5.5下)能够阐发一个或多个Android利用法式。假设阐发了一个以上的利用法式,它将利用ApkCombiner在步调(2.1)中把Android利用法式合并为一个利用法式。然后,在步调(2.2)中,Android利用法式的字节码被转换为Jimple。
同时,Epicc-IccTA在步调(2.3)平分析所有输进的利用法式(图中的Apk1和Apk2)以生成ICC链接,并在步调(2.4)中将成果存储到数据库。IccTA在步调(2.5)中利用由Epicc-IccTA生成的ICC链接来毗连Jimple代码中的Android组件。 步调(2.2)和(2.6)对应于FlowDroid的步调(1.1)和(1.2):Jimple代码被更新以考虑到组件的生命周期和回调,污点阐发被启动以生成污点途径的列表。
5.5.1 FlowDroid-IccTA:将ICC问题削减为组件内问题
因为两个Android组件之间没有间接的代码毗连,FlowDroid不克不及切确地检测基于ICC的隐私泄露。 在本节中,我们描述了FlowDroid-IccTA若何将ICC问题削减到一个组件内问题,FlowDroid能够对其停止高度切确的数据流阐发。我们的办法是操纵Android利用法式的Jimple代码,在代码中间接毗连组件。
正如介绍中提到的,Android中有三品种型的不持续:(1)ICC办法,(2)生命周期办法和(3)回调办法。我们起首在第5.5.1节描述了FlowDroid- IccTA若何处置ICC办法。然后,我们详尽阐明FlowDroid-IccTA若何处理
在第5.5.1节中,我们详尽介绍了FlowDroid-IccTA若何处理生命周期和回调办法。最初,利用我们在List- ing 5.2中的鼓励性例子,我们在第5.5.1节中阐了然代码东西化过程。
如图5.5所示,ICC问题在步调2.5得到处理。那时,Jimple代码被FlowDroid-IccTA更新为毗连组件。 所有的ICC办法都需要停止那种代码修改(在表5.1中列出)。我们为两个最常用的ICC办法详尽阐明那些修改:startActivity和startActivityForResult。 我们以类似的体例处置办事和播送领受机的ICC办法。
StartActivity。图5.6展现了FlowDroid-IccTA对我们鼓励性例子中Activity1和Activity2之间的ICC链接所做的代码转换。FlowDroid-IccTA起首创建了一个名为IpcSC(图5.6中的B)的辅助类,做为毗连源和目标组件的桥梁。然后,startActivity ICC办法被移除,并由挪用生成的辅助办法(redirect0)的语句代替(A)。
在(C)中,FlowDroid-IccTA生成了一个以Intent为参数的构造办法,一个假Main办法来挪用组件的所有相关办法(即生命周期和回调办法),并重写了getIntent办法。一个Intent被Android系统从挪用者组件转移到被挪用者组件。我们对Android系统的行为停止建模,通过利用自定义的con- structor办法Activity2 (Intent i)明白地将Intent转移到目标组件,该办法将Intent做为其参数,并将Intent存储到重生成的ield int_for_ipc。本来的getIntent办法要求Android系统供给传进的Intent对象。新的getIntent办法通过返回做为参数给新的构造办法的Intent对象来模仿安卓系统的行为。
辅助办法redirect0构造了一个Activity2类型的对象(目标组件),并用做为参数给辅助办法的Intent来初始化新对象。然后,它挪用Activity2的dummyMain办法。
为领会决目标组件,即主动揣度在办法redirect0中必需利用的类型(在我们的例子中,揣度Activity2),Flowdroid-IccTA利用由Epicc-IccTA计算的ICC链接。Epicc-IccTA不只为显式企图解析目标组件,也为隐式企图解析目标组件。因而,Flowdroid-IccTA在处置基于显式或隐式企图的ICC方面没有区别。
StartActivityForResult。 在Android中有一些特殊的ICC办法,好比star - tActivityForResult。一个组件C1能够利用那个办法来启动一个组件C2。一旦C2完毕运行,C1就会带着从C2返回的一些成果数据再次运行。startActivityForResult的掌握-ow机造如图5.7所示。有两个不持续:一个是从(1)到(2),类似于startActivity办法的不持续,另一个是从(3)到(4)。
与只触发组件间单向通信的通俗ICC办法(如startActivity)比拟,startActivityForResult ICC办法的语义更为复杂。 图5.8展现了在我们的鼓励例子中,代码是若何处置startAc - tivityForResult办法的。为了与常见的ICC办法连结一致,我们没有用Activity3的finish办法来挪用onActivityResult办法。相反,我们生成一个intent_for_ar字段来存储Intent,它将被转发还Activity2。 将被转回的Intent是由setResult办法设置的。我们重写setResult办法,将Intent的值存储到intent_for_ar。IpcSC .redirect0的辅助办法做了两个修改来间接毗连那两个组件。 起首,它挪用目标组件的dummyMain办法。 然后,它挪用源组件的onActivityResult办法。
生命周期和回调办法
在阐发Android利用法式时,一个挑战是要处理组件的回调办法和生命周期办法。在利用法式的代码中,那些办法之间没有间接挪用,因为Android系统处置生命周期和回调。关于回调办法,我们不只需要赐顾帮衬到由用户界面(UI)事务触发的办法(如onClick),还需要赐顾帮衬到由Java或Android系统触发的回调(如onCreate办法)。在Android中,每个组件都有本身的生命周期办法。为领会决那个问题,IccTA为每个组件生成了一个dummyMain办法,在那个办法中,我们对上面提到的所有办法停止建模,以便我们基于CFG的办法可以意识到它们。请重视,FlowDroid也生成了一个dummyMain办法,但它是为整个利用生成的,而不是像我们如许为每个组件生成。
东西化的鼓励性例子的CFG
图5.9表达清单5.2中介绍的东西化鼓励实例的CFG。在CFG中,getDeviceId是匿名的OnClickListener类中的一个源办法(第6行),由Activity1挪用。sendTextMessage办法是Activity2的一个汇。从源办法到汇办法有一条组件内的污点语句途径(用边表达
1到12)。
图5.9还展现,IccTA成立了一个切确的跨组件掌握--流图。因为我们利用了一种对代码停止检测的手艺来构建CFG,所以静态阐发的上下文在组件之间被保留下来。那使得IccTA可以阐发组件之间的数据流,从而使IccTA比现有的办法有更好的精度。
5.5.2 ApkCombiner: 将IAC问题简化为ICC问题
在Android中,利用间通信(IAC)类似于组件间通信(ICC)。事实上,IAC也依靠于组件通信,只是源组件和目标组件属于差别的利用法式。假设我们可以毗连利用法式,IAC问题就会酿成原则的ICC问题。
阐发多个利用法式。 如图5.5所示,FlowDroid一次只能阐发一个利用法式。因而,我们开发了一个东西,ApkCombiner,将多个利用法式合并为一个。 ApkCombiner连系了Android利用法式的所有部门,包罗字节码、资产、清单和所有资本。然后,我们利用IccTA来阐发合并后的利用法式,以计算基于IAC的隐私泄露。 因为FlowDroid-IccTA将合并的利用法式做为一个单一的利用法式来处置,它只检测基于ICC的隐私泄露。为了区分ICC泄露和IAC泄露,IccTA会查抄所有被污染的途径的语句能否属于统一个利用法式。
削减要阐发的组合利用法式的数量。 在理论中,当增加要阐发的利用法式的数量时,假设所有那些利用法式都用ApkCombiner组合,FlowDroid-IccTA的处置时间和内存需求也会增加。 为领会决那个问题,我们需要削减需要组合的安卓利用的数量。我们的处理计划是成立一个IAC图,此中一个节点是一个利用法式,一个边是一个链接,以表达利用法式之间的依靠关系。其背后的设法是,假设两个利用法式之间没有联络,就没有需要将它们合并。
IAC图是由小型独立IAC(sIAC)图(毗连组件)构成的。给定一个sIAC图,ApkCombiner将此中的所有节点(利用法式)合并为一个利用法式,然后IccTA从产生的利用法式中提取泄露。然而,在某些情状下,假设一个SIAC图仍然包罗大量的节点。那也会限造我们的办法的可扩展性。我们的处理计划是限造一个IAC泄露的长度(涉及几个利用法式)7。例如,假设一个SIAC图包罗10个节点(此中Ai与Ai+1相连,i∈{1,9}),长度限造被设置为ve。那么,该sIAC图被朋分成ive个sIAC(例如,一个sIAC是从A2到A6),IccTA能够阐发。那种权衡限造的长度使我们的办法变得可扩展。
构建IAC图的另一个益处是,新的利用能够以迭代和递增的体例添加到图中。当涉及到新的利用法式时,我们只需针对Epicc-IccTA运行它们并将它们添加到现有的IAC图中。在向IAC图添加新的利用法式时,我们不需要再次运行之前计算过的利用法式。
简而言之,通过成立IAC图,原始的安卓利用集被朋分成多个小集,IccTA能够阐发。
5.6 评判
我们的评估涉及以下研究问题:
RQ1 IccTA在精度和召回率方面与Android和FlowDroid的贸易污点阐发东西比拟若何?
RQ2 IccTA能否在实在世界的利用中识别泄露,它的速度若何?
RQ3 IccTA与其他学术界的ICC泄露检测办法比拟若何?
5.6.1 RQ1:IccTA与FlowDroid和贸易东西比力
我们在DroidBench上对IccTA与FlowDroid和IBM AppScan Source 9.0停止评估和比力,以测试ICC和IAC的泄露。不幸的是,我们无法将IccTA与其他静态阐发东西停止比力,因为它们的做者没有供给那些东西。
DroidBench。 DroidBench[43]是一组手工造造的Android利用法式,所有的泄露都是事先晓得的。 晓得利用法式中所有泄露的事实被称为空中本相,用于评估静态和动态平安东西在数据泄露方面的表示。DroidBench 1.2版包罗64个差别的测试案例,有差别的隐私泄露。然而,DroidBench中的所有泄露都是组件内的隐私泄露。 因而,我们开发了26个利用法式和23个测试案例,以扩展DroidBench的ICC和IAC泄露。一个测试案例利用于一个利用法式以测试ICC,并利用于两个利用法式以测试IAC。总共有18个利用法式包罗组件间的隐私泄露,6个利用法式包罗利用法式间的隐私泄露。新的测试案例集涵盖了表5.1中的前8种ICC办法的每一种。此外,在26个新的利用法式中,有两个不包罗任何隐私泄露。假设一个东西在那两个利用法式上检测到隐私泄露,那么检测到的泄露是错误的警报。最初,关于每个测试案例的利用法式,我们添加一个包罗水槽的不成达组件。那些无法抵达的组件用于ag娱乐平台那些不克不及准确构建组件间链接的东西。
那23个测试案例列在表5.2的第一栏。
IccTA。我们在所有的23个测试案例上运行IccTA。成果展现在表5.2中。IccTA
胜利通过了18个测试案例,此中17个测试案例包罗19个隐私泄露,一个测试案例(startActivity5)没有泄露。
在检测到的隐私泄露中,有三个是基于IAC的隐私泄露,其余的是基于ICC的隐私泄露。在startActivity5测试案例中,源组件利用数据类型为text/plain的隐含义图来启动另一个活动。然而,该测试案例中没有其他活动声明它能够领受数据类型为 text/plain 的企图。那意味着startActivity5测试用例中的组件之间没有联络。因为 IccTA 考虑到了企图的数据类型,它没有为该测试用例陈述任何隐私泄露。
startActivity4测试用例不包罗任何泄露。然而,IccTA确实陈述了一个错误的警告。原因是源组件利用带有URI的隐式企图来启动另一个活动。因为IccTA依靠于Epicc,而Epicc确实过度估量了URI的链接,所以它陈述了一个错误的泄露。
目前的版本没有考虑到内容供给者。那就是为什么IccTA漏掉了insert1、delete1、update1和query1测试案例的泄露。 所有那四个测试案例都与内容供给者有关。
FlowDroid。 在[5]中,FlowDroid已经在DroidBench的第一个版本长进行了评估。 在表5.2中,我们介绍了FlowDroid在新的23个测试案例中的成果。如前所述,FlowDroid最后被提议用于检测单个Android组件的泄露。然而,我们能够用FlowDroid的体例来计算所有单个组件的途径,然后将所有那些途径连系在一路(无论能否有实正的联络)。因而,我们估量FlowDroid能够检测到大部门的泄露,但会产生几个假阳性。表5.2的成果证明了那种预期: FlowDroid具有较高的召回率(69.6%)和较低的精度(23.9%)。在bindService{2,3,4}中,FlowDroid比IccTA多漏掉了三个泄露。颠末查询拜访,我们发现FlowDroid没有考虑办事组件的一些回调办法。
AppScan。 AppScan Source 9.0需要大量的手动初始化工做,因为它没有默认的源/汇设置装备摆设,也无法在不指定每个组件的进口点的情状下阐发Android利用法式。 我们定义了getDeviceId和log办法,那些办法在DroidBench中不断用于ICC和IAC泄露,做为源和汇,从头定义。我们还将所有组件的进口点办法(如活动的onCreate)添加为回调办法,以便AppScan晓得从哪里起头阐发。 AppScan自己不克不及检测组件间的数据流,只能检测组件内的数据流。AppScan有和FlowDroid一样的缺点,在Droid- Bench上应该有较高的召回率和较低的精度。 我们利用一个额外的脚原来连系组件之间的破绽。 正如预期的那样,AppScan的召回率很高(56.5%),精度很低(21.0%)。与FlowDroid比拟,App- Scan的表示更糟。事实上,AppScan没有准确处置startActivityForResult,因而错过了通过领受start-ForResult{2,3,4}中被挪用活动成果的办法的泄露。
结论。 IccTA在切确度和召回率方面都优于贸易污点阐发东西AppScan 9.0和FlowDroid。
5.6.2 RQ2:IccTA和实在世界的利用法式
我们在Core i7 CPU上运行具有8Gb堆的Java VM停止尝试。 为了评估我们的办法,我们用IccTA阐发了从Google Play市场以及一些第三方市场(如wandoujia)下载的3000个Android利用。IccTA在大约100小时内处置了3000个利用法式。IccTA没有检测到2575个(85.83%)利用法式的任何泄露。IccTA陈述了425个包罗隐私泄露的利用法式。 在那425个利用法式中,411个利用法式只包罗组件内泄露,14个利用法式包罗至少一个ICC泄露。 在那14个利用法式中,13个同时包罗组件内泄露和ICC泄露。IccTA检测到6989个IAC链接。此中IccTA检测到一个IAC泄露。那一成果表白,组件确其实停止通信和共享数据,但发作利用间泄露的情状很少。
关于利用内的泄露,IccTA在425个利用中检测到5986个泄露。在检测到的泄露中,147个(2.5%)是ICC隐私泄露。我们手动查抄了那147个陈述的ICC泄露,发现17个(11.6%)是假阳性。 换句话说,IccTA在实词利用上到达了88.4%的精度。误报来自于Epicc,它对组件之间的链接产生了误报。
我们在表5.3中总结了425个至少有一个破绽的利用法式中经常利用的源办法和汇类型(Java类)。 请重视,我们只计算在检测到的泄露中呈现的那些源办法和汇办法。利用最多的源办法是openConnection,它在169个利用法式中被利用了601次。利用最多的汇类型是Log,它在261个利用法式中被利用了2755次。我们研究水槽类型而不是水槽办法的原因是,在统一个水槽类型中存在大量的水槽办法。以Log汇类型为例,有八个汇办法将私有数据笔录到磁盘上。
让我们详尽描述三种泄露,每品种型的泄露都有一个。
组件内泄露:BZ .Prana .myphonelocator . IccTA检测到从类.SMSReceiver$MyLocationListener8的办法onLocationChanged中的getLongitude源办法起头的组件内隐私泄露。位置是通过类.SMSReceiver的smsReply办法中的sendTextMessage sink办法从利用法式中发送出来的。该利用法式被设想为通过SMS将位置发送到设备之外。然而,区分检测到的隐私泄露的企图不在本章的范畴内。我们将其做为我们进一步的工做。
ICC泄露:com .dikkar .ifind . IccTA在那个利用法式上检测到一个基于ICC的隐私泄露。 在类.iFindPlaces的onLocationChanged办法中,getLongitude源办法被挪用并返回Android手机的位置。 然后,位置被转移到另一个组件,.PlaceDetail,此中j类的办法b被挪用。 在办法b中,一个水槽办法Log .d用ServiceHandler标签名将位置笔录到磁盘中。为了验证检测到的泄露,我们开发了一个名为LogParser的Android利用法式。通过赐与android .permission .READ_LOGS 9的权限,LogParser陈述了所有由Find Places笔录的位置。
IAC泄露:com .bi .mutabaah .id到jp .benishouga .clipstore 。 IccTA陈述了利用法式com .bi .mutabaah .id和利用法式jp .benishou - ga .clipstore之间的IAC泄露。在组件com .bi .mutaba - ah.id.activity.Statistic中挪用了源办法findById,获得了一个TextView的数据。然后,数据被存储到一个带有两个额外的定名为extra .SUBJECT和extra .TEXT的Intent中。之后,挪用startActivity ICC办法将数据发送到jp .benishouga .clipstore利用法式,它从具有不异额外名称的企图中提取数据并将所有数据写进一个ile。
结论。IccTA在现实世界的利用法式中,在合理的时间内发作了泄露。虽然如斯,IccTA只检测到了一个IAC泄露。那表白利用法式之间的泄露是稀有的。
5.6.3 问题3:与其他学术东西比力
我们确定了两个可以处置ICC泄露的学术东西: SCanDroid [56]和SEFA [136]。
然而,ScanDroid未能陈述任何泄露,SEFA也不成用。因而,我们无法在DroidBench上评估它们。
为了答复那个研究问题,我们存眷并讨论各类办法的一些关键方面。SCanDroid和SEFA都利用了途径婚配的办法,它为所有零丁的组件计算途径,然后将一些途径组合在一路,能否组合两个途径的决定由婚配算法给出。途径婚配办法至少有两个次要缺点。
起首,即便对每个组件停止了污点阐发,当SCanDroid和SEFA连系污点途径时,阐发的布景也会丧失,因为阐发是在连系途径之前停止的。IccTA不存在那个问题,因为它在代码级别毗连组件,然后停止阐发。因而,它保留了两个组件之间的数据流。丧失上下文会降低东西的精度。事实上,一个企图能够照顾数据,也就是说,它可能包罗良多额外的键/值对,但此中只要一部门是灵敏的。一个切确的东西需要区分它们,以制止假阳性。关于途径婚配办法来说,区分它们其实不随便,因为它们在婚配两个可用途径时不保留企图的形态。
其次,一些特殊的ICC办法,如startActivityForResult,用婚配算法处置起来很困难。 当特殊的ICC办法存在于一个被多个组件挪用的类中时,情状会变得愈加蹩脚。 假设一个组件Activ - ity4也利用清单5.2中的ButtonOnClickListener类来与其他组件通信。我们在图5.10中展现了那种情状。途径婚配的办法起首会找出一条从startActivityForResult ICC办法到Activity3的途径。在Activity3的finish办法被挪用后,源组件的onActivityResult办法被Android系统挪用。 问题是很难晓得哪个组件(Activity2或Activity4)是源,因为它们都利用了创建Intent的统一个ButtonOnClickListener类。事实上,静态地处理那个问题长短常困难的,因为它是由Android(或Java)的动态绑定机造形成的。 在我们的办法中,IccTA通过明白挪用源组件(Activity2或Activity4)的恰当的on-ActivityResult办法(见图5.7和5.8)来处理那个问题,那要感激辅助类IpcSC。
结论。即便我们无法评估更先进的检测ICC泄露的东西(SCanDroid和SEFA),IccTA似乎更切确,次要是因为它保留了组件之间的上下文,不像途径婚配办法。
5.7 局限性
在本节中,我们将讨论IccTA的局限性。
FlowDroid。IccTA基于FlowDroid停止静态污点阐发,因而与FlowDroid的局限性不异。IccTA只在参数是字符串常数的情状下才会处理检测性挪用。它对多线程也是无视的。我们履历过FlowDroid无法准确阐发一些利用法式(内存消耗太大或者挂起)。我们从阐发5000个利用法式起头,只保留3000个能与FlowDroid一路工做的利用法式。在一个大的办事器上运行IccTA可能会大大削减下降的阐发数量。此外,我们十分有自信心,FlowDroid的下一个版本将处理那个问题。
Epicc。IccTA依靠Epicc来计算组件之间的链接。因为Epicc不处置URI,它不克不及为ContentProvider计算ICC链接,并且当其他三品种型的组件利用URI停止通信时,会产生误报。在理论中,因为假阳性的存在,链接的数量是浩荡的。我们查抄那些链接(企图和企图过滤器),只保留不利用URI的链接。
IccTA。目前,IccTA其实不处置一些很少利用的ICC办法,如sendActivities或sendOrderedBroadcastAsUser。组件之间发送的数据有一个企图,被表达为键/值对。当一个有污点的数据被放在企图中时,IccTA会污点所有的键/值对。那可能会招致假阳性,假设一个有污点的数据被放在一个企图中,而在领受组件中,一个没有污点的数据被从企图中检索出来,并被发送到水槽中。
当地代码。 一些安卓利用被打包成了当地代码。IccTA只阐发包罗Dalvik字节码的dex ile。
5.8 结论
本章讨论了在多个组件或多个利用法式中停止数据流阐发的次要挑战。我们介绍了IccTA10,一个基于ICC的污点阐发东西,可以停止如许的阐发。 特殊是,我们证明了IccTA能够通过对利用法式的代码停止阐发,供给一个高度切确的掌握流图来检测基于ICC的隐私泄露。 与之前的办法差别,IccTA可以对两个组件之间的数据流停止阐发,并对生命周期和回调办法停止足够建模,以检测基于ICC的隐私泄露。当在DroidBench上运行IccTA时,其精度到达了95.0%。当在从Google Play商铺以及其他第三方市场随机抉择的三千个利用法式上运行IccTA时,它在12个利用法式中检测到130个基于组件间的隐私泄露。
第六章
在生活中:平安和隐私的动态办法
对Android利用法式停止静态阐发,能够发现平安问题,如GPS坐标从设备中泄露出来。然而,静态阐发其实不间接在用户的设备上运行,因而没有考虑到设备的上下文。本章的目标是让各人领会动态办法若何填补静态阐发。我们是第一个提出在体内,即间接在设备上动态检测Android利用的东西链的人。我们提出了两个对利用法式停止检测的用例,以表白动态办法是可行的,它们能够操纵静态阐发的成果,而且从平安和隐私的角度来看,它们对用户是有益的。 此中一个用例是一个内粒度的权限系统原型,利用户可以随意禁用或启用利用法式的权限。
本章是基于以下手艺陈述中颁发的工做:
- Alexandre Bartel, Jacques Klein, Martin Monperrus, Kevin Allix and Yves Le Traon: Im- proving Privacy on Android Smartphones Through In-Vivo Bytecode Instrumentation, ISBN 978-2-87971-111-9, 2012.
6.1 简介
在谷歌的官方市场(Google Play,以前的AndroidMarket)上,每月有超越10000个新的利用法式。2 关于最末用户来说,在她的智妙手机上下载一个利用法式类似于在苹果树上抉择一个苹果:她只看到外表,没有证据表白此中没有虫子。不幸的是,有许多差别品种的蠕虫期待着传染智妙手机,如泄露私家数据的歹意软件和唤喊高价号码的告白软件。
在那一章中,我们声称改进安卓利用隐私的有效和可利用的手段是通过在智妙手机上间接对利用的字节码停止仪器化来施行运行时监控和拦截利用与安卓仓库的互动(体内)。在进一步介绍我们的奉献之前,让我们保卫我们的关键主张。
为什么要停止运行时监控和拦截? 我们想在运行时容许或不容许一个利用法式的行为。 我们利用运行时监控,因为它包罗看察一个利用法式在施行过程中的行为。它搜集某些目标或拦截利用法式和系统其他部门之间接口的所有改变。在本章中,我们将讨论两个涉及运行时监控和拦截的案例研究,包罗在Android软件仓库之上实现一个内粒度的权限模子,如[123]所提议的。
为什么要停止字节码东西化?至少有两种办法能够停止运行时监控和拦截:修改Android软件栈或字节码东西化。 软件施行仓库的修改包罗改动操做系统或核心库以拦截所需信息。在安卓系统中,那意味着改动底层内核、Dalvik虚拟机或安卓框架。除非说服安卓联盟,不然那在摆设上相当有限,因为一般的最末用户既没有权力(被监禁的手机)也没有才能如许做。 此外,那个处理计划需要用户改动他们的固件,那是一个非同小可的使命,而所谓的安卓系统的碎片化问题又使其愈加复杂,因为没有一个单一的安卓系统,而是许多差别的安卓系统,每个系统都是为运行在特定的设备(平板电脑、智妙手机......)而定造的。假设操做系统被修改,就需要为每个可能的Android版本创建一个自定义的东西化版本,那在理论中是不随便做到的。然而,字节码东西化是在不克不及修改的施行平台上施行运行时监控的最简双方法之一。在为改进隐私而停止的粒度政策施行的布景下,我们可以--因为字节码东西化--对已经摆设在安卓智妙手机上的利用法式施行粒度答应模子,而无需对安卓软件栈停止任何修改。
为什么要在智妙手机上间接停止体内东西化?Bytecode东西化能够在设备之外停止,例如利用互联网上的长途办事。然而,许多国度制止向第三方办事分发二进造文件(例如法国)。 此外,一些市场的办事条目(如Android的Google Play)也不容许如许做。在设备上间接对利用法式停止仪表化,能够使利用法式连结在设备内。
总而言之,我们认为在挪动设备上确保平安和隐私的最有效和最适用的办法是间接在智妙手机上对利用法式的字节码停止检测(体内),该检测是为特定的平安或隐私问题而定造的。我们的次要奉献是::
- 我们成立了一个东西链,能够间接在Android设备上主动从头打包Android利用法式;
- 我们已经成立了一个东西链,能够间接在Android设备上主动阐发Android利用;
- 该东西链已经通过实现两个原型停止了测试,那两个原型增加了末端用户的隐私。一个是删除告白,另一个是让用户完全掌握利用法式的运行权限。
- 如许一个东西链的可行性已经得到了评估。限造和挑战已经被指出。
据我们所知,我们是第一个提出在设备上间接主动转换安卓利用的东西链的3。
本章的组织构造如下: 第6.2节为读者供给了两个场景,阐了然Android利用字节码东西化的需要性。 第6.3节描述了间接在Android设备(智妙手机、平板电脑......)上对Android利用停止编程的东西链。第6.4节介绍了有价值的字节码东西的设想和实现,以包管智妙手机的平安和隐私。第6.5节展现了在合理时间内运行整个东西链的可行性。最初,第4.8节总结了本章。
6.2 字节码东西化的动因
在差别的场景下,间接在智妙手机设备上操做和阐发Android利用法式的字节码是有益的(体内)。在本节中,我们将介绍两个有价值的用例: AdRemover和BetterPermissions。
那两个案例都改进了用户的隐私。AdRemover障碍了告白库的工做,因而,在统一时间,避免他们发送与定位(GPS坐标,...)或设备自己的私家信息,如IMEI(国际挪动设备身份)。BetterPermissions利用户有才能启用或禁用利用法式的权限。在一个极端的情状下,用户期看没有任何利用法式可以拜候她的联络人列表,她将从手机上的所有利用法式中删除联络人权限。其成果是为用户供给了更好的隐私。
6.2.1 往除告白
近一半的安卓利用嵌进了第三方代码来处置利用内告白[101]。有相当大比例的告白撑持的利用法式包罗至少两个告白库[120]。
此外,安卓利用做为自力更生的软件包分发,绑缚了专门开发的代码和他们可能需要的第三方库,如仅有的二进造告白模块。
安卓系统施行的是基于每个利用政策的平安模子:要么一个利用的所有部门都受益于一个给定的权限,要么其任何部门都不受益。那意味着,当用户对一个利用法式授予权限时,她现实上是对可能由差别实体编写的组件授予权限,包罗告白库。
例如,一个报纸利用法式可能被容许将其位置发还给利用法式的发布者,如许她就能看到本地的新闻。 然而,从隐私的角度来看,嵌进式告白库不该该被容许向告白公司发送位置数据。目前,用户面对一个两难境地:她要么降低她的隐私程度期看,要么不利用一个有价值的利用法式。
对平台的那一限造的处理办法是制止在体内利用告白库。
那可能有积极的副感化,因为告白库对电池的利用也有很大的影响。根据比来的一项研究[100],第三方告白模块能够对免费利用法式中所破费的能量的65%-75%负责。
6.2.2 细粒度的答应政策
安卓框架依靠于一个基于权限的模子,并遵照一个 "要么全数,要么全数 "的政策。在安拆时,用户必需承受或回绝利用法式所要求的所有权限。只要当所有要求的权限被承受时,利用法式才会被安拆。没有办法只承受某些权限(如拜候当地化数据)而不承受其他权限(如毗连到互联网)。用户必定要完全相信编写权限列表的利用法式开发者。Enck等人[48]已经指出,一个拥有多个灵敏权限的利用法式是一个实正的平安威胁。例如,假设一个利用法式要求有发送短信的权限和读取联络人名单的权限,那么联络人名单就有可能通过短信发送至长途德律风。
一个细化的权限模子包罗让用户可以根据本身的利用情状,为利用法式指定本身的权限集。 设备上所有利用法式的所有权限集构成了平安战略。然后,基于权限的底层系统将强逼施行那个用户自定的政策。
在未经修改的安卓平台上,运行如许的用户级平安战略是不成能的,因为未经修改的利用代码。然而,正如我们在后面所展现的,通过在安拆时把持利用法式的字节码,它确实是可能的,在体内。
6.3 体内字节码仪器化的东西链
本节介绍了我们在体内对Android利用停止字节码东西化的定见,即间接在智妙手机长进行。读者能够参考第2.1节,领会关于Android仓库和Android利用法式的更多细节。
6.3.1 要求
对一个完全可运行的Android利用法式停止仪器化和从头包拆其实不简单。它包罗从利用代码中提取可施行代码,阐发和笔录它,重建一个新的可运行的Android利用,并再次签订它,因为操做系统要求利用被签订。
我们的东西链有以下要求:
1. 安卓操做系统必需是未修改的(为了6.1节中提出的普遍适用性);
2. 运行Android利用法式的Dalvik虚拟机必需是未修改的,特殊是在设置装备摆设值方面,如更大堆大小(为了普遍适用,见第6.1节);
3. 用于检拆字节码的硬件必需是市场上常见的智妙手机的代表。
6.3.2 东西链
字节码仪器化过程有以下几个步调: 1) 从安卓利用apk文件中提代替码;2) 用字节码操做东西修改提取的代码;3) 从头构建一个包罗修改内容的新安卓利用
3)从头构建一个包罗修改正的代码的新的Android利用法式。
那三个步调能够合成为五个根本步调,如图6.1所示:i)提取并将Dalvik字节码转换为Java字节码(步调a-b),ii)把持字节码(步调b-c),iii)将那种表达办法翻译回Dalvik字节码(步调c-d),iv)重建一个新的apk文件(步调d-e),v)最初用一个新的私钥签订所有文件(步调e-f)。如今让我们讨论一下每个步调中利用的东西。
i) 提取Dalvik字节码 第一步,如图6.1.(a-b)所示,是从apk ile中提取.dex ile类,并将其转换为能够用原则的未修改的Java字节码阐发东西包阐发的Java字节码类。 关于那一步,我们利用东西dex2jar4。
ii) 仪表字节码 在那一步,我们用两个差别的东西停止尝试,它们能够操做字节码。回忆一下,字节码操做是图6.1中(b)到(c)的那一步。利用差别的东西使我们有时机丈量它们之间在施行时间和内存消耗方面的差别,并决定哪一个更合适于在内存受限的系统中操做字节码。
ii.a) Soot。用Soot阐发东西箱将类转换为Jimple。Soot[75]是一个用于Java法式的开源阐发东西箱。它能够对Java源代码或字节码停止操做。它容许开发者对法式停止阐发和转换。例如,法式内的ow阐发能够确定一个变量在代码中的某个点能否能够为空。Soot还能够停止差别的挪用图阐发,那对特定的字节码阐发十分有用。Soot中的大大都阐发和转换都利用一种喊做Jimple的内部表达。Jimple是Java字节码的一种简单的无仓库表达。我们把Soot移植到Android系统上,把它的Java字节码转换为Dalvik,并创建一个封拆的Android利用法式。据我们所知,以前没有任何工做将安卓字节码做为一种笼统,能够间接在智妙手机长进行静态阐发。
ii.b) ASM。我们体味到,Soot有时很慢,需要大量的资本(特殊是内存)。因而,我们也运行ASM来停止字节码阐发。ASM[25]是一个Java字节码工程库。它的特征之一是它是轻量级的,因而更合适在内存或处置资本有限的系统上运行。它次要被设想用来操做和转换字节码,虽然它也能够用来停止一些法式阐发。它有一个核心API来施行简单的转换,还有一个树形API来施行更复杂的字节码转换(那需要更多的CPU处置和内存空间)。
iii) 将修改后的字节码转换回Dalvik字节码 一旦类被阐发东西箱阐发和修改后,就用dx5将其转换回Dalvik字节码,dx5会从Java类文件中生成类.dex ile。那个步调在图6.1中的c-d边展现出来。
iv) 重建利用法式 如图6.1(d-e)所示,在第四步之后,一个新的Andoid利用法式被成立。 重生成的类.dex、数据和原利用法式的安卓清单都被插进到一个新的zip6 ile中。
v) 签订修改后的利用法式 Android要求利用法式停止加密签名。 因而,生成的压缩包的所有文件都利用新创建的一对公钥/私钥(在图中没有表达)停止签名,新的公钥被添加到压缩包中(在图中没有表达)。我们利用keytool和jarsigner Java法式来签订利用法式(图6.1.(e-f))。
用新钥匙签订利用法式可能会招致利用法式之间的兼容性问题。例如,两个或更多用统一密钥签名的利用法式能够共享统一个历程。为了使那个功用陆续工做,需要在旧钥匙和新钥匙之间连结一对一的映射,以便用统一个重生成的钥匙签订两个转换的利用法式(最后用
不异的密钥)用不异的重生成的密钥签名。 庇护那种映射和处置利用法式之间的那种兼容性不属于本章的范畴。
我们在Android上设想了一个利用原则东西的字节码操做过程。 下面介绍两个详细的字节码东西化原型的设想和实现。
6.4 用例设想和实现
任何操纵第6.3节中介绍的东西链的用例城市阐发或修改一个利用法式的字节码。阐发或修改字节码由图6.1中的步调(b-c)表达。如今我们介绍一下我们是若何实现和评估第6.2节的两个用例的。它们都是修改利用法式的字节码。 AdRemover修改字节码以删除告白。 BetterPermissions修改了字节码,以便为用户供给一个细化的权限战略系统。
6.4.1 AdRemover的实现
我们专注于两个普遍利用的Android告白模块: AdMob和AdSense。告白不是安卓系统的一部门,而是存在于利用法式的字节码中。因而,利用法式不共享告白库代码。然而,它们各自都有一份库代码的副本。禁用告白需要对每个包罗告白库的利用法式停止检测。
告白需要I/O操做来获取告白数据。一个利用告白库的安卓利用开发者不期看她的利用因为告白库而瓦解。那就是为什么告白库的开发者在设想告白库时要特殊重视反常情状的原因。他们估量I/O操做会经常失败,那取决于不成揣测的情况。例如,假设设备不再有收集笼盖,就会抛出一个反常。
基于那一看察,我们假设I/O代码已经被告白开发者放置在Try/Catch块中,以恢复I/O失败引起的反常。 我们的东西操纵那一假设,按捺利用法式的告白包的每个Try/Catch部门。关于它碰着的每一个Try/Catch块,我们的东西城市提取被处置的I/O反常的类型,创建如许一个反常对象,并在Try块的最起头插进一条抛出那个反常的指令。
为此,我们搜集了那些库所利用的Java包的名称,并将AdRemover设置为只对属于那些包的类停止操做。我们写了两个AdRemover的实现: 一个利用Soot,一个利用ASM。
6.4.2 BetterPermissions: 细粒度的权限战略治理
在那种情状下,细粒度的战略是指用户指定哪些权限被授予利用法式。在现实世界中,用户只熟悉权限和利用,所以把战略限造在利用层面而不是更低的层面(如Android组件或Java办法)长短常合理的。然而,出于阐明的目标,本节中的战略包罗了Java办法和权限之间的映射。
为了使以用户为中心的战略存在,我们需要对每个期看掌握的利用法式的字节码停止检测。回忆第2.1节,Android利用法式通过Android API与Android系统通信。该东西检测所有受一个或多个权限庇护的API挪用,并将那些挪用重定向到一个战略办事。战略办事是独立的Android利用法式的一个Android办事组件。根据用户定义的战略,它受权或不受权利用法式挪用受庇护的办法。
当东西化的利用法式运行时,用户定义的战略由战略办事来施行。事实上,关于每一个东西化的办法,运行中的东西化法式城市挪用战略办事,并查抄战略。假设政策容许原始API办法的挪用,则施行API挪用。不然,就会施行一个假的实现,并返回一个假的默认值。
我们的原型东西在用户层面(也称为利用层面)施行用户自定的政策。它容许以前不克不及修改系统战略的用户为一组利用法式施行他们本身的战略。 修改代码以插进平安查抄被称为内联参考监控(IRM),由Erlingsson等人和Evans等人初次提出[50, 51, 52]。
为掌握或限造一个利用法式的权限,它的字节码必需被东西化。 所有需要一个或多个权限的办法挪用[bartel2012automatically, 53]都被包裹在代码中,那些代码依次为:1:
1.询问战略办事,利用法式能否被受权挪用该办法
2. 根据政策办事的答复,要么挪用原始办法,要么挪用假办法。
例如,节点7的getLocation(p1)办法挪用(需要permis- sion GPS)在图中已经被挪用战略办事所包裹。假设政策批准了那个挪用,原始的getLocation(p1)就会被施行,不然就会挪用一个假的办法,从头酿成一个假的默认值。
总共有N个东西,此中N是利用法式字节码中所考虑的API挪用的数量。
确定战略 下一步,如图6.3所示,是确定关于东西化利用的战略。用户为每个利用法式定义一组容许的权限。在幕后,战略会生成一个需要启用权限的所有Java办法的列表。那些办法被设置为受权。在图 6.3 中,只要 Instrumented NewsReader 的办法 getLocation() 被容许。
请重视,那一步能够先施行,只对未被战略受权的办法挪用停止检测。然而,对每个需要一个或多个权限的API办法挪用停止仪器化,使得在运行时改动战略成为可能。
战略办事 最初,当仪器化的利用法式运行时,战略办事会强逼施行,如图6.4所示。关于每一个东西化的办法(那里的原始/东西化的办法是getLocation及其相关的权限GPS),运行中的利用法式会挪用policyAccepts()(步调A),并通过挪用policyHas()(步调B)查抄战略。办法policyAccepts()假设政策容许原始办法,则返回true,假设不容许则返回false。假设政策容许原始办法,则挪用原始办法(图6.4中就是那种情状,因为步调C返回true)。不然,对应于原始办法的存根办法被施行。那里,存根处置办法getLocation没有被施行。我们将战略办事做为一个Android办事来实现,将东西化代码做为静态阐发东西Soot的一个插件。
6.4.3 评估
我们如今查抄我们的用例实现能否有效。关于那两个案例,我们针对一个实在世界的利用法式运行指令,并运行由此产生的修改后的利用法式。
AdRemover 我们通过在An- droid市场上随机抉择一个利用法式来测试我们的东西能否有效。我们确保该测试利用法式利用AdRemover目前处置的两个告白模块之一。
起首,我们在安卓设备上运行未修改的测试利用法式,并确保它是一个工做的利用法式,而且它确实展现告白。
然后,我们将那个利用法式发送到我们的东西链(与Soot实现),在PC上运行。修改后的利用法式仍然有效,而且不再展现告白。我们在测试过程中监测收集毗连,发现该利用法式不再发送任何告白恳求。
最初,我们再次处置未修改的利用法式,此次是在智妙手机上间接运行字节码操做。运行修改后的利用法式的成果与在原则PC上修改后的利用法式的成果不异。
BetterPermissions为了评估内粒度战略,我们抉择了另一个随机的利用法式,并对其停止检测,以包住每个与GPS相关的权限灵敏的API挪用。该利用法式被检测,然后被从头打包成一个新的签名利用法式。我们在一个安卓设备上运行那个东西化的利用法式,并利用差别的战略对其停止测试。用户自定的战略如期施行了。
总而言之,那两种字节码转换的成果是利用法式可以准确运行。那些最后的成果很重要,因为那两个用例阐了然利用字节码东西链能够实现什么。 对我们来说,同样重要的是,考虑到当前智妙手机的内存和CPU限造,所考虑的东西链能否能够在Android利用法式的大型数据集上现实运行。 下一节将通过丈量体内东西的施行时间和内存消耗往返答那个问题。
6.5 体内仪器的性能
在那一节中,我们介绍了利用第6.3节中提出的东西化过程的成果,并在图6.1中停止了总结。我们的目标是领会:1)在硬件资本受限的情状下,能否有可能在智妙手机上操做字节码。2)它能否需要合理的时间。
6.5.1 办法
我们在一组130个Android利用法式上丈量了东西化过程的各个步调的施行时间。那个聚集在第6.5.3节中有描述。我们在三个差别的安卓智妙手机上运行仪器化过程,那些手机的设置装备摆设在第6.5.2节中介绍。
整个过程的可行性是通过东西链的每一步(1:dex2jar,2:Soot/ASM,3:dx,4:customZip,5:签名)的时间来权衡。 运行每一步的时间和胜利通过每一步的利用法式的数量也得到了丈量。
关于该过程的第二步(步调:对字节码停止阐发),我们对ASM和Soot停止评估。关于ASM,我们丈量了在AdRemover案例研究中对Java字节码停止阐发所需的时间。AdRemover转换操纵ASM树形API来施行6.4.1中描述的try/catch块操做。 通过丈量生成AdRemover和BetterPermissions案例研究的Java类所需的时间来评估Soot(Ad- Remover是用ASM和Soot实现的)。
6.5.2 尝试素材
我们在三个基于Android的智妙手机设备长进行尝试。它们的设置装备摆设详见表6.1。次要的区别是处置器的时钟速度(0.8,1.2和1.4 GHz),主内存的总量(512,768和1024 MiB),Android版本(2.2,2.3.4和4.0.3)和Dalvik虚拟机的更大堆大小(24,32和48)。因为堆大小掌握了单个历程可分配的更大内存,它也掌握了可同时分配的更大对象数量。
核心的数量也是差别的。 然而,在尝试过程中,我们并没有操纵多核的优势。那种硬件契合6.3.1中提到的要求#3。
6.5.3 数据集
我们将整个尝试协议利用于一组130个安卓利用,那些利用是从安卓市场的前500个利用中随机挑选出来的7。它们逾越了差别的范畴,如娱乐、游戏、通信、多媒体、系统或新闻。那个数据集不是艺术性的,因为它只包罗实在世界的利用。
为了更好地概述那些利用,图6.5展现了关键的利用目标,如图表。它们表白大大都(75%)的Android利用的Dalvik字节码小于614KiB,小于602个类,均匀办法度小于3。
6.5.4 Dalvik到Java字节码的转换
利用dex2jar从Dalvik可施行代码到Java字节码的转换时间如图6.6所示。
看察1 在智妙手机2和平板电脑1上,75%的利用将dex iles转换为jar的时间不超越60秒。在我们的Android利用数据集上,转换时间不超越250秒。
看察2 更大的Dalvik字节码(4000 KiB)的利用法式在智妙手机2和平板电脑1上都能胜利转换。
看察3 我们重视到,在Dalvik字节码大小小于4000KiB的情状下,转换时间与dex ile的大小(形式为a - X + b)是线性的。利用线性回回,我们发现关于智妙手机2,a等于0.069,b等于0.3。关于平板电脑1,我们有,0.049和-0.4。转换时间和Dalvik字节码的大小之间的线性关系使我们可以在理论上揣测转换任何大小的Dalvik字节码所需的时间(假设我们揣度出大于4000KiB的大小)。例如,处置具有10 MiB的Dalvik字节码的Android利用法式的时间,关于智妙手机2来说是700秒,关于平板电脑1来说是500秒。
结论1 在体内将Dalvik字节码转换为Java字节码在几分钟内是可行的。
局限性:智妙手机1无法处置任何dex ile。别的,当利用智妙手机2和平板电脑1时,别离有26个和11个dex ile招致转换的Android利用法式dex2jar瓦解。那种瓦解是OutOfMemory或StackOverflow反常。
智妙手机1的成果是由Android的硬编码更大堆大小(32 MiB或48 MiB)阐明的。关于其他两个设备,瓦解的原因是默认的8 KiB仓库大小。总的来说,在智妙手机2上有104个(80%)安卓利用法式被胜利转换为jar ile,在平板电脑1上有119个(91%)。
然而,因为安卓设备变得越来越强大,安卓系统的默认堆大小也在增长。事实上,在安卓2.2系统中,堆的大小是24 MiB,在安卓2.3.4系统中是32 MiB,在安卓3.0系统中是48 MiB。那种继续的增长将使我们的东西链可以转换具有更大Dalvik字节码大小的Android利用法式。
此外,一些利用法式可能被稠浊了,以避免Dex2jar将Dalvik字节码转换为Java类。 在尝试过程中,我们没有碰着任何稠浊的情状。 我们的东西链依靠的是独立的组件。因而,假设Dex2jar不克不及处置某些稠浊手艺,它能够很随便地被处置那些手艺的同等组件代替。
6.5.5 字节码把持的性能
本节介绍了我们利用两个差别的东西库停止体内字节码操做的性能丈量: ASM和Soot。
用ASM停止操做
利用ASM对Java字节码停止转换的时间如图6.7所示。在那个尝试中,6.2.1中描述的AdRemover转换是用ASM实现的。
看察4 所有在智妙手机2上用dex2jar胜利转换的104个利用法式都被ASM胜利处置。
胜利地被ASM在体内处置。它在不到600秒的时间内处置了每一个jar(更大4MB的大小)。
看察5 我们重视到,关于小于4000KiB的Dalvik字节码,转换时间与jar的大小(形式为a-X+b)呈线性关系。利用线性回回,我们发现关于智妙手机2,a等于0.146。关于平板电脑1,我们有,0.025。
结论2 在智妙手机上利用ASM把持字节码是可行的。考虑到我们的转换和数据集,ASM并没有与智妙手机资本不相容的特殊内存或CPU要求。
用Soot停止操做
我们如今考虑AdRemover转换的Soot实现。在130个An- droid利用法式中,只要3/130在智妙手机2上被准确处置,19/130在平板电脑1上被准确处置。
看察6 只要最小的利用法式(就Dalvik字节码而言)能够被转换。例如,在智妙手机2上转换任何小于或等于20KiB大小的jar需要不到30秒。然而,较大但较小的利用法式(在25%的四分位数),利用Soot东西需要长达18分钟。
结论3 在体内利用Soot只对最小的利用法式是可行的。我们假设,堆的大小是体内利用Soot的次要障碍因素。为了验证那个假设,我们在一台台式电脑长进行了一个尝试,包罗阐发我们的安卓利用数据集,那些利用具有差别的更大堆大小(从5Mib到50Mib,以5Mib为单元)。成果如图6.8所示。 Soot可以处置67个堆大小为50Mib的利用法式。 那些成果清晰地表白,最多有一半的Android利用能够在堆大小为50Mib的情状下被处置。在Java和Dalvik虚拟机上堆的利用(因而所需的更大尺寸)类似的假设下,那意味着内存现实上是在Android上利用Soot的次要阻塞因素。
6.5.6 Java字节码到Dalvik的转换
一旦一个利用法式在Java字节码层面上被检测到,就必需将其转换回Dalvik字节码。利用dx东西从Java类到dex ile的转换时间如图6.9所示。
看察7 智妙手机2上的33/130个和平板电脑1上的39/130个利用法式的Java字节码已经胜利转换为Dalvik字节码了。
看察8 jar iles从20到400 KiB的转换时间不超越80秒。
结论4 Dx东西是东西链的一个瓶颈。它只能准确处置25%到30%的利用法式。原因是它把每个Java类都放在内存中,并遭到体内处置的内存限造,与Soot类似。那个东西是现成的,能够通过对类的处置来限造内存消耗,从而优化在资本有限的设备上运行。.
6.5.7 创建一个新的apk文件
从东西化的Dalvik字节码创建一个apk ile的时间如图6.10所示。重视,关于那一步,输进集不是前一步的输出。我们只要39/130个利用法式在前面的步调中被准确处置过。在每一步,都有一些申请失败。关于剩下的91/130个无法计算出原始东西化的Dalvik字节码的利用法式,我们把利用法式的原始Dalvik代码做为输进。如许一来,上一步的问题就不会骚乱第四步的成果。
看察9 121/130个输进被胜利处置。前一个apk ile的大小和新apk的创建时间之间没有明显的关系。只要9/130个利用法式产生反常,因为它们的大小太大,因而不克不及被压缩东西处置。
看察10 关于95%的利用法式,无论设备和原始apk ile的大小若何,都需要少于ive秒。
结论5 在智妙手机上创建apk文件是可行的。与转换字节码或用Soot操做字节码的时间比拟,创建一个新的apk ile的时间能够漠视不计。
与Dalvik大小没有线性关系,正如图6.6和6.9中的情状一样。那可能是因为在生成apk文件时,除了字节码大小外,还有其他因素在起感化,好比处置媒体文件(图像、声音等),那些因素有时会收配Dalvik字节码大小。
6.5.8 对生成的apk文件停止签名
图6.11表达利用法式的签名时间。
看察11 120/130个安卓利用在平板电脑1上被胜利签订。apk ile的大小和apk ile的签名时间之间没有明显的关系。 14/130个利用法式产生了一个反常,因为它们的大小太大,因而不克不及被处置(智妙手机2上有14个,平板电脑1上有10个)。
看察成果12 关于95%的利用法式,无论设备和apk ile的大小,都需要最多12秒的时间来签订利用法式。
结论6 在智妙手机上签订apk ile是可行的。与apk ile的创建步调类似,计算时间能够漠视不计。 在智妙手机1和智妙手机2之间看察到的差别反映了其CPU时钟频次的差别。
6.5.9 结论
我们如今总结一下我们对安卓利用停止体内修改的尝试成果。
可行性
表6.3总结了智妙手机2的所有尝试,并强调了整个办法的可行性。
计算了Soot和ASM版本的东西链的所有步调的总施行时间。关于一个基于ASM的仪器,处置一个利用法式需要120秒的中位时间,也就是2分钟。我们认为用户会附和在起头利用一个利用法式之前期待2分钟,假设他们在那个东西化过程中得到更多的包管,能够获得更好的隐私。在那2分钟内,手机仍然能够利用,因为只利用了一个核心(大大都智妙手机的特征是多核心CPU),并且只能利用虚拟机容许的更大堆内存(而不是所有内存)。
那些尝试表白,在安卓系统上间接操做字节码是可行的。该过程中最高贵的步调是Dalvik到Java字节码的转换,反之亦然,以及Soot字节码操做步调。
hopsasa
若何进步In Vivo Instrumentation的性能?
根据我们的阐发,次要的阻塞因素是内存。 阐发和转换利用法式所需的更大堆大小是许多转换步调的一个问题。我们认为那个问题很随便处理:1)下一代更强大的硬件;2)即将推出的安卓操做系统和虚拟机版本,它们的更大堆大小可能会大大增加(例如,安卓4的堆大小被设定为48 MiB)。
Dalvik到Java的转换和Java到Dalvik的转换是两个十分耗时的步调。它们利用未经修改的Dex2jar和dx版本。 有两种办法能够征服那些消耗资本的东西。
起首,那些东西历来没有被优化过以在资本有限的平台上运行。我们相信,在CPU和内存消耗方面有许多优化的时机。
第二,我们能够用更好的替代品来代替那些东西。例如,一个用于操做Dalvik字节码的类似ASM的li-brary将容许跳过Dalvik到Java和Java到Dalvik的转换。如许的东西正在呈现,如ASMdex8。另一个处理计划包罗间接从Dalvik字节码到Jimple字节码的双向转换,那两者都是基于存放器的。我们确实正在开发一个Dalvik到Jimple的翻译原型,喊做Dexpler[12]。
总而言之,我们的成果表白,我们能够合理地想象在最多5分钟内对100%的数据集利用法式停止字节码操做。
对有效性的威胁
如今让我们来讨论一下对我们尝试成果有效性的威胁。
施行错误:我们的成果是成立的,因为在施行过程中,涉及到的任何ive法式,以及我们编写的胶水和丈量代码中都没有严峻的错误。
数据集的可妥帖性: 我们的数据集可能无法代表示实世界中利用的Android利用法式。
线性揣度: 我们为Dalvik到Java和Java到Dalvik的转换所成立的线性关系在字节码大小小于或等于300KiB时是成立的。关于尺寸更大的字节码,它可能不成立。在存在非线性奇异点的情状下,可能无法阐发大型利用法式。
字节码操做时间: 我们关于字节码操做时间的成果是通过相对简单的转换获得的。可能的情状是,复杂的转换不是统一数量级的,并且消耗的内存要多得多。然而,关于第6.2节中介绍的用例,仪器化只包罗监控和代办署理Java办法。
6.6 结论
我们在本章中提出并评估的东西链是一个里程碑,它回应了Stravou等人[123]比来提出的关于迫切需要停止字节码阐发以在手机长进行体内平安查抄的说法。我们已经1)提出了一个东西链,容许对Android字节码停止操做、仪器化和阐发;2)表白有可能在合理的时间内间接在未修改的Android软件栈的未修改的智妙手机上运行该东西链。详细来说,我们的尝试表白,利用ASM,我们数据集中的39个(30%)利用能够在952秒内完成东西化(中位时间为120秒)。此外,我们还讨论了我们看察到的特殊限造,如Android系统的硬编码堆大小。
我们相信,那些差别的限造能够被敏捷征服,至少有两个次要原因。起首,我们利用的是现成的Java东西,那些东西没有颠末优化,无法在资本(内存/CPU)有限的情况中运行,并且可能有很大的操做难度。 第二,智妙手机的硬件和操做系统的开展将使处置更大的安卓利用法式成为可能(例如,在安卓4上,默认的堆大小是以前版本的两倍)。
我们目前正在研究其他用例。特殊是,我们正在施行一种在智妙手机上设置和运行的行为歹意软件检测办法。那种办法包罗对字节码停止检测,将API办法挪用重定向到负责检测歹意行为的存根上。
第七章
相关工做
在过往的四年里,关于Android协议栈及其利用的研究急剧增加。 那能够阐明为,安卓仓库是时髦的、开源的,那便于对系统停止阐发和修改,并且有数以百万计的利用法式可供阐发。
本章的其余部门组织如下。 第7.1节描述了与Dalvik字节码解析和类型化有关的研究。 第7.2节重点介绍了从Android系统中提取权限图的替代手艺。 第7.3节总结了用于阐发组件间和利用间通信的手艺,以及在安卓利用中发现泄露的手艺。最初,第7.4节描述了与间接在设备上对Android利用法式停止仪器化有关的研究。
7.1 Dalvik的当地类型化
在理论中,Android利用法式的Java源代码或Java字节码是不成用的,只要Dalvik字节码才是。 Java语言呈现于1995年,从那时起,已经开发了阐发Java源代码和字节码的东西。 那就是为什么人们对将Dalvik字节码转换回Java字节码的东西感兴致的原因,如许现有的东西就能够用来阐发Android利用法式。 在第7.1.1节中,我们讨论了将Dalvik字节码转换成Java字节码的东西。
在第7.1.1节中,我们讨论了将Dalvik字节码转换为Java字节码的东西,在第7.1.2节中,我们讨论了利用中间表达法反汇编和/或组拆Dalvik字节码的东西。
7.1.1 Dalvik到Java字节码的转换器
Ded [47] 和Dare [91] 是Dalvik字节码到Java字节码的转换器。一旦生成了Java字节码,Soot就被用来优化代码。Dex2jar [99]也从Dalvik字节码生成Java字节码,但没有利用任何外部东西来优化生成的Java字节码。Undx[115]也是一个Dalvik到Java字节码的转换器,但似乎已经无法利用。
另一方面,我们的办法不是间接生成Java字节码,而是Jimple代码。据我们所知,现有的东西没有间接将Dalvik字节码转换为Jimple代码。从Jimple代码中,因为Jimple代码是Soot的内部代码表达,我们也能够生成Java字节码。用我们的办法阐发一个Android利用法式只需要一个步调(即Dalvik字节码到Jimple),而不是像所有现有的办法那样需要两个步调(即Dalvik字节码到Java字节码和Java字节码到Jimple)。
7.1.2 Dalvik 汇编/反汇编法式
Radare [96], Dedexer [95], Smali [62] 是Dalvik反汇编器。他们利用本身的Dalvik字节码的代表:他们不克不及操纵现有的阐发东西。例如,Dedexer生成的格局接近Jasmin,但包罗Dalvik指令,障碍了Java字节码的生成。 我们的东西利用Soot的内部表达法,它容许现有的东西阐发/转换Dalvik字节码。
Androguard [40] 是一个Dalvik字节码阐发器。它有一个反汇编器和模块来阐发Dalvik字节码。Redexer[104]和AsmDex[90]是Dalvik字节码东西化框架。它们可以在字节码程度上对Android利用法式停止阐发。
那些办法都不克不及停止高级静态阐发,如数据流阐发。另一方面,我们的办法将Dalvik字节码转换为Jimple,即Soot的内部表达。现有的对Jimple代码停止数据流阐发的东西能够操纵我们的东西来阐发Android利用法式。
7.2 权限图的提取
7.2.1 关于Java权限模子
固然Android的权限模子与Java中实现的差别,但下面的研究提出了相关的看点,以使我们的奉献得到重视。
Koved等人描述了一个新的静态阐发[74],为Java2法式生成一个权限列表(在Java权限模子中)。Geay等人提出了一种改进的办法[58]。 我们也利用静态阐发,但是在Android的情况下,特殊是在毗连Android API和办事的绑定机造方面,与Java情况差别。正如我们的评估所展现的,绑定器阻遏了现成的Java静态阐发东西来处理对办事的长途挪用。
Pistoia等人[103]提出了一种静态阐发,以识别应该被付与特权的代码部门。那个问题在Android框架中不会呈现,因为代码自己没有特权,而是在进口点停止拜候掌握。那意味着安卓框架的设想者必需重视创建由权限施行点庇护的特殊进口点,但不会影响我们的静态阐发。
基于角色的拜候掌握(RBAC)机造是由Cen- tonze等人[28]利用静态阐发来阐发的。当一个受庇护的操做把持数据时,那个数据不该该间接或间接地被战略中不决义的途径所拜候。 假设不是如许,该操做就被称为位置纷歧致。他们开发的东西能够查抄JavaEE法式的RBAC战略能否是位置一致的,或者能否存在一些破绽。安卓系统定义了庇护操做的每项使命,而那些操做又会操做受庇护的数据。 我们的目标是计算权限差距,那可能会展现出对最小特权原则的违背。安卓系统庇护的操做能否是位置一致的,不在我们的办法范畴之内。
同样与基于角色的拜候掌握有关,Pistoia等人[102]正式成立了RBAC模子,并静态地查抄了基于JavaEE的RBAC系统的一致性。 我们查抄Android利用法式的权限列表能否尊重最小特权原则。那些概念是不异的(安卓的权限能够近似于角色,我们查抄安卓框架的每一个点都需要哪些角色),但目标系统却纷歧样。有趣的是,我们利用类似的办法来处理Binder问题,就像他们处理长途办法挪用问题一样:不是静态阐发Binder/RMI代码来处理办法,而是计算从长途办法的挪用到长途办法自己的映射。但一个次要的区别是,在Android的情状下,系统办事和上下文必需事先被初始化,以模仿准确的系统形态。
7.2.2 关于Android的权限模子
Android的平安模子在灰色文献[49, 118]和官方文档[128]中都有描述。差别类型的问题已经被研究,如社会工程进攻[66],通同进攻[86],隐私泄露[59]和特权晋级进攻[55,36]。比拟之下,我们的办法并没有描述一个特定的弱点,而是描述了一种削减潜在破绽的软件工程办法。
然而,我们并没有像[89, 93, 42, 31, 26]那样为Android描述一个新的平安模子。 例如,Quire[42]在运行时庇护挪用链和恳求的数据来源,以避免某些类型的进攻。在我们的工做中,我们没有修改现有的Android平安模子,我们设想了一种办法来缓解其固有的问题。
此外,差别的做者根据体味摸索了Android模子的利用。例如,Barrera等人[11]提出了一项关于若何利用权限的实证研究。特殊是,他们利用了可视化手艺,如自组织地图,来识别权限的形式,以及权限分组的形式。其他的实证研究包罗Felt的关于权限模子的有效性的研究[54],以及Roesner的关于用户对基于权限的系统的反响的研究[109]。固然我们的办法也包罗体味性的部门,但它也是可操做的,因为我们设想了一种可操做的软件工程办法来征服一般的基于权限的平安模子,特殊是Android的模子。
Enck等人[48]提出了一种办法来检测求助紧急的权限和歹意的权限组。他们设想了一种语言来表达平安专家所表达的规则。在安拆时不成立的规则表白有潜在的平安问题,因而是一个高进攻面。我们的目标是差别的:我们的目标不是识别从专家那里发现的风险,而是识别利用法式的权限标准和平台资本和办事的现实利用之间的差距。与[48]相反,我们的办法是完全主动化的,在那个过程中没有专家参与。
PScout[6]是一个与我们的并行设想的静态阐发。它也利用Soot,但只依靠
CHA,不利用Spark。我们的工做在第4.6.2节中对他们的部门成果停止了比力和验证。
最初,Felt等人[53]与我们同时停止了同样的研究。 他们颁发了第一个版本的开发者资本(如API挪用)和权限之间的地图。 有趣的是,我们摘取了两种完全差别的办法来识别该地图:他们利用测试,而我们利用静态阐发。因而,我们的工做验证了他们的大部门成果,虽然我们发现了一些差别,我们在第4.6.3节详尽讨论了那些差别。但关键的区别是,我们的办法是完全主动化的,而他们的办法需要手动供给测试 "种子"(如输进值)。然而,在存在检测的情状下,假设测试是恰当的,他们的办法会更有效。因而,我们认为那两种办法是互补的,无论是在基于权限的架构的概念层面,仍是在详细的逆向工程和笔录Android的权限方面。
Mustafa等人[88]努力于系统办事的阐发。他们的办法是利用上下文灵敏的后向切片办法,从权限查抄办法起头提取子挪用图。他们的阐发愈加切确,因为他们捕获了权限查抄的前提。然而,他们只考虑了独立的系统办事,没有处置RPC。
另一方面,我们从Android的API进口点起头阐发,并处置办事RPC链接。
7.3 Android利用法式中的数据泄露
据我们所知,我们的东西IccTA是第一个通过代码东西无缝毗连Android组件的办法,以施行基于组件间通信(ICC)的静态污点阐发。通过利用代码东西手艺,上下文的形态和数据(例如,一个企图)在组件之间传输。据我们所知,目前还没有其他现有的静态办法来检测Android隐私泄露,处置ICC问题并在组件之间连结形态。
7.3.1 静态阐发
有几种利用静态阐发来检测隐私泄露的办法。PiOS[44]利用pro-gram slicing和可达性阐发来检测可能的隐私泄露。TAJ[130]利用不异的污点阐发手艺来识别收集利用中的隐私泄露。然而,那些办法引进了大量的假阳性成果。CHEX[84]是一个东西,通过跟踪灵敏源和外部可拜候接口之间的污点来检测Android利用法式中的组件劫持破绽。 然而,它最多只限于1个对象的灵敏度,那在理论中招致了不切确性。 LeakMiner和AndroidLeaks表达有才能处置An- droid生命周期,包罗回调办法,但那两个东西对上下文不灵敏,因而无法切确阐发许多现实情状。FlowDroid[5]引进了一种高度切确的污点阐发办法,具有较低的误报率,但它不克不及识别基于ICC的隐私泄露。IccTA通过对原始利用的代码停止检测,在连结高精度的同时,停止基于ICC的静态污点阐发。
ComDroid[30]和Epicc[92]是两个处理ICC问题的东西,但它们次要存眷ICC的破绽,并没有污损数据。
SCanDroid[56]是一个用于阐发基于ICC的隐私泄露的东西。 它修剪了所有对Android操做系统办法的挪用边,并守旧地假设基对象、参数和返回值继续了参数的污点。那种办法比我们的东西切确得多,因为我们在掌握途径图顶用我们的假主办法来模仿所有的Android操做系统办法(除了当地办法)。 另一个东西SEFA[136]也处理了ICC的问题。它施行全系统的数据流阐发,以检测可能的破绽(例如,被动的内容泄露)。SCanDroid和SEFA都利用一种婚配的办法来阐发组件间的泄露。 SCanDroid将所有向利用法式导进数据的办法定义为inow办法,将所有从利用法式导出数据的办法定义为outow办法。然后,它婚配inow和outow办法来毗连两个组件。 SEFA将ICC办法定义为桥梁汇,以区别于灵敏汇。它利用桥汇与其他组件婚配,从而毗连两个组件。正如我们之前提到的,与我们的东西化办法比拟,婚配办法有一些缺点。因而,即便我们不克不及在DroidBench上评估SCanDroid和SEFA,也来IccTA在设想上愈加切确。
AsDroid[69]和AppIntent[140]是另两个利用静态阐发来检测Android利用中权限泄露的东西。它们都试图阐发隐私泄露的企图。阐发泄露的企图不在我们的办法范畴之内。然而,我们认为有需要区分隐私泄露能否是有意的。我们将此做为我们进一步的工做。
7.3.2 动态阐发
另一方面,动态污点阐发手艺在运行时跟踪灵敏数据。 Taint- Droid[45]是最复杂的动态污点跟踪系统之一。它跟踪第三方利用法式的私家数据。CopperDroid[105]是另一个动态测试东西,它看察Android组件和Linux系统之间的彼此感化,以重建高程度的行为,并利用一些特殊的刺激手艺来磨练利用法式,以避免歹意活动。其他几个系统,包罗AppFence[67]、Aurasium[138]、AppGuard[8]和BetterPermission[13]试图通过动态监测被测试的利用法式来缓解隐私泄露问题。
然而,那些动态办法能够被特殊设想的办法所哄骗,以躲避平安跟踪[114]。 因而,动态跟踪办法可能会错过一些数据泄露,并产生一个不敷的近似值。另一方面,静态阐发办法可能会产生一个过度的近似值,因为所有利用法式的代码都被阐发了,即便是在运行时永久不会施行的代码。在阐发Android利用法式的数据泄露时,那两种办法是互补的。
7.4 Bytecode的In Vivo Instrumentation
7.4.1 监控利用法式
因为 "挪动 "歹意软件的爆炸性增长和挪动操做系统的日益复杂,在运行时监控智妙手机利用法式是比来呈现的一个设法。
Bose等人[23]旨在根据运行时的行为来检测歹意软件。为此,他们在Symbian OS模仿器中添加了挂钩,以跟踪操做系统和API挪用。 换句话说,歹意软件检测只在模仿器中实现,在体外停止。相反,我们的目标是在活的用户情况中停止歹意软件检测,并表白那在中期内是可行的。
Enck等人[46]提出了一个名为TaintDroid的运行时监控框架,它容许污点跟踪和阐发,以跟踪Android中的隐私泄露。 他们的原型是基于运行Android利用法式的Dalvik虚拟机的一个修改版本。 同样,Costa等人[34]对挪动设备的Java虚拟机(Java ME)停止了扩展,以增加运行时监控功用。相反,我们的可行性研究表白,在未修改的Android系统中实现运行时监控是可能的。
比来,Burgera等人[27]提出了一种基于搜集的操做系统挪用来检测歹意软件的办法。运行时监控能够在差别的颗粒度程度长进行。固然Burgera等人描述的办法是在操做系统挪用层面,但我们的目标是在API挪用层面供给运行时监控,也就是说,更细粒度,更接近挪动利用法式的利用域。
Davis等人[37]提出了一个Android利用重写框架的原型,并论述了它在监控利用和实现内粒度拜候掌握方面的用处。
最初,Shabtai等人根据对各类系统目标的搜集和阐发来检测歹意软件,如CPU利用率、通过Wi-Fi发送的数据包数量等。那是一种检测歹意软件行为的间接办法。 同样,通过监测API挪用,我们间接看察利用法式的行为。本论文中提出的体味成果表白,那现实上是可能的。
7.4.2 告白权限的别离
Shekhar等人[120]提出了一个新的Android告白系统,容许利用法式和它的告白模块在差别的历程中运行,因而有差别的权限设置。 那个新系统必需在开发阶段手动插进到利用法式中,因为没有供给主动化的利用法式修改。
Pearce等人[101]提出了一个告白框架的案例,该框架将被整合到Android平台内。每个开发者都可以利用定造的API,该API将在Android设备上可用。那种办法需要对安卓框架停止修改,而且一个特定的用户拥有一个嵌进该告白系统的安卓版本的设备。
7.4.3 答应政策
Erlingsson等人和Evans等人[50, 51, 52]是第一个把持字节码来间接在Java法式中编织平安战略的人。 他们的Inline Reference Monitor(IRM)手艺容许(1)将法式开发与战略定义完全分隔;(2)拥有独立于法式运行的Java虚拟机的战略机造。我们还将平安战略间接编织在Android利用法式中,从而获得强大的Android利用法式,其平安战略独立于其所运行的Android系统。
与我们的工做最接近的是两个Dalvik字节码操做系统: I-Arm Droid[38]和Mr. Hide[72]。次要区别在于我们的办法是在体内运行,而他们的办法不是。
AppGuard[7, 9]也实现了体内字节码把持。然而,该办法是基于dexlib一个字节码操做库,它不供给像Jimple与Soot那样的笼统代表。 因而,用他们的办法对字节码停止更高级的推理(例如在图上)是很困难的。
将感兴致的办法重定向到一个监视器是IRM的根底。Von Styp-Rekowsky等人通过在运行时修改Dalvik函数指针的等价物提出了一种新的办法[125]。那种办法削减了开销,能够很随便地被我们的内层权限系统所摘用。
Xu等人提出了Aurasium [137],那是另一个权限治理系统。它确其实C语言库的程度上运行,并将感兴致的初级函数重定向到监控器。在那个初级此外操做使得注进假值和区分一般和Java级平安相关操做变得很困难。
Reddy等人[104]声称,通过创建 "以利用法式为中心的权限",即表达利用法式能够做什么的权限,而不是表达利用法式能够利用什么资本的当前Android权限,Android平台的平安性将得到改进。他们编写了一个库,容许所谓的 "以利用为中心的权限 "被治理。此外、
他们起头开发一个喊做 "redexer "的东西,其目标是主动重写现有的利用法式,以使它们利用那些新的权限。
Nauman等人[89]扩展了Android基于战略的平安模子,使其可以在运行时施行约束。他们创建的东西,称为Apex,容许用户表达对利用法式利用任何权限的限造: 例如,通过Apex能够向任何给定的利用法式授予SEND_SMS权限,同时确保该利用法式天天发送的短信不克不及超越用户指定的数量。 用户也有可能改动主意,完全阻遏利用法式发送短信息。那是对安卓系统的一个重要改进,因为它容许用户指定一个更细化的政策,而不是必需在授予一个利用法式在安拆时可能要求的所有权限或不安拆该利用法式之间做出抉择。 然而,那种办法需要在安卓框架的深处停止修改,因而需要得到谷歌的撑持,并整合到安卓的将来版本中,才气被普遍利用。
凡是情状下,一个权限能够庇护对原始资本的拜候,例如从相机拍摄的原始图片。Jana等人[71]提出的办法,通过在原始数据抵达利用法式之前对其停止过滤,能够有一个愈加细化的政策。假设你安拆了一个利用法式,从相机拍摄的照片中识他人脸。在传统的基于权限的系统中,利用法式将被付与CAMERA的权限。 用他们的办法,利用法式能够只被付与一个新的FACE_RECOGNITION的细粒度权限。然后,来自相机的原始数据将被窜改,只保留关于人脸的信息,而不是关于拍摄照片的情况。因为利用法式只要关于人脸的信息,它不克不及再从头识别隐私灵敏的情况信息(例如,墙上的街道名称,黑板上的文字)。
本文所描述的工做是并世无双的,该论文是一个重要的奉献。我们改进了以下范畴的手艺程度:(1)用Dexpler阐发Dalvik字节码,那是一个通过Jimple表达法对Dalvik字节码停止完全类型化的东西;(2)基于权限的阐发,用一个通用办法来阐发基于权限的框架和提取权限,以及一个通用办法来阐发基于权限的利用法式和ind权限差距。(4) 用IccTA对安卓系统停止数据泄露阐发;(5) 通过两个用例对安卓利用停止动态阐发。
第八章
结论和将来工做
本章的组织构造如下。 第8.1节概述了本博士论文的奉献。第8.2节描述了将来工做的潜在标的目的。
8.1 结论
在那项工做中,我们从平安的角度阐发了Android基于权限的系统及其利用。与传统的Java利用比拟,Android利用具有差别的构造和编码。 需要新的东西和笼统手艺来准确阐发Android利用法式。
我们介绍了Dexpler,一个将Dalvik字节码转换为Jimple的东西,Jimple是Soot的内部表达。Dexpler已经在超越2.5万个包罗1.35亿个办法的利用法式长进行了评估,发现99.99%的办法都是准确的类型。
第二,我们阐发了安卓系统自己,以提取API办法和权限之间的映射。我们的东西对安卓系统的特征停止建模,如系统办事通信和办事身份反转。它提取了一个权限矩阵,此中有4962个与权限相关的进口点。我们阐发了开发者是若何为Android利用法式编写权限列表的。我们提出了一个东西来静态阐发安卓利用,以查抄非需要的权限。我们发现,超越18%的利用法式至少声了然一个无用的权限。
第三,我们阐发了安卓利用,以发现数据泄露。我们提出了IccTA,一个在安卓利用的组件之间和安卓利用之间识别数据泄露的东西。IccTA超越了现有的对安卓利用停止污点阐发的东西,到达了95%的切确度和82%的召回率。
最初,我们研究了若何将动态阐发与静态阐发的成果连系起来利用。 我们提出了一个东西链,用于主动转换体内的Android利用法式,即间接在运行Android的设备长进行转换。我们在两个原型中利用该东西链。第一个原型容许用户抉择细化的权限战略,并依靠于通过静态阐发Android系统获得的权限映射。 第二个原型从利用法式中删除告白。
8.2 将来的工做和开放的研究问题
本节描述了潜在的将来研究标的目的。
8.2.1 框架阐发
提取一个答应查抄的通用模子
值得摸索的是,若何将权限施行做为一个跨范畴的问题来表达,以便根据平安标准,在利用法式或框架层面上主动添加或删除权限施行点。如许的工做将答复以下问题: 权限查抄能否老是以同样的体例插进到代码中?有可能绕过权限查抄吗?若何验证一个基于权限的系统?
进步精度
我们如今正在研究一种模块化的办法,那种办法可以协同阐发当地代码和字节代码,并连系两者的权限信息。 成果的精度受限于挪用图构造的精度和处置的Android组件的类型。此外,进步精度也能够进步该办法的可扩展性,因为更切确的挪用图可能包罗更少的边,因而需要更少的计算来提取权限信息。
从头审阅实证评估
此外, 因为我们的办法是通用的, 我们能够将其利用于其他基于权限的系统, 如FirefoxOS或谷歌阅读器.
8.2.2 安卓利用静态阐发的将来
我们还能实现利用阐发的主动化吗?
我们只利用静态阐发来阐发Android利用法式。然而,有一些办法能够障碍静态阐发,如代码稠浊、密集利用reection来隐躲办法挪用、加密字节码、加密字符串、在虚拟机中施行代码等。在我们的阐发中,我们会错过那类利用法式的泄露。退一步讲,我们会发现那些手艺只是减缓了静态阐发Android利用法式的过程。它们迫使我们分两步停止阐发: (1) 运行利用法式,找出办法值和字符串值;(2) 用第一步提取的信息再次运行静态阐发。第一步能在多大水平上实现主动化还有待看察。读者可能认为,只要歹意软件的利用法式才会利用那种手艺来隐躲他们的歹意代码,所以在一组利用法式中检测歹意软件是很随便的。然而,一些良性利用法式的做者其实不期看让他们的代码变得易懂,也会利用稠浊手艺。跟着稠浊手艺变得越来越普及,仅靠静态阐发是不敷的。必需开发新的东西来动态地阐发利用法式,与静态阐发利用法式相连系。
新的稠浊手艺
一个好的起头是看一下所有阐发Android利用的东西的局限性。例如,假设用于创建Intent对象的字符串是通过复杂的操做(如串联,通过多种办法ow)构建的,那么计算组件之间的链接的东西可能会失败。假设利用法式中经常利用深度拜候途径,静态阐发Android利用法式的东西可能无法一般工做。 最初,那些东西在字节码层面上工做,其实不阐发当地代码:将字节码转换为当地代码会使它们失往感化。就像哈希函数随便计算,但反转成本很高一样,能否有一些限造对进攻者来说很随便操纵,但阐发起来十分困难和高贵?
泄露分类
我们对Android利用法式中的泄露的办法有以下限造:它没有给出关于它发现的泄露的信息。事实上,它不克不及告诉你一个泄露是利用法式的特征(例如,利用法式应该把联络人名单发送到你本身的长途办事器)仍是歹意的(例如,一个歹意软件把你的联络人名单发送到互联网上的某个长途办事器)。处理那个问题的办法之一是阐发利用法式的文本描述,并将其与我们的办法所给出的泄露相婚配。如许一来,安卓利用只要在泄密事务与描述不婚配时才会被进攻。比来,人们对发掘利用法式描述的办法感兴致[60, 97, 63]。
平安利用法式的市场
开发者能够为每个利用法式供给一个预期行为的清单,而不是发掘利用法式的描述。那个列表能够在运行利用法式时被动态查抄(假设其行为纷歧致,利用法式将被停行)或在阐发代码时被静态查抄。此外,为了简化阐发检测办法,应该限造或制止利用中的类加载和当地代码。现有的办法是从官方文件或法式中的文本信息中提取标准[127, 68, 98]。此外,能够开发主动手艺,而不是要求开发者写出标准的清单。
针对市场利用的可扩展的阐发
我们的办法在小规模的利用法式上是可行的。 一个开放的研究问题是找出一个可扩展的办法来阐发成千上万的利用市场。 一个可能的标的目的是将市场阐发视为一个两步的过程。 在第一步中,每个利用法式都将被零丁阐发,并计算出利用法式的笼统。笼统将取决于人们想要处理的问题的品种(例如,利用间的泄露)。在第二步中,笼统被连系起来以处理那个问题。以下的挑战必需得到处理: 若何切确地毗连利用法式?当通信是双向的,若何处置笼统中的数据流?在那个问题上,Android的工做很少[20]。
在那篇论文中,我们(1)提出了Dexpler,它容许对Android利用停止阐发和东西化,(2)阐发了Android框架以提取权限图,我们操纵权限图来识别Android利用中的权限缺口,(3)开发了IccTA来检测Android利用中的泄露,(4)表白静态阐发的成果能够对动态阐发有用。简而言之,在那篇论文中,我们为阐发安卓框架、安卓利用以及更普遍的基于权限的框架或利用奠基了根底。那些阐发是理解基于权限的系统及其利用的第一步。它们为创建平安的基于权限的系统展平了道路,在那个系统中,平安问题将被降到更低。