英语原文共 10 页
Android程序的静态分析
摘要:
内容:Android是一种基于Java的编程语言 ,是一种用于嵌入式和移动设备的操作系统,其上层是用Android语言本身编写的。作为一种语言,它具有基于事件的扩展库和来自声明性XML布局文件的图形视图的动态扩展。为了正确性和精确性,Android程序的静态分析器必须考虑这些特性。
目的:扩展基于抽象解释的Julia静态分析器,对Android程序进行正式正确的分析。这篇文章深入地描述了这种扩展,描述了我们所面临的困难以及我们所取得的结果。
方法:我们扩展了Julia分析器的类分析,它是许多其他分析的核心,通过考虑一些Android关键特定功能,例如程序的许多入口点的潜在存在以及从XML到反射的图形视图的扩展。 我们还显着提高了Android程序的归零度分析的精确度。
结果:我们和Julia一起分析了大部分谷歌和一些更大的开源程序开发的Android应用程序。我们已经应用了大量的静态分析,包括classcast、死代码、空值和终止分析。Julia自动地在谷歌示例和开源应用程序中发现了错误、缺陷和低效。
结论:Julia是Android程序的第一个声音静态分析器,基于形式化的抽象解释等基础。我们的结果显示,它可以分析真正的第三方Android应用程序,不需要任何用户的代码注释,在标准硬件上最多7分钟就可以得到正式正确的结果;因此,它已准备好首次工业化使用。
1.介绍
Android是移动和嵌入式设备(如手机、平板电脑和电视)操作系统市场的主要参与者。它是为这类设备开发的操作系统,这些设备的上层是用一种编程语言编写的,也就是Android。作为一种语言,Android是带有移动和扩展库的Java
交互式应用程序,因此是基于事件驱动的体系结构。任何Java编译器都可以编译Android应用程序,但是生成的Java字节码必须转换成最终的、经过非常优化的Dalvik字节码才能在设备上运行。
Android应用程序的静态分析非常重要,因为质里和可靠性是Android市场成功的关键。有bug的应用程序会得到负面反馈,并立即被潜在用户丢弃。因此,Android程序员希望确保他们的程序是无bug的,例如,他们不会抛出任何意外异常,也不会挂起设备。但Android应用程序也越来越多地部署在关键的环境中,甚至是在安全性和可靠性最为重要的军事场景中。基于这些原因,像Klocwork这样的行业参与者已经将其静态分析工具从Java扩展到Android,从而获得了我们所知道的唯一针对 Android的静态分析。从他们的网页上我们可以推断,它的力量是相对有限的。我们无法获得免费的评估许可证。
像Klocwork这样的工具是基于语法检查的。这意味着通过查找通常包含错误的代码的典型语法模式可以识别错误。语法检查的使用可以实现非常快速和实用的分析。但是,当有错误的代码不遵循分析器所知道的预定义模式时,它无法识别错误。对于像Julia这样的语义工具来说,情况正好相反,基于形式化方法的人工智能还不能证明程序片段不包含错误的地方,就会发现错误。第二个场景要复杂得多,计算成本也高得多,但它为结果的可靠性提供了保证:如果没有发现(某个类的)潜在错误,那么代码中就没有该类的错误。换句话说,语法工具是快速的但不健全的。这两种方法都发出错误警报,即潜在的错误实际上不是真正的错误。精度(即bug的数量,关于警告的数量)是一个关键问题,因为错误警报的数量不应该压倒该工具的用户。大多数静态分析工具的开发人员都承认这一点。例如,我们可以引用Coverity的web页面:“通过提供行业最准确的分析解决方案和最低的误报率,您可以专注于真实的和相关的缺陷,而不是浪费开发周期。” 因此,静态分析器的开发人员的大部分工作是减少误报的数量。这对于声音分析器来说要困难得多,因为他们不能仅仅丢弃警告而仍然保持声音。无论如何,像Klocwork这样的公司出现在这个市场上,表明业界认识到了Android代码静态分析的重要性。
一种更科学的方法是基于SCanDroid工具,目前仅限于Android应用程序的安全验证。它对Android应用程序进行信息流分析,通过意图跟踪组件间的通信,并通过应用程序联盟非法获取安全特权。它的基础是基于约束的代码分析,并且有一个可靠的保证,至少对于一种受限的字节码来说是这样。Klocwork目 前没有对Android应用程序执行任何信息流分析。
Julia是一个基于抽象解释的Java字节码静态分析器,它自动确保所分析的应用程序不包含大量编程错误。它应用了非平凡的全程序、过程间和语义静态分析,包括classcast、 死代码、空值和终止分析。与抽象解释中的典型情况一样,它具有正确性保证:如果应用程序包含分析器所考虑的那种错误,则Julia将报告它。这使得分析结果更有意义。虽然Java和Android是同一种语言,有着不同的库集,但是Julia在Android上的应用并不直接,我们需要解决很多问题,Julia才能正确准确的分析Android程序。许多都与不同的库集有关,其他的则与使用XML构建应用程序的一部分有关。在本文中,我们将这些问题和我们的解决方案一起呈现出来,并展示所得到的系统能够以很高的精度分析重要的Android程序,并发现第三方代码中的错误。本文没有详细描述Julia提供的静态分析(已经在其他地方发表过),只描述了分析器及其分析对Android的适应性。
必须指出,我们的Julia分析器在反射、Java类加载机制的重新定义和多线程的存在下是不可靠的。这并不意味着不能分析使用这些特性的程序,而是说结果可能是不正确的。实际上,我们工作的一个主要成果是教会Julia在Android中的XML布局扩展过程中反射的具体使用,这样分析的结果在这种情况下仍然是可靠的(但对于反射的其他用途则不是)。
我们的分析器假设了一个封闭的世界假设,例如,它假设在入口点,变量可能被绑定到与它们声明的类型兼容的每个类,可能以任何可能的方式共享或持有null。同样的假设不适用于库,库可以被扩展,其行为可以通过子类化进行修改。因此,我们的库不是一个模块化的分析,因为我们只分析完整的(封闭的)Android应用程序。
有许多静态分析器能够分析Java源代码并发现bug或低效。大多数都是基于在句法分析或使用定理证明进行一些简化(通常是不合理的)假设。由于Android语言是Java,只有库会发生变化,所以原则上也可以将这些分析器应用到Android源代码中。然而,正如我们在下一节中所展示的,有一些新的语言特性,如XML inflation, 这些工具无法理解,它们会影响程序控制流图的相同构造,通常通过称为类分析的类型推断分析来执行由于使用这个库的方式,Android代码中有许多新的bug,这不是典型的Java代码。因此,静态分析器要么假设这些特性不存在,这些bug不存在(不可靠),要么必须以合理的方式处理它们。我们认为在本文中强调的解决方案也可以应用于这些静态分析仪,因为它们并不局限于我们选择的特定静态分析仪。
本文的其余部分组织如下。第二节论证了Android程序静态分析的难点。第三部分介绍了与本文相关的Android概念。第4节展示了我们在Android代码上执行的更相关的静态分析。第5-7节描述了我们如何改进Julia在Android上的工作。特别地,第5节讨论了在存在XML扩展的情况下,通过类分析构建声音控制流图。第8节展示了来自标准谷歌发行版和大型开源项目的许多重要Android程序的实验结果;这表明Julia在这些程序中发现了一些实际的错误。第9节总结全文。
- Android静态分析的挑战
对Android程序的分析是很重要的,因为我们必须考虑Android的一些特定特性,无论是分析的正确性还是精确性。
首先,Julia分析Java字节码,而Android应用程序是在Dalvik字节码中提供的。有从Dalvik到Java字节码的翻译程序。但是,在Eclipse IDE中开发的Android应用程序始终可以以jar格式导出,即以Java字节码导出。Eclipse是目前Android的标准开发环境,因此我们更喜欢从Eclipse生成jar文件。
另一个问题是Julia从程序的主方法开始分析程序,而Android程序从许多事件处理程序开始分析程序。对于一些基于事件的Java程序,比如使用actionPerformed事件处理程序的Swing程序,这也是一个问题。对于Android代码来说, 这是一个更大的问题, 因为整个程序都是通过事件处理程序工作的,而这些事件处理程序通常是通过反射调用的,因此对于不理解反射的静态分析器来说,它们实际上可能看起来像是死代码。因此,我们必须修改Julia,以便从所有这些处理程序开始分析,将它们视为潜在的并发条目点。必须说明的是,Android事件处理程序是由单个线程执行的,因此我们不必考虑多线程应用程序分析的困难问题。入口点从最坏情况的假设进行分析,例如,声明它们的参数和接收器可以属于与它们的静态类型兼容的任何类,或者始终为空或保留重叠的数据结构。
一个更复杂的问题是Android使用的通过XML文件的用户界面的声明性规范。这意味着代码不能完全采用字节码格式,而是在运行时使用Java反射将XML布局文件扩展为实际的字节码。不要认为布局代码只包含与静态分析无关的图形方面,从而低估了这个问题。相反,在Android程序中,XML可扩展类(如视图、菜单和首选项)包含应用程序的大部分甚至全部代码,包括其业务逻辑。此外,XML扩展代码和显式应用程序代码之间的链接引入了强制类型转换和潜在的空指针异常。因此,如果希望XML扩展正确,分析程序必须详细考虑它。
最后,真正的挑战是库的大小一般来说,Android程序同时使用受限的java。和新的android。/层次结构。它们的类必须与程序-起分析,这很容易导致对1000个或更多方法的分析。
3.安卓系统基础知识
Android应用程序是用Java编写的,并在它们自己的虚拟机中的进程中运行。它们没有单一的入口点,而是可以按需使用其他Android应用程序的某些部分,并且可以通过直接或通过操作系统调用事件处理程序来要求它们的服务。特别是,Android应用程序包含Android应用程序包含活动(通过可视界面与用户交互的代码)、服务(不与用户交互的后台操作)、内容提供程序(数据容器,如数据库)和广播接收器(对广播消息作出响应的对象)。事件处理程序没有特定的顺序安排,只有一些明显的例外,比如活动的生命周期。
一个XML清单文件注册应用程序的组件。其他XML文件描述活动的可视化布局。活动通过Android库提供的扩展器将布局文件扩展为可视对象(视图的层次结构)。这意味着库或用户定义的视图不是由新语句显式创建的,而是通过反射扩展的。findViewByld等库方法访问扩展的视图。以Android2.2的谷歌发行版为例,考虑图1中的活动。onCreate事件处理程序在活动第一次创建时被调用,在它的构造函数被Android系统隐式调用之后。setContentView库方法调用布局扩展器;它的整数参数惟一地标识了如图2所示的XML布局文件。从图2文件的第3行可以看出,图1第9行标识为lunar的视图属于用户定义的视图类com.example android.lunarland.lunaview。因此,图1中第9行中的强制转换是正确的。常里出来。lunar layout R.id。在编译时,分别从XML布局文件名和它们所包含的视图标识符自动生成lunar。用户可以在代码中多次、处处调用setContentView,他可以将任何整数表达式的值传递给它并传递给findViewByld,尽管通常的方法是传递编译器生成的常量。这种对象的声明式构造也适用于首选项(图形应用程序选项)和菜单。
图1.Android文件LunarLander.Java的一部分源代码
图2.XML布局文件lunar_layout.xml
4.我们应用的静态分析的集合
我们在这里描述了我们让Julia应用于Android程序的主要分析。相比最后两个,前六个相对简单。除了纯粹语法上的方法重新定义检查之外,它们都利用了在提取应用程序期间已经执行的类分析,该类分析计算程序的控制流图的过近似值。因此,他们利用程序的语义、全程序和程序间的信息。
这些分析并不新鲜。它们是非常著名的面向对象代码静态分析,已经由诸如Klocwork、Coverity和FindBugs等工具执行,请参见它们各自的主页。新奇之处在于它们是在Android代码的声音工具中实现的。
平等的检查。Java程序员可以用指针标识检查 == 和编程检查 equals 来比较对象。在大多数情况下,后者是首选。但是,当程序员知道标识相等对应于编程相等时,== 用于有效地比较内部对象。因此,对同一类型使用这两种检查是潜在bug的症状。此外,在数组上使用 equals 或 == 很可能是一个错误。为了确定 == 和 equals 被应用,Julia使用了《 Object-oriented type inference》中定义的0-CFA类分析的改进。
Classcast检查。不正确的类转换是典型的编程错误。Java中引入泛型类型减少了强制类型转换的使用,但程序员有时仍然需要它们。不幸的是,Android实际上引入了需要强制类型转换的新情况,例如图1中的第9行和第1行。Julia使用它的类分析来证明类型转换是正确的。我们必须考虑Android库的特性,以保持类分析的精确性,从而证明这些类型转换是正确的。
静态更新检查。从构造函数或实例方法内部修改静态字段是合法的,但这是可能的错误或至少是糟糕的编程风格
资料编号:[5364]
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。