王國(guó)珍,楊紅麗
(北京工業(yè)大學(xué) 信息學(xué)部,北京 100124)
隨著移動(dòng)互聯(lián)網(wǎng)的高速發(fā)展,智能手機(jī)已經(jīng)成為每個(gè)人生活中必不可少的工具,手機(jī)操作系統(tǒng)也正在高速發(fā)展.截止到2017年,Android智能手機(jī)在全球市場(chǎng)中占有超過85%的市場(chǎng)份額[1],占據(jù)著市場(chǎng)的主導(dǎo)地位.Android應(yīng)用市場(chǎng)為用戶提供了功能各異的應(yīng)用程序,截止2017年2月,Google Play已經(jīng)發(fā)布了2700 000個(gè)應(yīng)用[2].Android應(yīng)用的種類變得更加多樣,提供的功能也更加專業(yè),應(yīng)用之間可以分享信息并且相互協(xié)作完成一些復(fù)雜的任務(wù).例如,一個(gè)電子支付應(yīng)用可以被多個(gè)第三方的電子商務(wù)應(yīng)用調(diào)用來完成支付功能.Android系統(tǒng)提供了開放活動(dòng)(Exported Activity,EA)機(jī)制,可以將應(yīng)用內(nèi)特定的Activity分享給其他的應(yīng)用.
EA往往包含開發(fā)者想要推廣的關(guān)鍵功能,可以被其他的應(yīng)用重復(fù)執(zhí)行.因此,它們的質(zhì)量是關(guān)鍵功能得到有效推廣的關(guān)鍵因素.另一方面,因?yàn)镋A可以被任意的應(yīng)用執(zhí)行,因此包含EA但是開發(fā)不是很完備的應(yīng)用很容易被惡意應(yīng)用濫用[3].綜上,開放活動(dòng)的質(zhì)量驗(yàn)證是一個(gè)非常值得關(guān)注的課題.
在Android應(yīng)用質(zhì)量驗(yàn)證方面,測(cè)試是一個(gè)很熱門的課題.大部分現(xiàn)有的工作主要集中在分析和測(cè)試單個(gè)應(yīng)用的圖形交互界面(Graphical User Interface,GUI)上,被測(cè)應(yīng)用與外部應(yīng)用之間的交互往往被忽略.我們的實(shí)驗(yàn)結(jié)果表明,在現(xiàn)有工作中EA很難被覆蓋到.因此,在對(duì)Android應(yīng)用的測(cè)試過程中應(yīng)該使用針對(duì)性的技術(shù)對(duì)這類Activity進(jìn)行測(cè)試.
本文討論了如何系統(tǒng)的測(cè)試Android應(yīng)用中的EA.首先,自動(dòng)的生成一系列的應(yīng)用作為測(cè)試驅(qū)動(dòng)應(yīng)用,然后利用這些測(cè)試驅(qū)動(dòng)應(yīng)用啟動(dòng)目標(biāo)應(yīng)用中的EA,發(fā)現(xiàn)其中的漏洞.本文使用數(shù)據(jù)流分析技術(shù)得到啟動(dòng)EA所需的信息,結(jié)合預(yù)先定義的模板生成測(cè)試驅(qū)動(dòng)應(yīng)用.選取了10個(gè)現(xiàn)實(shí)生活中使用非常廣泛的安卓應(yīng)用進(jìn)行了測(cè)試并且有效的檢測(cè)到了一些問題.通過分析測(cè)試結(jié)果,將檢測(cè)到的問題分為兩類:應(yīng)用崩潰和界面異常.實(shí)驗(yàn)結(jié)果表明本文提出的方法可以有效的對(duì)EA進(jìn)行系統(tǒng)化測(cè)試,間接提高了存在EA應(yīng)用的質(zhì)量.
這部分內(nèi)容將介紹在一些相關(guān)的背景知識(shí),主要包括EA和Android系統(tǒng)提供的Intent機(jī)制.
Activity是使用率最高的Android組件,它提供了與用戶交互的GUI窗口.Activity可以分成兩類:內(nèi)部活動(dòng)(Internal Activity,IA)和開放活動(dòng)(Exported Activity,EA).前者只能被同一應(yīng)用中的其他組件啟動(dòng),后者允許被外部應(yīng)用調(diào)用.EA是一種應(yīng)用間有效的交互、協(xié)作方式.默認(rèn)情況下除了應(yīng)用的Main Activity之外所有的Activity都是IA類型,開發(fā)者可以在Manifest文件中將Activity的屬性(android:exported)設(shè)置為TRUE,使得該Activity變?yōu)镋A類型.如果不設(shè)置android:exported屬性,也可以在Manifest配置文件中EA對(duì)應(yīng)的 外部應(yīng)用通過Intent機(jī)制調(diào)用其他應(yīng)用中的EA.Intent是消息傳遞的載體,其中包含目標(biāo)組件的標(biāo)識(shí)符和目標(biāo)組件初始化所需的數(shù)據(jù). 發(fā)送方組件通過一系列重載的API(Application Programming Interface)以鍵值對(duì)(key-value)的形式將不同類型的數(shù)據(jù)附加到Intent中,例如,putExtra(String,int)可以添加整形數(shù)據(jù),putExtra(String,String)可以附加字符串型數(shù)據(jù).該方法的第一個(gè)參數(shù)是用于識(shí)別不同數(shù)據(jù)的鍵值(key),第二個(gè)參數(shù)是表明該數(shù)據(jù)的值(value).Android系統(tǒng)還提供了接收方組件獲取特定鍵值所對(duì)應(yīng)數(shù)據(jù)的API.例如,getIntExtra(String key)可以根據(jù)指定的key值來獲取其對(duì)應(yīng)的整形數(shù)值. 第三方開發(fā)商開發(fā)的應(yīng)用通常會(huì)通過該機(jī)制為EA傳遞數(shù)據(jù)來完成一些任務(wù),所以數(shù)據(jù)的有效性檢驗(yàn)和EA的容錯(cuò)性是非常重要并且需要特別關(guān)注的方向. 本小節(jié)將通過一個(gè)簡(jiǎn)單的例子介紹本文研究的動(dòng)機(jī).圖1是樣例應(yīng)用中一個(gè)EA(Foo)的代碼片段,該EA不會(huì)被應(yīng)用中的其他組件調(diào)用.在onCreate方法中包含一條字符串類型數(shù)據(jù)和一條整形數(shù)據(jù),它們的鍵值分別為:“key1”、“key2”.由于該 Activity 不會(huì)被應(yīng)用自身調(diào)用,所以現(xiàn)有的技術(shù)和工具[4,5]不會(huì)覆蓋到它. 圖1 EA的代碼片段 圖2是一個(gè)調(diào)用EA的測(cè)試驅(qū)動(dòng)應(yīng)用的示例代碼.它創(chuàng)建了一個(gè)Intent實(shí)例,設(shè)置它的目標(biāo)Activity組件為Foo,并且設(shè)置了Foo初始化數(shù)據(jù),最后通過startActivity(Intent intent)方法執(zhí)行該Intent.通過這個(gè)例子可以發(fā)現(xiàn),對(duì)EA系統(tǒng)化測(cè)試的關(guān)鍵問題是如何為Intent中各種各樣的數(shù)據(jù)賦值. 圖2 Foo的測(cè)試驅(qū)動(dòng)應(yīng)用 本文提出了一種系統(tǒng)化測(cè)試Android應(yīng)用中EA的方法.該小節(jié)中,首先對(duì)方法進(jìn)行了簡(jiǎn)單的概述,然后詳細(xì)介紹幾個(gè)關(guān)鍵模塊. 為了測(cè)試待測(cè)樣本中所有的EA,本文所提方法的主要思想是自動(dòng)化的生成一批測(cè)試驅(qū)動(dòng)應(yīng)用,每個(gè)測(cè)試驅(qū)動(dòng)應(yīng)用會(huì)執(zhí)行攜帶不同數(shù)據(jù)(包括無效數(shù)據(jù))的Intent,啟動(dòng)被測(cè)EA以檢測(cè)它處理不同數(shù)據(jù)時(shí)是否會(huì)出現(xiàn)漏洞.圖3是方法的概述.它包含四個(gè)模塊:Android安裝包(Android Package,APK)解析、Intent分析、測(cè)試驅(qū)動(dòng)生成、測(cè)試執(zhí)行.第一個(gè)模塊提取待測(cè)樣本中所有的EA信息,包括:EA的包名和類名等;第二個(gè)模塊獲取每個(gè)EA啟動(dòng)所需的數(shù)據(jù)信息;測(cè)試驅(qū)動(dòng)生成模塊生成一批可調(diào)用EA的測(cè)試驅(qū)動(dòng)應(yīng)用;最后一個(gè)模塊在一臺(tái)真實(shí)的設(shè)備上執(zhí)行生成的測(cè)試驅(qū)動(dòng)應(yīng)用并記錄執(zhí)行結(jié)果. Android應(yīng)用大多數(shù)都采用Java語言實(shí)現(xiàn)并被編譯為Dalvik字節(jié)碼.應(yīng)用中的字節(jié)碼文件、資源文件和配置文件最后被打包成一個(gè)二進(jìn)制形式的APK文件.為了進(jìn)行后面的分析,本文首先利用Apktool[6]對(duì)APK文件進(jìn)行反編譯,反匯編二進(jìn)制代碼和配置文件.Apktool是Google官方提供的一款對(duì)Android應(yīng)用逆向工程的工具.基于Android官方文檔中對(duì)Manifest配置文件的介紹,解析Manifest文件提取所有Activity信息,根據(jù)EA的android:exported屬性以及 圖3 方法概述 為了構(gòu)建測(cè)試驅(qū)動(dòng)應(yīng)用,需要獲取每個(gè)EA所需的數(shù)據(jù)信息.根據(jù)上文所述,Activity主要利用若干特定的系統(tǒng)API(參見1.2)將鍵值(或者數(shù)據(jù)名稱)指定為API的參數(shù)來獲取數(shù)據(jù)內(nèi)容.因此,該模塊的目標(biāo)就是提取每個(gè)EA中數(shù)據(jù)的鍵值,并通過判定API的類型確定數(shù)據(jù)的類型. 以圖1中的源碼為例,需要分析該EA代碼中所有的方法并且確定getStringExtra和getIntExtra的第一個(gè)參數(shù)的值,即Intent中附加數(shù)據(jù)的鍵值.實(shí)際上,該問題可以被看作是一個(gè)到達(dá)定值問題,它是數(shù)據(jù)流分析中最普遍和最有用的模型.到達(dá)定值模型可以靜態(tài)的確定那些預(yù)定義的變量在到達(dá)代碼指定位置時(shí)的值.本文中使用Soot[7,8]提供的數(shù)據(jù)流分析模型ForwardDataFlowAnalysis實(shí)現(xiàn)了該算法. 該模塊生成測(cè)試EA的測(cè)試驅(qū)動(dòng)應(yīng)用,預(yù)先設(shè)計(jì)了一個(gè)測(cè)試驅(qū)動(dòng)應(yīng)用的模板,只包含一個(gè)Activity.在入口函數(shù)onCreate中創(chuàng)建了一個(gè)Intent實(shí)例,它的目標(biāo)Activity是被測(cè)EA,這樣就可以在測(cè)試驅(qū)動(dòng)程序啟動(dòng)后可以自動(dòng)的啟動(dòng)目標(biāo)EA.之后我們隨機(jī)生成之前模塊中提取到的鍵值所對(duì)應(yīng)數(shù)據(jù)類型的值,并且使用putExtra APIs將生成的數(shù)據(jù)添加到Intent實(shí)例中.在onCreate的最后將Intent作為startActivity API的參數(shù)啟動(dòng)EA. 除了這些代碼,Manifest文件也是應(yīng)用執(zhí)行的重要部分,所以創(chuàng)建了一個(gè)Manifest文件并且在其中聲明Activity列表.最后,將源碼和Manifest文件一起打包成一個(gè)APK文件. 測(cè)試驅(qū)動(dòng)應(yīng)用生成之后,將它們部署到設(shè)備中并執(zhí)行它們?nèi)?dòng)EA,為了檢測(cè)EA中存在的問題,需要記錄執(zhí)行過程中設(shè)備中出現(xiàn)的信息.使用Adb工具將上述過程自動(dòng)化,Adb是Android 軟件程序工具包(Software Development Kit,SDK)提供的一款用于連接Android設(shè)備的工具.Adb可以批量的將測(cè)試驅(qū)動(dòng)應(yīng)用安裝到設(shè)備中并執(zhí)行這些應(yīng)用,測(cè)試驅(qū)動(dòng)應(yīng)用被Adb啟動(dòng)后會(huì)自動(dòng)化的啟動(dòng)測(cè)試目標(biāo)應(yīng)用中的EA,并且保存設(shè)備的屏幕截圖供之后的分析用. 為了評(píng)估方法的有效性,本文根據(jù)上文提到技術(shù)實(shí)現(xiàn)了一個(gè)工具EASTER(Exported Activity:Specific TestER),使用若干真實(shí)應(yīng)用在一臺(tái)Google Nexus 5上進(jìn)行了實(shí)驗(yàn). 從Google Play和其他的Android市場(chǎng)上下載了10個(gè)應(yīng)用作為實(shí)驗(yàn)應(yīng)用.表1展示了這些應(yīng)用的詳細(xì)信息,包括應(yīng)用大小、Activity的數(shù)量和EA數(shù)量.從表中可以發(fā)現(xiàn)EA在現(xiàn)實(shí)應(yīng)用中被廣泛使用,系統(tǒng)的測(cè)試它們是一個(gè)非常重要的研究課題.本文使用了很流行的Android應(yīng)用黑盒測(cè)試工具M(jìn)onkey[9]對(duì)處理過的應(yīng)用進(jìn)行測(cè)試,用以評(píng)估Monkey對(duì)應(yīng)用中EA的覆蓋情況,本次試驗(yàn)中對(duì)應(yīng)用中EA的字節(jié)碼進(jìn)行了插樁處理.實(shí)驗(yàn)中設(shè)置Monkey對(duì)每個(gè)應(yīng)用進(jìn)行測(cè)試時(shí)生成的事件數(shù)量為10 000.覆蓋率如表1中最后一列所示,實(shí)驗(yàn)表明應(yīng)用中大約有17%的EA可以被Monkey生成的事件序列所覆蓋. 實(shí)驗(yàn)中首先使用EASTER為應(yīng)用中每個(gè)EA生成一個(gè)測(cè)試驅(qū)動(dòng)應(yīng)用,然后讓它們?cè)谠O(shè)備中有序的運(yùn)行.試驗(yàn)中,如果一個(gè)測(cè)試驅(qū)動(dòng)應(yīng)用可以成功的啟動(dòng)該EA,就認(rèn)為該測(cè)試驅(qū)動(dòng)應(yīng)用可以覆蓋該EA.表2展示詳細(xì)的實(shí)驗(yàn)結(jié)果,其中第三列給出了被覆蓋的EA數(shù)量,最后一列表明了覆蓋率.從表中可以發(fā)現(xiàn),生成的測(cè)試驅(qū)動(dòng)應(yīng)用可以覆蓋實(shí)驗(yàn)應(yīng)用中大多數(shù)的EA(平均73.7%),覆蓋率遠(yuǎn)遠(yuǎn)大于Monkey對(duì)EA的覆蓋率.有幾個(gè)特殊的樣本的覆蓋率較低,例如:Snapchat和騰訊新聞.這些應(yīng)用中對(duì)一些EA設(shè)置了某些系統(tǒng)或者自定義的權(quán)限,拒絕來自于未授權(quán)應(yīng)用的調(diào)用請(qǐng)求.這個(gè)問題將在之后的工作中解決. 表1 實(shí)驗(yàn)應(yīng)用 表2 EASTER的覆蓋率 實(shí)驗(yàn)中使用EASTER結(jié)合不同的Intent數(shù)據(jù)為應(yīng)用中每個(gè)EA生成了5個(gè)測(cè)試驅(qū)動(dòng)應(yīng)用,并深入研究了它們執(zhí)行過程中出現(xiàn)的問題.可以將實(shí)驗(yàn)過程中出現(xiàn)的問題分成兩類:應(yīng)用奔潰和顯示異常,其中前者表示該EA在測(cè)試中會(huì)崩潰,后者代表EA顯示不正常,例如顯示沒有友好用戶提示的空白窗口.表3展示了詳細(xì)的實(shí)驗(yàn)結(jié)果,其中第二和第三列是生成測(cè)試驅(qū)動(dòng)應(yīng)用的數(shù)量和報(bào)告出有漏洞EA的數(shù)量.最后兩列分別列出了在EA測(cè)試過程中出現(xiàn)應(yīng)用崩潰和顯示異常兩類問題的測(cè)試驅(qū)動(dòng)程序的數(shù)量. 表3 EASTER檢測(cè)到漏洞數(shù)量 本小節(jié)中進(jìn)一步的分析了存在漏洞應(yīng)用的代碼,準(zhǔn)確的定位漏洞的位置.首先利用反編譯工具jdgui[10]將有漏洞的應(yīng)用的字節(jié)碼轉(zhuǎn)換成Java程序,之后人工的檢查檢測(cè)報(bào)告中EA的代碼.下面分別對(duì)兩個(gè)應(yīng)用中的兩種漏洞進(jìn)行分析. 圖4顯示愛奇藝應(yīng)用中一個(gè)類名為 FalconActivity的EA的代碼片段.推測(cè)第三行中開發(fā)者忽視了對(duì)“argument”鍵值所對(duì)應(yīng)數(shù)據(jù)使用前的有效性校驗(yàn).在實(shí)驗(yàn)中發(fā)現(xiàn),隨機(jī)生成一個(gè)字符串賦值給該變量,應(yīng)用總會(huì)出現(xiàn)崩潰. 圖4 愛奇藝應(yīng)用的代碼片段 圖5給出了優(yōu)酷應(yīng)用中類名為 GameDetailsActivity的EA中onCreate方法的代碼片段.我們可以發(fā)現(xiàn)如果Intent不為空并且appid為空時(shí)loaddata方法不會(huì)被執(zhí)行并且該Activity會(huì)顯示了一個(gè)空白窗口,這樣會(huì)迷惑用戶. 圖5 優(yōu)酷的代碼片段 這部分將簡(jiǎn)要介紹了幾種Android應(yīng)用自動(dòng)測(cè)試生成方法的相關(guān)工作. Fuzzing是一個(gè)被普遍使用,對(duì)Android應(yīng)用進(jìn)行黑盒測(cè)試的方法.Machir等人[4]開發(fā)了一款隨機(jī)生成系統(tǒng)事件的工具——Dynodroid,該工具生成的事件與用戶事件相同. 基于模型的測(cè)試也是測(cè)試GUI程序典型的技術(shù),也可以用來測(cè)試Android應(yīng)用.Wang等人[5]將GUI行為構(gòu)建成一個(gè)FSM模型,他們利用靜態(tài)分析技術(shù)提取與控件相關(guān)的事件,使用動(dòng)態(tài)探測(cè)技術(shù)捕獲Activity的遷移.Azim和Neamtiu[11]也提出了一個(gè)測(cè)試生成工具——A3E,它使用靜態(tài)分析技術(shù)構(gòu)建GUI模型,基于深度優(yōu)先搜索和目標(biāo)搜索策略并結(jié)合GUI模型生成事件序列. 以上研究值關(guān)注為應(yīng)用生成事件序列.Mirzaei等人[4]將Android應(yīng)用中的事件輸入和數(shù)據(jù)輸入?yún)^(qū)分開,利用符號(hào)執(zhí)行引擎Symbolic PathFinder(SPF)生成數(shù)據(jù)輸入.Jensen等人[12]使用符號(hào)執(zhí)行技術(shù)生成事件和數(shù)據(jù)覆蓋指定代碼. 現(xiàn)有的工作主要是通過動(dòng)態(tài)執(zhí)行應(yīng)用或者靜態(tài)分析代碼來提取和遍歷程序行為.這些方法有一個(gè)共同的缺點(diǎn)就是它們不能有效的覆蓋應(yīng)用的特殊部分——EA,因?yàn)镋A往往在應(yīng)用內(nèi)部不會(huì)被調(diào)用,大部分EA是提供給外部應(yīng)用進(jìn)行訪問的. 本文介紹了一個(gè)自動(dòng)化測(cè)試Android應(yīng)用中EA的方法,現(xiàn)有的工作中很少有相關(guān)的討論.實(shí)驗(yàn)結(jié)果表明EA被廣泛的應(yīng)用在現(xiàn)實(shí)的應(yīng)用中,但是很多時(shí)候開發(fā)者對(duì)它的開發(fā)不是非常完備.由于EA通常包含開發(fā)者渴望推廣的功能,對(duì)EA進(jìn)行系統(tǒng)化的測(cè)試在保證Android應(yīng)用質(zhì)量的研究中是非常值得關(guān)注的問題.相信本文的工作是對(duì)現(xiàn)有工作的一個(gè)非常有用的補(bǔ)充,之后的研究也是很有意義的. 本文只是對(duì)Android應(yīng)用中EA進(jìn)行了初步的研究,并沒有全面考慮EA和Intent機(jī)制的所有特性,例如Intent Filter和Permission等.之后的工作將解決這些問題以加強(qiáng)EASTER的性能.除此之外,Intent的數(shù)據(jù)也是通過自己開發(fā)的工具隨機(jī)生成的,之后的工作中也可以使用模糊測(cè)試或者混合測(cè)試技術(shù)加強(qiáng)EASTER的功能.1.2 Intent
1.3 示例說明
2 測(cè)試方法
2.1 方法概述
2.2 APK解析
2.3 Intent分析
2.4 測(cè)試驅(qū)動(dòng)生成
2.5 測(cè)試執(zhí)行
3 試驗(yàn)結(jié)果與分析
3.1 實(shí)驗(yàn)設(shè)計(jì)
3.2 EA的測(cè)試覆蓋率
3.3 實(shí)驗(yàn)結(jié)果分析
3.4 案例分析
4 相關(guān)工作
5 結(jié)語