计算机应用   2016, Vol. 36 Issue (10): 2811-2815  DOI: 10.11772/j.issn.1001-9081.2016.10.2811
0

引用本文 

汤杨, 曾凡平, 王健康, 黄心依. 基于静态分析的Android GUI遍历方法[J]. 计算机应用, 2016, 36(10): 2811-2815.DOI: 10.11772/j.issn.1001-9081.2016.10.2811.
TANG Yang, ZENG Fanping, WANG Jiankang, HUANG Xinyi. Android GUI traversal method based on static analysis[J]. JOURNAL OF COMPUTER APPLICATIONS, 2016, 36(10): 2811-2815. DOI: 10.11772/j.issn.1001-9081.2016.10.2811.

基金项目

安徽省自然科学基金资助项目(11040606M131)

通信作者

汤杨(1991—),男,安徽肥西人,硕士研究生,主要研究方向:Android安全、软件测试.E-mail:tangyang@mail.ustc.edu.cn

作者简介

曾凡平(1967—),男,江西南康人,副教授,博士,主要研究方向:软件测试、信息安全;
王健康(1991—),男,安徽滁州人,硕士研究生,主要研究方向:Android安全;
黄心依(1993—),女,安徽滁州人,硕士研究生,主要研究方向:Android安全

文章历史

收稿日期:2016-04-18
修回日期:2016-06-07
基于静态分析的Android GUI遍历方法
汤杨1, 曾凡平1,2,3, 王健康1, 黄心依1    
1. 中国科学技术大学 计算机科学与技术学院, 合肥 230026 ;
2. 计算机科学国家重点实验室(中国科学院软件研究所), 北京 100190 ;
3. 安徽省计算与通讯软件重点实验室, 合肥 230026
摘要: 针对传统软件安全测试方法(例如:符号执行、模糊测试、污点分析等)无法获得较高的Android程序图形用户界面(GUI)覆盖率的问题,提出动态和静态相结合的Android程序测试方法。该方法在静态分析Android应用程序数据流的基础之上,构建程序活动转换图和函数调用图,解析程序GUI元素,进而编写测试脚本动态遍历应用程序GUI元素。将该方法应用于订票日历、WiFi万能钥匙和360天气应用的实际测试,结果表明:Activity的平均覆盖率达到76%,明显高于人工测试的平均值30.08%和基于控件树遍历的42.05%~61.29%,该方法能够有效遍历Android应用程序GUI元素
关键词: 静态分析    动态测试    事件模拟    活动调用图    函数调用图    图形用户界面遍历    
Android GUI traversal method based on static analysis
TANG Yang1, ZENG Fanping1,2,3, WANG Jiankang1, HUANG Xinyi1     
1. School of Computer Science and Technology, University of Science and Technology of China, Hefei Anhui 230026, China ;
2. State Key Laboratory of Computer Science, Institute of Software, Chinese Academy of Sciences, Beijing 100190, China ;
3. Anhui Province Key Laboratory of Software in Computing and Communication, Hefei Anhui 230026, China
Abstract: Traditional security testing methods (such as symbolic execution, fuzz testing, and taint analysis) cannot obtain high coverage of Graph User Interface (GUI) for Android programs. To solve this problem, an Android program testing method combining both static and dynamic analysis was proposed. Based on the static analysis of data flow of Android applications, activity translation graph and function call graph were constructed, and the GUI elements of the program were parsed, then scripts were written to dynamically traverse GUI elements of applications. This method was applied to the testing of the applications including Booking Calendar, Wifi Master Key and 360 Weather, the result showed that the average coverage of activity reached 76%, which was significantly higher than that of manual testing (30.08%) as well as GUI tree traversal (42.05%-61.29%). Experimental result demonstrate that the method can effectively traverse GUI of Android applications
Key words: static analysis    dynamic test    event simulation    activity translation graph    function call graph    Graph User Interface (GUI) traversal    
0 引言

随着移动互联网的普及,智能手机已经成为了访问互联网应用的一种主要终端设备,Android作为智能手机的主流操作系统,截至2015年第二季度其市场占有率高达82.8%[1];同时,基于Android系统的应用软件也在呈指数增长。然而由于Android系统的开源特性,Android碎片化问题严重,市场上主流的Android手机出货商都有各自定制的Android系统,导致应用程序很难去适配不同版本的系统,程序的通用性无法保证。相对于传统的软件,移动应用程序开发周期短、迭代更快,开发者容易忽略测试的重要性。这些都难以保证Android程序的正确性、健壮性和安全性。

当前针对Android应用程序的动态测试方法主要以事件为驱动,遍历程序图形用户界面Graph User Interface (GUI)元素来发现程序的漏洞或者隐私泄露等敏感行为,验证程序的功能或者正确性、安全性。例如,数据驱动架构通过虚拟测试引擎解析事件数据库中数据表作为输入触发执行[2],或者将测试程序当成Android应用根据测试任务的不同利用Android API(Application Programming Interface)生成不同测试用例[3],或者利用Android测试工具进行事件模拟结合软件安全分析的方法遍历应用程序[4-6]。这些方法需要模拟用户事件驱动程序运行。文献[1-2]中将用户事件保存在数据库中利用事件流驱动,针对漏洞或者冲突测试,不足在于仅关注测试用例生成,忽略了GUI状态变化对程序的影响。文献[4-6]中针对事件模拟,主要有基于Monkey随机事件遍历和基于instrumentation框架非随机事件遍历。随机事件流对应用程序GUI覆盖率相对较低,测试结果难以控制。相对而言,通过测试脚本发送特定事件针对性较强,但是由于应用程序复杂,GUI元素的属性和类型繁多,目前的覆盖测试覆盖率不高,无法满足实际测试需求。

针对现有方法的不足,本文提出基于动态和静态结合的Android动态测试方法。首先,利用静态分析工具建立应用程序的活动转换图(Activity Translate Graph,ATG)和函数调用图(Function Call Graph,FCG);其次,通过解析应用程序中Activity页面元素布局,利用Google测试库中的测试工具模拟程序UI(User Interface)事件;最后,编写测试脚本遍历程序活动转换图和函数调用图,动态执行应用程序遍历程序的GUI。具体的工作流程如图 1所示。通过对被测试应用程序apk文件进行预处理(反编译),获取程序注册Activity和UI元素信息;根据smali中间代码构建活动调用图。最后利用数据流分析构建程序函数调用图。在完成静态预处理之后,测试脚本将程序安装到模拟器中动态执行,模拟相关的按键事件和用户行为向程序发送模拟用户交互事件。通过遍历活动调用图和函数调用图交叉结合的方式,遍历应用程序GUI控件。

图 1 基于UI触发的动态测试流程
1 相关工作

Android市场的广阔前景吸引了大量的开发者和研究人员,在Android应用程序的静态分析和动态测试方面目前已取得了一定成果,已提出了许多静态分析工具和动态分析方法。

1.1 Android应用程序静态分析

静态分析是无需执行程序代码,综合采用词法分析、语法分析、控制流分析等技术手段对程序代码进行静态扫描,来验证代码是否满足规范性、安全性、可靠性等指标的一种代码分析技术。静态程序分析是常用的验证程序正确性、分析程序中错误代码的方法。

传统的静态分析可用于检测Android 应用程序中的恶意行为和隐私泄露。通过反编译应用程序包得到Dalvik字节码,结合相关分析工具进行静态分析,查找Android应用程序中的内部组件间通信数据泄露[7-9]。这些技术通常是基于程序的控制流图或数据流图,但是现代软件开发规模越来越大,应用程序中的控制流和数据流相当复杂,增加了静态分析的复杂性,并且静态分析由于没有实际的运行场景会带来很多误报和漏报。

1.2 Android应用程序界面解析

Android应用GUI界面是在布局文件中实现的,GUI元素可以通过静态XML格式文件声明,或者在运行时实例化布局元素。Android系统提供了简易的XML词汇表对应视图类和其子类,诸如widgets和layouts,可以创建View和ViewGroup对象子类控件,并操作它们的属性。

Android应用程序是事件驱动型程序,需要相应的用户事件或者系统事件来动态运行程序。部分研究根据手机屏幕中的像素点发送随机事件流,无需解析程序GUI界面,只需要获取屏幕当前像素信息,发送随机事件流。这种方法通常用来对程序进行压力测试以发现程序中的未知错误。但是利用随机事件流驱动程序无法预测运行结果,准确度和测试覆盖率无法保证。目前,大多数动态安全测试都采用可编程测试用例方式[4-6],通过反编译程序apk安装包,提取manifest文件获得程序Activity和GUI元素,构建相关GUI控件树。在程序运行时动态分析应用界面,生成基于GUI元素的生成树,从树的根节点遍历GUI元素从而驱动程序运行。

1.3 Android应用程序动态测试

由于Android程序越来越复杂,迭代周期越来越短,为保证程序的健壮性和安全性,移动应用测试得到越来越多的重视。在最近几年的工业界和学术界实践中,移动应用测试主要关注框架的定义和支持工具,其他工作则强调功能和非功能的测试,如性能、稳定性和安全性等。

Amalfitano等[4]提出基于GUI爬虫的Android移动应用检测技术,利用爬虫技术自动建立应用的GUI模型从而获得可以被自动执行的测试用例。Hu等[6]提出旨在寻找GUI 漏洞的自动化测试方法,利用随机事件流驱动应用程序的执行,分析程序产生的日志文件,将它与过去的日志文件作比较来发现漏洞。Jensen等[10]提出到达应用程序源码中指定目标点的事件序列,首先通过符号执行建立单个事件处理器摘要,然后建立UI遍历模型生成从程序入口到达指定事件的序列。赵耀宗等[11]以GUI Ripping技术为基础,建立GUI控件树,通过动态遍历GUI控件树达到遍历程序的效果。

在工业应用中,Android开发平台相继出现众多测试工具及相关的API以及框架。在现有的工具中,Monkey[12]基于应用之上发送随机事件序列给目标程序,通常被用于程序的压力测试。尽管其操作简单且自动化程度高,但是单纯的随机测试不能有效覆盖应用程序。Instrumentation[13]允许对应用程序做更为复杂的测试,甚至是框架层面的。通过Instrumentation可以模拟按键按下、抬起、屏幕点击、滚动等事件。Instrumentation是通过将主程序和测试程序运行在同一个进程来实现这些功能。缺点是对测试人员编写脚本能力要求较高,需要对Android相关知识有一定了解,还需要配置AndroidManifest.xml文件,不能跨多个APP。

2 动态GUI测试技术

动态测试技术是根据测试人员编写的测试脚本,模拟执行程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能。针对Android程序的特殊性,GUI动态测试技术是指模拟用户事件、遍历程序GUI元素、执行应用程序、通过动态运行程序来遍历应用程序GUI控件。

2.1 静态分析应用程序构建ATG、FCG

Android应用程序包含四大组件:Activity、Service、Broadcast Receiver和Content Provider,其中Activity组件主要用来展示程序用户界面。在Activity生命周期里有多个可以相互转化的活动状态,本文只考虑可视状态下的Activity及其界面UI元素。

在本文中定义Android应用程序活动转换图(ATG)和函数调用图(FCG)的概念如下。

定义1 ATG为一个有向图 G=〈V,E〉,其中图的节点V 代表一个Activity,有向边 E 代表从一个Activity到另一个Activity的转化。有向图的入口为程序的MainActivity。FCG是一个从程序中提取的有向图 g=〈v,e〉,节点v代表程序中的函数,有向边e 表示从调用者到被调用者之间的关系。FCG的入口可能为一个Activity的初始化函数,也有可能是用户自定义的函数。

在静态分析应用程序apk文件时,首先反汇编程序apk文件,获得其manifest文件和smali代码,在manifest文件中找出程序注册的Activity。其次,寻找smali代码中的setClass方法及参数,建立Activity启动顺序,在一个Activity中启动另一个Activity即为一个转化。而对于程序FCG,由于其本身相当复杂,本文利用目前使用较为广泛的开源工具androguard[14]进行分析。

在通常情况下,利用androguard获得的函数调用图的调用关系相当复杂。例如,表 1为利用androguard获得相应apk函数调用图中边的数量,从中可以看出:一个应用程序的函数调用图中边可能达到几万或十几万规模,难以通过测试脚本进行覆盖。由于本文基于事件触发遍历活动调用图和函数调用图,因此,在函数调用图中利用正则表达式简化程序中结构化的调用,仅保留与Android组件、监听、触发相关的函数及调用关系,以此简化函数调用图。

表 1 应用程序静态分析结果
2.2 应用程序界面解析和事件模拟

在Android应用程序中,与用户交互的界面即一个Activity的实例,GUI是由View子类构造的层次结构来实现的,每个View控件代表Activity用户界面中某个空间,通常可以响应用户事件,例如一个View控件可以为一个响应用户点击的按钮。Android提供了很多内置的View控件提供给开发人员使用。“Widget(小组件)”是具有可视部分且通常支持用户交互的View控件,比如按钮、文本框、多选框或图像。“Layout(布局)”为ViewGroup的子类,用来管理包含在其中的其他View控件的大小和位置,也可以通过派生View或ViewGroup来创建自定义的小组件或是布局。对于GUI元素,本文只考虑静态注册的GUI元素,利用开源工具apktool反编译apk程序包,提取res目录下的XML文件获得静态GUI元素。通过UiAutomatorviewer[15]工具获取屏幕快照,解析相关GUI元素获得相关属性。获得这些GUI元素之后再根据其相关属性,建立相应的事件集。

利用测试脚本驱动程序运行时需要向系统发送相应的模拟事件,在实际工作中使用UiAutomator测试框架,它可以提供单击、长按、拖拽、输入以及原生事件注入等操作。可以通过它监测系统与应用程序之间的交互,动态反馈调节事件输入,进而遍历应用程序GUI。

2.3 动态遍历算法

基于上文提出的相关概念和模型遍历应用程序,当应用程序运行在当前Activity时,需要遍历从当前位置开始的函数调用图。根据当前GUI状态,获得UI元素属性之后通过测试工具UiAutomator提供的API向程序发送相关的事件,等待程序运行,监控程序动态反馈。重复以上动作,从当前活动转换到另一个活动,通过这种方法遍历整个程序Activity及相关函数。

当程序在运行出现错误时输出日志文件,输出测试脚本模拟的相关事件。具体流程如图 2所示。

图 2 动态测试流程

通过静态分析应用程序的apk文件,获得Activity转换图和函数调用图,通过深度优先遍历算法遍历Activity。当被测试程序开始运行时从主Activity开始遍历,获得当前屏幕状态,获取当前界面GUI控件及属性,利用正则表达式匹配函数调用图中的函数名进行深度遍历。当程序遍历到与Activity相关的Intent函数时,进行Activity遍历,直到深度遍历的Activity栈为空时,Activity遍历完成。当GUI控件集合为空时,基于函数调用图的控件遍历结束,此时,测试程序终止。算法1描述基于深度优先遍历活动转换图,算法2描述基于函数调用图的模拟事件遍历程序。

算法1 活动转化图遍历算法。

1) Initialize TraverseStack;

2) traversed[]={0};

3) traverse act;

4) traversed[act]=1;

5) input act to TraverseStack;

6) while(TraverseStack){>

7) act_temp=top of TraverseStack;

8) if(exist next of act_temp){

9) traverse act_temp.next;

10) traversed[act_temp.next]=1;

11) }

12) else

13) pop act_temp;

14) }

算法2 函数调用图遍历算法。

1) initialize event set

2) initialize GUI set

3) get UiObect set by UiSelector with event attributes

4) traverse the object set base on the FCG

5) compare the type of events with function name by regular expression

6) generate and sent simulation events to device

7) monitor the state change of the window,and feed relevant data

8) if the collection is empty then go to next activity

9) else go to 2)

10) until all activities have been traversed

3 实验验证

通过遍历具体的Android应用程序来说明本文方法的实现,以检验其实际测试效果。三个Android应用程序为从AppChina应用汇下载的订票日历V1.3、WiFi万能钥匙V4.1.6 和360天气V3.22。

3.1 测试框架

本文以Android UiAutomator测试框架为基础,通过UiautomatorViewer工具动态获取元素的属性。编写测试用例遍历应用程序GUI元素,模拟用户操作与设备用户界面交互以及获取屏幕内容。UiAutomator依赖于平台的辅助功能API在远程的控件树上获取屏幕内容以及执行一些操作。UiAutomator的相关类及API如图 3所示。

图 3 UiAutomator类图

利用UiAutomator编写测试脚本自动启动目标程序,解析程序界面,模拟用户动作遍历活动转化图和函数调用图,自动地遍历应用程序的GUI元素,直至满足条件停止遍历。图 4为GUI测试框架,利用命令行发送系统命令,实现PC端和移动端的数据通信,利用Eclipse编写测试脚本打包至模拟器测试执行。在Android系统模拟器中测试程序和被测试应用通过测试API实现遍历和反馈。

图 4 GUI测试框架图
3.2 实验

为说明本文方法的实现过程,验证方法的有效性,使用UiAutomator测试框架编写测试脚本对三个典型的Android应用程序进行GUI遍历测试。开发环境为Windows 7的PC 平台,脚本运行在搭载Android4.4 操作系统的Android 模拟器上。

PC端实验环境如下:CPU为Intel 酷睿i3,操作系统为Windows 7(64位),内存4 GB,开发语言为Java,开发工具为Eclipse。

移动端实验环境如下:系统为Android 4.4.4 ,内核版本为3.10.0-genymotion,内存为2 GB,分辨率为768×1280。

本文以Activity覆盖率和GUI覆盖率为评价标准,覆盖率被定义为测试程序运行过程中遍历到的元素数量与应用静态注册的相应元素数量的比例。遍历到Activity或GUI元素越多,则覆盖率越高,说明方法有效性越强。

利用UiAutomator提供的相关API编写测试程序,打包导入模拟器中测试运行。模拟用户向目标发送事件,根据当前状态动态遍历应用程序。实验结果如表 2所示。

表 2 动态测试结果

表 2可看出,Activity的平均覆盖率达到76%,GUI平均覆盖率达到64%。由实验结果可知,本文方法是有效的。该方法可以用于Android程序测试,在动态安全分析、GUI测试等方面具有较高的可用性。

3.3 实验结果分析

由实验结果可知,基于动静态结合的动态测试方法Activity覆盖率明显高于人工测试的平均值30.08%[16]。与基于控件树遍历的方法[11]相比,在Activity覆盖率方面高于其42.05%~61.29%的覆盖率。本文还增加了GUI覆盖率的评价标准,相对于单独以Activity覆盖率为评价标准,增加GUI覆盖率能更加客观地显示测试效果。因此基于动静态结合的测试方法在Activity和GUI测试上更加有效。由于结合程序函数调用图,测试路径更加接近于程序真实执行路径,有助于应用程序动态安全等方面研究。

在可行性方面,基于Java的UiAutomator具有很好的扩展性和耦合性,相对与基于动态执行环境约束[17],对测试人员素质能力要求不高,无需修改Android系统framework层源码,使测试人员更容易上手,因此本文方法更具备实用性。

通过对应用程序GUI的遍历,可发现影响覆盖率的因素主要包括Activity布局、函数调用图的复杂度和触发事件类型。在布局方面,当接受模拟用户动作之后UI显示界面发生变化,例如WebView,测试用例无法针对这些变化动态调整。在函数调用图方面,随着程序越来越复杂,函数调用图无法准确还原真实的控制流。Android本身定义的事件无法满足客观编程需要,针对开发者自定义的事件函数无法准确地包含在函数调用图中。

4 结语

本文提出了一种基于静态分析的遍历Android应用程序GUI的方法。该方法在程序Activity组件和函数调用关系的基础之上建立遍历模型,通过解析程序界面UI元素,利用UiAutomator工具编写测试脚本模拟用户事件遍历应用程序GUI。通过对真实的应用进行GUI动态遍历实验,验证了本文方法的有效性。

本文方法能以较高的覆盖率遍历Android应用程序的Activity和GUI,可应用于应用程序安全性、动态测试等方面的研究。

今后计划在以下两方面的开展研究:优化测试方法,结合反汇编代码,优化函数调用图,编写测试脚本使之适合复杂的应用程序,提高自动化水平;根据本文方法动态运行程序,监控程序行为,为程序安全分析提供相关数据。

参考文献
[1] IDC. IDC: smartphone OS market share 2015, 2014, 2013, and 2012[EB/OL]. [2016-05-29]. http://www.idc.com/prodserv/smartphone-os-market-share.jsp. (0)
[2] ANBUNATHAN R, BASU A. Data driven architecture based automated test generation for Android mobile[C]//Proceedings of the 2015 IEEE International Conference on Computational Intelligence and Computing Research. Piscataway, NJ: IEEE, 2015: 1-5. (0)
[3] ANBUNATHAN R, BASU A. An event based test automation framework for Android mobiles[C]//Proceedings of the 2014 International Conference on Contemporary Computing and Informatics. Piscataway, NJ: IEEE, 2014: 76-79. (0)
[4] AMALFITANO D, FASOLINO A R, TRAMONTANA P. A GUI crawling-based technique for Android mobile application testing[C]//Proceedings of the 2011 IEEE Fourth International Conference on Software Testing, Verification and Validation Workshops. Washington, DC: IEEE Computer Society, 2011: 252-261. http://cn.bing.com/academic/profile?id=2113867182&encoded=0&v=paper_preview&mkt=zh-cn (0)
[5] AMALFITANO D, FASOLINO A R, TRAMONTANA P, et al. Using GUI ripping for automated testing of Android applications[C]//Proceedings of the 27th IEEE/ACM International Conference on Automated Software Engineering. New York: ACM, 2012: 258-261. (0)
[6] HU C, NEAMTIU I. Automating GUI testing for Android applications[C]//Proceedings of the 6th International Workshop on Automation of Software Test. New York: ACM, 2011: 77-83. http://cn.bing.com/academic/profile?id=2004921952&encoded=0&v=paper_preview&mkt=zh-cn (0)
[7] LI L, BARTEL A, BISSYANDÉT F, et al. IccTA: detecting inter-component privacy leaks in Android apps[C]//Proceedings of the 37th International Conference on Software Engineering. Piscataway, NJ: IEEE, 2015, 1: 280-291. (0)
[8] ARZT S, RASTHOFER S, FRITZ C, et al. FlowDroid: precise context, flow, field, object-sensitive and lifecycle-aware taint analysis for Android apps[J]. ACM SIGPLAN Notices, 2014, 49 (6) : 259-269. doi: 10.1145/2666356 (0)
[9] WEI F, ROY S, OU X. Amandroid: a precise and general inter-component data flow analysis framework for security vetting of Android apps[C]//Proceedings of the 2014 ACM SIGSAC Conference on Computer and Communications Security. New York: ACM, 2014: 1329-1341. http://cn.bing.com/academic/profile?id=2027538101&encoded=0&v=paper_preview&mkt=zh-cn (0)
[10] JENSEN C S, PRASAD M R, MØller A. Automated testing with targeted event sequence generation[C]//Proceedings of the 2013 International Symposium on Software Testing and Analysis. New York: ACM, 2013: 67-77. http://cn.bing.com/academic/profile?id=2121507867&encoded=0&v=paper_preview&mkt=zh-cn (0)
[11] 赵耀宗, 程绍银, 蒋凡. Android 应用程序 GUI 遍历的自动化方法[J]. 计算机系统应用, 2015, 24 (9) : 219-224. ( ZHAO Y Z, CHENG S Y, JIANG F. Automatic method for GUI traversal in Android applications[J]. Computer Systems & Applications, 2015, 24 (9) : 219-224. ) (0)
[12] Android developer. Monkey[EB/OL]. [2016-02-29]. https://developer.android.com/intl/zh-cn/tools/help/monkey.html. (0)
[13] Android developer. Instrumentation[EB/OL]. [2016-02-29]. http://developer.android.com/intl/zh-cn/reference/android/app/Instrumentation.html. https://developer.android.com/index.html (0)
[14] Androguard[EB/OL]. [2016-05-29]. https://github.com/androguard/androguard. (0)
[15] Android developer. UiAutomatorviewer[EB/OL]. [2016-02-21]. https://developer.android.com/intl/zh-cn/tools/testing-support-library/index.html. https://developer.android.com/topic/libraries/testing-support-library/index.html (0)
[16] AZIM T, NEAMTIU I. Targeted and depth-first exploration for systematic testing of Android apps[J]. ACM SIGPLAN Notices, 2013, 48 (10) : 641-660. doi: 10.1145/2544173 (0)
[17] ZHENG C, ZHU S, DAI S, et al. SmartDroid: an automatic system for revealing UI-based trigger conditions in Android applications[C]//Proceedings of the Second ACM Workshop on Security and Privacy in Smartphones and Mobile Devices. New York: ACM, 2012: 93-104. (0)