【摘 要】Android的大量應用給移動終端用戶帶來了豐富的體驗,但其存在的大量盜版應用卻嚴重損害了開發(fā)者的權(quán)益。本文在分析Android應用結(jié)構(gòu)的基礎上,總結(jié)現(xiàn)有的Android應用保護技術(shù),如代碼混淆技術(shù)、動態(tài)加載技術(shù)、軟件水印技術(shù)等。
【關(guān)鍵詞】Android 軟件保護 代碼混淆 動態(tài)加載 軟件水印
【中圖分類號】TP311 【文獻標識碼】A 【文章編號】1674-4810(2015)35-0097-03
由于Android具有開源和免費的特點,得到了大量移動終端制造商的支持,各種各樣的Android應用層出不窮。在應用數(shù)量不斷增長的同時,盜版應用的數(shù)量也隨之增加。為了阻止應用被破解或篡改,多種保護Android應用的方法也應運而生,本文主要對現(xiàn)有的Android應用保護技術(shù)進行歸納總結(jié)。
一 Android應用結(jié)構(gòu)
Android系統(tǒng)的結(jié)構(gòu)如圖1所示,應用程序的執(zhí)行主要依賴于Android的核心庫(Libraries)和Dalvik虛擬機。
圖1 Android系統(tǒng)結(jié)構(gòu)
由于PC平臺的Java虛擬機不適合移動終端,因此Google公司為Android平臺設計了Dalvik虛擬機。它是Android應用程序的最終運行環(huán)境。除了本地庫代碼可以直接在底層運行外,應用程序的其他部分都被編譯為Dalvik字節(jié)碼在Dalvik虛擬機上運行。Java程序經(jīng)過編譯后會生成Android平臺特有的dex(Dalvik Executable)文件,它是一種專為Dalvik虛擬機設計的壓縮文件格式,適合處理器頻率和內(nèi)存容量有限的移動終端。
為了給用戶提供更好的操作體驗,Android應用除了dex文件外還包括其他一些文件或文件目錄,如用于存儲簽名信息的META-INF目錄,用于存儲資源文件的res目錄,用于存儲本地代碼的lib目錄和二進制資源文件resources.arsc等。這些文件會在Android應用程序發(fā)布前,和dex文件一同打包成完整的apk(Android Package)文件。
二 Android應用保護技術(shù)
一般來說,攻擊者對Android應用的破解主要經(jīng)過以下幾個步驟:首先是對應用的反編譯,通過反編譯的代碼分析程序的執(zhí)行流程,從中找到破解應用的突破口;其次,如果對應用的反編譯效果不理想,攻擊者會轉(zhuǎn)向?qū)玫母櫿{(diào)試,嘗試在跟蹤的過程中發(fā)現(xiàn)程序的某些關(guān)鍵數(shù)據(jù)或代碼;最后,如果完成了對Android應用的破解,攻擊者會對應用進行重新打包,生成新的apk文件。為了阻止攻擊者對軟件的破解,可以采取以下幾種方法對軟件進行保護。
1.代碼混淆技術(shù)
代碼混淆的目的是將程序轉(zhuǎn)化為語義相同但語句不同的版本。經(jīng)過混淆的代碼可以明顯加大分析代碼語義的難度,因此非常適合防范針對程序的反編譯攻擊。由于Android應用主要使用Java語言進行開發(fā),可以通過混淆Java源代碼,或混淆編譯后的字節(jié)碼來實現(xiàn)阻止攻擊者分析程序語義的目的。目前代碼混淆主要有以下幾種:
第一,詞法混淆和數(shù)據(jù)混淆。詞法混淆是改變或去除函數(shù)名或變量名原有含義的一種混淆方法,而數(shù)據(jù)混淆是對變量或數(shù)據(jù)結(jié)構(gòu)進行分割或合并的一種混淆方法。De AR提出一種通過交換程序中的變量名、函數(shù)名和類名的詞法混淆方法,這種方法的特點是不僅可以去除程序中的詞法信息,而且可以進行逆向混淆。Chan提出了一種對標識符進行修改和重用的詞法混淆算法。這種方法不是直接對標識符重命名,而是盡可能重用已有的標識符。經(jīng)過這種方法混淆的程序,其中存在大量名稱相似的標識符,攻擊者很難從中分析出函數(shù)或變量原有的含義。Collberg總結(jié)了多種數(shù)據(jù)混淆的方案,如多變量(或數(shù)組)的合并、單變量(或數(shù)組)的拆解、靜態(tài)字符串的動態(tài)生成等。這些方法的目的都是去除原始代碼中的有意義信息,增加攻擊者理解代碼的難度。
第二,類混淆和布局混淆。Sosonkin等人提出了類合并和類拆分兩種混淆方法。顧名思義,類合并是將原有類中的變量和函數(shù)進行組合后生成新類,而類拆分則是將一個完整的類拆分成多個相互關(guān)聯(lián)的小類。無論是類合并還是類拆分,都會改變原有類之間的調(diào)用或繼承關(guān)系,人為地增加代碼分析的難度。
布局混淆主要采用刪除調(diào)試、注釋信息、改變數(shù)據(jù)的分布順序?qū)Τ绦蜻M行混淆。由于在編寫程序時往往會留下大量的注釋信息,而邏輯上相關(guān)的數(shù)據(jù)往往也會被程序員放置在物理上相鄰的位置,這些都會成為攻擊者分析程序的線索。為了清除這些有可能被攻擊者利用的信息,Collberg提出了一些布局混淆的方法,如改變實例變量、方法或數(shù)組的順序等。
第三,控制流混淆。程序的控制流信息是一種非常重要的程序結(jié)構(gòu)信息。如果攻擊者重構(gòu)出程序的控制流信息,不僅可以了解程序的工作流程,而且還可以很容易地對程序的執(zhí)行過程進行篡改。因此,必須使用某種方法對于程序的控制流信息進行修改,使其變得難以理解,從而增加攻擊者破解的難度。
對于控制流信息的修改,一般采用控制流混淆技術(shù),具體有以下幾種方法:一是通過內(nèi)聯(lián)、外聯(lián)變換改變代碼的組織結(jié)構(gòu)。例如,合并函數(shù)或使用增加額外參數(shù)的辦法來控制函數(shù)的執(zhí)行次序。這種方法改變了原有代碼中函數(shù)的調(diào)用順序和執(zhí)行次數(shù),也稱為控制聚合混淆。二是對原有代碼的執(zhí)行方向進行調(diào)整。例如,原有代碼中的增序循環(huán)可以轉(zhuǎn)變?yōu)橄喾吹慕敌蜓h(huán)。這種方法不會改變程序的執(zhí)行,但攻擊者卻會產(chǎn)生迷惑,因此也稱為控制順序混淆。三是通過“壓扁”“平整”控制流,改變原有程序的分支轉(zhuǎn)移結(jié)構(gòu)。例如,將多個IF…ELSE分支整合成一個多分支的switch結(jié)構(gòu)。這種方法將原本清晰的條件分支轉(zhuǎn)變?yōu)榛逎y懂的分支結(jié)構(gòu),從而增加了分析的難度,因此也稱為Dispatcher混淆。四是通過增加無效代碼、Goto語句等,偽造額外的控制流,不僅消耗攻擊者的分析時間,也可以令某些反編譯軟件失效,這種方法也稱為控制計算混淆。
2.動態(tài)加載技術(shù)
動態(tài)加載是一種在PC平臺得到廣泛應用的代碼保護技術(shù)。它的實現(xiàn)原理是將原始程序嵌套在另一個可執(zhí)行程序中,將該可執(zhí)行程序變成原始程序的“外殼”。動態(tài)加載的原理如圖2所示。
圖2 動態(tài)加載原理
當用戶運行增加了“外殼”的可執(zhí)行程序時,首先被執(zhí)行的是“外殼”代碼,它會將原始程序從數(shù)據(jù)段中解密出來,釋放到內(nèi)存或文件系統(tǒng)中,然后根據(jù)一定的條件(如驗證用戶身份是否合法)決定是否將運行權(quán)交給原始程序。如果攻擊者對增加了“外殼”的可執(zhí)行文件進行反編譯,只能得到“外殼”代碼的反編譯結(jié)果,無法窺探到原始程序的代碼。
對Android應用的動態(tài)加載保護可以通過使用Java類加載器和Jni調(diào)用本地代碼實現(xiàn)。如果使用Java類加載器,那么需要生成“外殼”程序的dex文件,并將原始程序的dex文件作為數(shù)據(jù)嵌入“外殼”程序的數(shù)據(jù)段中,形成圖3所示的結(jié)構(gòu)。
Dex Header
Checksum
Signature
File_size
……
Loader代碼
加密壓縮后的原始dex代碼
圖3 加殼后的dex文件
當“外殼”程序開始執(zhí)行后,它會將數(shù)據(jù)段中的原始dex文件進行恢復,存放在文件系統(tǒng)中,然后通過DexClassLoader加載運行原始的dex文件。該方法實現(xiàn)簡單,但需要將原始dex文件釋放到文件系統(tǒng)中,存在一定的安全隱患。
為了克服將原始dex文件釋放到文件系統(tǒng)中的缺點,Patrick提出了一種利用Jni調(diào)用openDexFile(byte[ ])函數(shù)來實現(xiàn)加載dex文件的方法。由于該方法可通過一個字節(jié)數(shù)組來傳遞 dex文件,原始dex文件可以直接釋放到內(nèi)存中,無須寫入文件系統(tǒng),因此避免了文件泄露的危險。
3.軟件水印技術(shù)
軟件水印是一種把程序的版權(quán)信息和用戶身份信息嵌入到程序中,或利用程序本身的一些特征(如代碼結(jié)構(gòu)、調(diào)用關(guān)系等)來識別盜版軟件的技術(shù)。由于Android應用在被攻擊者破解后,往往會被重新打包發(fā)布,因此目前針對Android應用的軟件水印保護研究主要集中在如何檢測應用的相似度,從而檢測出被重新打包的盜版應用。
Wu Zhou以Dalvik字節(jié)碼中的操作符和操作數(shù)作為應用的特征,設計了一種應用相似度檢測系統(tǒng)。該系統(tǒng)利用模糊散列技術(shù),分別提取原始程序和目標程序的特征,然后依據(jù)特征值的近似程度作為檢測的結(jié)果。
為了提高檢測的準確度,Jonathan將較難被篡改的程序依賴關(guān)系圖PDG(Program Dependency Graph)作為程序的特征,提出了一種基于PDG的相似度檢測系統(tǒng),并通過實驗證明該方法的有效性。
4.反跟蹤調(diào)試技術(shù)
跟蹤調(diào)試軟件是程序設計人員發(fā)現(xiàn)程序中潛在錯誤的重要工具,但攻擊者同樣可以使用跟蹤調(diào)試軟件來記錄程序的執(zhí)行過程、內(nèi)存訪問和文件讀寫數(shù)據(jù),從中查找分析程序執(zhí)行中的關(guān)鍵部分,從而對程序進行破解。為了讓攻擊者得不到程序執(zhí)行時的信息,可以使用以下的方法阻止跟蹤調(diào)試軟件對程序進行動態(tài)跟蹤。
第一,時間差異法。時間差異法主要是通過在代碼的任意兩端插入獲取當前時間的函數(shù),通過計算兩端時間的差值,來判斷是否有調(diào)試器附著在本程序進程上。如果程序沒有被調(diào)試器附著,那么程序的執(zhí)行速度完全取決于CPU的運算速度,在代碼任意兩端設置的時間函數(shù)所計算出的時間差應該是一個很小的、固定的值。但是,如果程序被調(diào)試器附著后,攻擊者往往會對程序進行單步執(zhí)行跟蹤,從而觀察、分析程序的執(zhí)行過程,這樣一來勢必造成時間差的大幅增加。因此,可以通過編寫代碼,在需要保護的代碼兩端設置計時函數(shù)并設置閾值。如果計時函數(shù)計算出的時間差超過閾值,則說明程序很有可能被調(diào)試器附著,可以采取終止程序等手段來阻止攻擊者的跟蹤調(diào)試。
第二,父進程判別法。調(diào)試器可以通過兩種方法對目標程序進行調(diào)試,一種是在目標程序運行后,附著在目標程序上對其進行跟蹤,另一種是首先運行調(diào)試器程序,繼而由調(diào)試器程序啟動目標程序,將目標程序作為調(diào)試器程序的子進程,進行跟蹤調(diào)試。子進程可以通過操作系統(tǒng)提供的函數(shù)來獲得父進程的PID(Process Identifier),這是該進程在系統(tǒng)中獨一無二的標識信息。通過PID,子進程還可以進一步獲得父進程的其他信息,如進程映像名稱。子進程可以將獲得的父進程映像名稱與流行的調(diào)試器映像名稱進行對比,從而判斷自己是否處于被調(diào)試器加載啟動的狀態(tài)。
在Android平臺中,一個進程可以通過函數(shù)getppid獲得其父進程的PID。如果該程序是由NDK編寫,那么該程序的父進程應該與該程序所在的APK包同名。如果程序判斷兩者不同,則程序極有可能是作為某種調(diào)試器的子進程,此時程序可以采取停止運行來對抗調(diào)試。
三 總結(jié)及展望
如何防止攻擊者對軟件進行破壞或盜版一直是信息安全領(lǐng)域的研究熱點,本文選擇Android應用作為研究目標,分析了Android應用開發(fā)的結(jié)構(gòu),闡述了幾種常見的Android應用保護技術(shù),對這些技術(shù)的特點和適用范圍進行了總結(jié)。利用這些技術(shù),開發(fā)人員可以不同程度地延緩或阻止攻擊者對應用的破解,保護自身的合法權(quán)益。
參考文獻
[1]史揚、曹立明、王小平.混淆算法研究綜述[J].同濟大學學報(自然科學版),2005(6)
[2]王一賓、陳意云.代碼迷惑技術(shù)研究進展[J].吉林大學學報(信息科學版),2008(4)
[3]羅宏、蔣劍琴、曾慶凱.用于軟件保護的代碼混淆技術(shù)[J].計算機工程,2006(11)
[4]王建民、余志偉、王朝坤等.Java程序混淆技術(shù)綜述[J].計算機學報,2011(9)
[5]趙躍華、郭玉杰.面向?qū)ο蟮目刂屏鬓D(zhuǎn)換方法[J].計算機工程與設計,2010(20)
[6]張鵬、牛少彰.Android平臺軟件保護技術(shù)[J].中國電子商情(通信市場),2014(1)
[7]張立和、楊義先、鈕心忻等.軟件水印綜述[J].軟件學報,2003(2)
[8]吳世忠、郭濤、董國偉等.軟件漏洞分析技術(shù)進展[J].清華大學學報(自然科學版),2012(10)
[9]王浩宇、王仲禹、郭耀等.基于代碼克隆檢測技術(shù)的Android應用重打包檢測[J].中國科學(信息科學),2014(1)
〔責任編輯:龐遠燕、汪二款〕