專利名稱:一種Android平臺軟件保護(hù)系統(tǒng)、方法及設(shè)備的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種計算機(jī)軟件保護(hù)技術(shù),特別是用于Android平臺的軟件防泄密和版權(quán)保護(hù)系統(tǒng)及方法、服務(wù)器和智能終端。
背景技術(shù):
目前,由Google公司主導(dǎo)開發(fā)的Android操作系統(tǒng)已經(jīng)是全球市場占有率最高的移動智能終端平臺。Android的應(yīng)用軟件數(shù)量不斷增長,并建立了良好的軟件銷售模式。與傳統(tǒng)PC平臺一樣,Android應(yīng)用軟件的成功商業(yè)化,也引發(fā)了對它們的逆向分析和破解。對應(yīng)用軟件的逆向分析(reversing analysis)包括
一、對軟件的可執(zhí)行代碼采用反匯編、反編譯、調(diào)試等方法進(jìn)行分析,以了解其代碼的 執(zhí)行流程和算法實現(xiàn)等;
二、對軟件的配置文件和數(shù)據(jù)文件進(jìn)行分析,以獲得這些文件的格式和語義等;
三、對軟件的網(wǎng)絡(luò)通信數(shù)據(jù)進(jìn)行分析,以獲得軟件與服務(wù)器通信的協(xié)議格式、協(xié)議語義、數(shù)據(jù)加密方法和數(shù)據(jù)具體含義等。其中,后兩類分析建立在第一類分析的基礎(chǔ)之上,即需要先分析可執(zhí)行代碼,才能進(jìn)一步分析配置文件、數(shù)據(jù)文件、網(wǎng)絡(luò)通信數(shù)據(jù)等。通過逆向分析,攻擊者可以獲得軟件中的商業(yè)機(jī)密。例如,在手機(jī)的反病毒軟件中,惡意代碼檢測算法、特征匹配算法等可執(zhí)行代碼,以及惡意代碼特征庫等數(shù)據(jù)文件,一旦被攻擊者逆向分析得到具體細(xì)節(jié),既可能被其他同類軟件所利用,也可能被惡意代碼作者進(jìn)行針對性防御或攻擊。再比如,在手機(jī)的網(wǎng)銀支付軟件中,通過網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)涉及用戶的身份認(rèn)證和金融賬戶信息,一旦軟件代碼、配置文件、網(wǎng)絡(luò)通信數(shù)據(jù)等被攻擊者通過逆向分析徹底了解,就有可能導(dǎo)致進(jìn)一步的惡意攻擊,對個人和銀行造成直接的經(jīng)濟(jì)損失。破解(cracking)是在逆向分析基礎(chǔ)上的一種具有專門目的的攻擊。商業(yè)軟件需要用戶付費后使用。對未付費用戶,一般不允許使用,或只能使用少量功能,或只能使用一段試用期。為了保障這一策略,商業(yè)軟件通常包含對用戶許可(License)和用戶身份的鑒別(以下將負(fù)責(zé)這一鑒別工作的代碼片段稱為“鑒權(quán)代碼”),以判斷用戶是否已經(jīng)付費。攻擊者通過對鑒權(quán)代碼的逆向分析,并進(jìn)一步篡改代碼執(zhí)行流程、篡改、復(fù)制或偽造相關(guān)配置文件、篡改網(wǎng)絡(luò)數(shù)據(jù)、修改內(nèi)存數(shù)據(jù)等,使未付費用戶也可以獲得付費用戶才擁有的功能。這種攻擊稱之為破解,它極大地?fù)p害了軟件開發(fā)者的經(jīng)濟(jì)權(quán)益,違反了知識產(chǎn)權(quán)保護(hù)的相關(guān)法律。Android平臺的應(yīng)用軟件開發(fā)一般采用Java語言。源代碼被編譯成Java類文件,再用Android SDKCSoftware Development Kit,軟件開發(fā)工具包)中的工具轉(zhuǎn)換為DEX格式的二進(jìn)制可執(zhí)行文件,最后與軟件配置、資源文件等一起打包成APK格式文件,即Android應(yīng)用軟件安裝包。用戶下載APK格式文件,并安裝到Android終端。應(yīng)用軟件運行時,DEX格式文件中的指令在Android系統(tǒng)中的Dalvik虛擬機(jī)之中執(zhí)行。Android是一個源代碼完全開放的操作系統(tǒng)。無論是DEX格式文件的指令編碼方法,還是Dalvik虛擬機(jī)的工作原理,都因為源碼公開而已經(jīng)被人們所知。目前已經(jīng)出現(xiàn)了針對DEX格式文件的各類逆向分析工具,包括反匯編工具smali、反編譯工具dex2jar,以及針對APK格式文件的apktool等自動化工具。此外,逆向分析和破解的技術(shù)在傳統(tǒng)PC平臺上已經(jīng)出現(xiàn)多年,Android平臺的攻擊者已經(jīng)借鑒了傳統(tǒng)的方法。在這些工具和方法的幫助下,目前攻擊者已經(jīng)可以輕易地對絕大部分Android應(yīng)用軟件進(jìn)行逆向分析和破解。例如,常見的破解流程是使用apktool解開APK文件,apktool會調(diào)用smali對其中的DEX格式文件進(jìn)行反匯編;攻擊者分析smali的反匯編結(jié)果,了解該應(yīng)用軟件的代碼流程;然后找到鑒權(quán)代碼,對關(guān)鍵的部分進(jìn)行修改,例如把鑒權(quán)時的條件跳轉(zhuǎn)指令改成無條件跳轉(zhuǎn)指令;再使用apktool將這些修改過的代碼重新打包成APK格式文件,并重新簽名。這樣就得到了一個破解后的APK文件。此外,Android應(yīng)用程序還可以使用NDK (Native Development Kit,原生開發(fā)工具包)開發(fā)。Android系統(tǒng)運行于Linux之上,每個應(yīng)用軟件所在的Dalvik虛擬機(jī)是一個獨立的Linux進(jìn)程。Android NDK提供了這樣一種開發(fā)方法程序員用C語言編寫軟件的 部分功能,由NDK的工具將源碼編譯為Linux中的動態(tài)鏈接文件(SO格式文件);用Java語言編寫其他功能,用SDK工具編譯為DEX格式文件;最后由SDK將SO格式文件和DEX格式文件一起打包為APK格式文件。在運行時,DEX中的代碼加載SO格式文件,并調(diào)用其提供的函數(shù)接口。NDK開發(fā)中的SO格式文件是Linux ELF格式標(biāo)準(zhǔn)的一種,其中的指令格式是ARM體系結(jié)構(gòu)的ARM指令集或Thumb指令集。目前有IDA Pro等反匯編工具和x86/ARMDecompiler等反編譯工具可以對這種文件進(jìn)行逆向分析。目前這一平臺防御逆向分析和破解方法包括
一、代碼混淆。即自動化地用等效但冗余復(fù)雜的代碼替換開發(fā)人員手寫的Java源代碼,提高攻擊者進(jìn)行逆向分析的工作量。二、更改字符串信息。在高質(zhì)量的Java源代碼中,包、類、方法、變量的名字往往具有較好的可讀性,即具有明確含義,因此可以通過名稱猜測其功能。DEX文件完整地保存了這些名字,為逆向分析提供了方便。但大部分名字只在應(yīng)用程序內(nèi)部使用,例如自定義的類。如果將這些名字替換為無意義的字符串,并不會影響程序的運行,但會使逆向分析陷入理解困難。Android SDK中的ProGuard工具就利用這種方法來保護(hù)軟件。三、使用NDK開發(fā)。如前所述,對SO文件的逆向分析涉及對ARM格式匯編語言的理解,一定程度上提高了對軟件代碼進(jìn)行逆向分析的難度。這些方法存在以下問題
1.無論是代碼還是加密后的數(shù)據(jù),都以文件形式長期存在于Android安裝文件和Android設(shè)備之中,攻擊者可以輕易地獲得;
2.通過代碼混淆,代碼依然可以被反匯編和反編譯,只是提高了理解代碼所需要的時
間;
3.通過更改字符串信息,代碼本身的邏輯并未發(fā)生改變,依然可以被反匯編和反編譯,同樣只是提高了理解代碼所需要的時間;
4.隨著攻擊者逐漸了解熟悉ARM格式匯編語言,并隨著該平臺反編譯工具的不斷成熟,采用NDK開發(fā)的方法所提高的逆向分析難度會越來越低。
理論上來說,應(yīng)用軟件在計算設(shè)備中的執(zhí)行最終都無法躲避被逆向分析。軟件保護(hù)的本質(zhì)是不斷提高逆向分析和破解的難度與時間成本,使攻擊者得到有價值信息需要付出的成本高于其所能獲得的利益。軟件保護(hù)會帶來額外的軟件開發(fā)成本,例如增加開發(fā)難度、延長開發(fā)時間等。因此,從是否需要特別保護(hù)的角度,邏輯上可以將應(yīng)用軟件的代碼分為兩部分
一、非核心代碼,不需要特別保護(hù),例如與用戶交互的界面、復(fù)用的第三方庫代碼等;
二、核心代碼,需要特別保護(hù),例如重要的算法、鑒權(quán)代碼、重要配置數(shù)據(jù)等。這兩個部分如何劃分,沒有通用的方法,由每個應(yīng)用軟件的實際情況決定。例如,在反病毒軟件中,惡意代碼檢測算法、特征匹配算法等都是核心模塊;在網(wǎng)銀軟件中,用戶登陸代碼、金融交易代碼等都是核心模塊;在收費商業(yè)軟件中,付費代碼、鑒權(quán)代碼等都是核心模塊。
·
本發(fā)明還涉及對Android系統(tǒng)中DEX文件動態(tài)加載技術(shù)的修改。通常情況下,Android應(yīng)用軟件中的DEX文件是在安裝時由系統(tǒng)保存在指定的位置。為了擴(kuò)展應(yīng)用軟件的能力,Android提供了 DEX文件動態(tài)加載技術(shù)。具體而言,應(yīng)用軟件在運行時,可以通過dalvik. system. DexClassLoader類加載一個之前沒有安裝的APK格式或JAR格式文件,并將該文件中所包含的名為“classes, dex”的DEX格式文件加載至Dalvik虛擬機(jī);進(jìn)一步地,可以通過該類的findClassO等方法,調(diào)用這個DEX格式文件中實現(xiàn)的代碼。 到目前為止的Android版本(從I. 0至4. 0),通過上述方法動態(tài)加載DEX格式文件存在下列要求包含了“classes, dex”的APK或JAR格式文件必須是一個物理文件,保存在設(shè)備內(nèi)置的NAND閃存或外置的SD卡中;動態(tài)加載時,系統(tǒng)會在設(shè)備內(nèi)置的NAND閃存或外置的SD卡中生成一個臨時文件,該文件是對DEX格式文件的優(yōu)化(擴(kuò)展名為.odex)。
發(fā)明內(nèi)容
針對以上技術(shù)問題,本發(fā)明主要公開了一種在Android系統(tǒng)中保護(hù)應(yīng)用軟件不受逆向分析和破解系統(tǒng)和方法。為Android系統(tǒng)中Dalvik虛擬機(jī)和Linux系統(tǒng)庫增加接口,使Android具有從內(nèi)存中直接加載DEX格式文件和SO格式文件的能力;將應(yīng)用軟件的核心代碼存儲在在線服務(wù)器中,加密并簽名后發(fā)送給安裝在客戶端的應(yīng)用軟件;應(yīng)用軟件接收到核心代碼后驗證簽名并解密,然后將明文存儲在內(nèi)存中,直接加載到系統(tǒng)中,然后調(diào)用其中的代碼,最后釋放內(nèi)存。該方法極大地增加了攻擊者進(jìn)行逆向分析和破解的難度,能有效保護(hù)Android應(yīng)用軟件的安全。本發(fā)明由三部分組成
1、修改過的Android操作系統(tǒng),實現(xiàn)DEX格式文件在內(nèi)存中的動態(tài)加載;
2、應(yīng)用軟件的非核心代碼,安裝在智能終端(包括手機(jī)、平板電腦等)中,且該智能終端使用上述修改過的Android操作系統(tǒng);
3、應(yīng)用軟件的核心代碼,存儲在長期在線的服務(wù)器中。首先,對Android操作系統(tǒng)的源代碼進(jìn)行修改。在Dalvik虛擬機(jī)上增加這樣的功能,使Dalvik虛擬機(jī)可以從指定的內(nèi)存地址直接加載一個DEX格式文件,并使得應(yīng)用程序可以通過其中代碼的包名、類名、方法名,調(diào)用這些代碼在Dalvik虛擬機(jī)中執(zhí)行。在Android底層的Linux上增加這樣的功能,使Linux可以從指定的內(nèi)存地址直接加載一個SO格式文件,并使得應(yīng)用程序可以通過其中代碼的API接口,調(diào)用這些代碼在Linux中執(zhí)行。應(yīng)用軟件的核心代碼是由Java源代碼經(jīng)過Android SDK中的工具編譯成的DEX格式文件,或者是由C源代碼經(jīng)過Android NDK中的工具編譯成的SO格式文件。存儲這些核心代碼的服務(wù)器接收智能終端中應(yīng)用軟件非核心代碼發(fā)來的請求,將其請求的核心代碼加密、進(jìn)行數(shù)字簽名,然后發(fā)送給智能終端中的應(yīng)用軟件。應(yīng)用軟件的非核心代碼位于完整的Android應(yīng)用程序(即APK格式文件)之中。軟件開發(fā)者將這一應(yīng)用程序公開分發(fā),用戶將其安裝至智能終端中。非核心代碼除了完成應(yīng)用軟件所需要的功能以外,還具備以下功能向服務(wù)器發(fā)送請求,接收發(fā)來的核心代碼,并驗證其數(shù)字簽名;申請一段內(nèi)存,將核心代碼解密至這段內(nèi)存;根據(jù)核心代碼是DEX格式還是SO格式,使Dalvik虛擬機(jī)或Linux從這段內(nèi)存中直接加載核心代碼,然后根據(jù)需要通過API接口調(diào)用核心代碼的功能;最后當(dāng)應(yīng)用軟件不再使用核心代碼時,釋放掉這一段內(nèi)存。
具體而言,本發(fā)明提供了一種Android平臺軟件保護(hù)系統(tǒng),包括智能終端和在線服務(wù)器
所述智能終端包括修改后的Android操作系統(tǒng)和應(yīng)用軟件的非核心代碼;所述修改后的Android操作系統(tǒng)對Android操作系統(tǒng)的源代碼進(jìn)行修改,實現(xiàn)應(yīng)用軟件的核心代碼在內(nèi)存中的動態(tài)加載;所述應(yīng)用軟件的非核心代碼在完整的Android應(yīng)用程序之中,具備應(yīng)用軟件所需要的功能以外的功能,包括向在線服務(wù)器發(fā)送請求,接收在線服務(wù)器發(fā)來的核心代碼,經(jīng)過驗證之后在內(nèi)存中加載應(yīng)用軟件的核心代碼,根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼;
在線服務(wù)器存儲應(yīng)用軟件的核心代碼,接收智能終端中應(yīng)用軟件非核心代碼發(fā)來的請求,將被請求的核心代碼經(jīng)過處理之后發(fā)送給智能終端中的應(yīng)用軟件非核心代碼。所述系統(tǒng)應(yīng)用軟件的核心代碼包括DEX格式文件和SO格式文件。所述系統(tǒng)的在線服務(wù)器存儲應(yīng)用軟件的核心代碼,接收智能終端中應(yīng)用軟件非核心代碼發(fā)來的請求,將部分或者全部被請求的核心代碼進(jìn)行加密和/或?qū)⒈徽埱蟮暮诵拇a進(jìn)行數(shù)字簽名之后發(fā)送給智能終端中的應(yīng)用軟件非核心代碼。本發(fā)明還提供了一種Android操作系統(tǒng)的源代碼修改方法,適用于所述的系統(tǒng),所述方法包括
對 Android 操作系統(tǒng)的 Dalvik 虛擬機(jī),擴(kuò)展 Android Framework 中 dalvik. system.DexClassLoader類的功能,擴(kuò)展后的dalvik. system. DexClassLoader類提供調(diào)用接口,接收內(nèi)存中的DEX格式文件,以加載DEX格式文件的方式加載所述的DEX格式文件;
在Android源碼中Linux內(nèi)核和系統(tǒng)庫的源碼部分增加一個接口,所述接口從指定的內(nèi)存地址加載SO格式文件;
編譯整個Android源碼工程,生成相應(yīng)的系統(tǒng)鏡像和開發(fā)工具。所述方法加載所述的DEX格式文件時產(chǎn)生的.odex臨時文件保存在內(nèi)存中。本發(fā)明還提供了一種Android平臺軟件保護(hù)方法,適用于所述的系統(tǒng),所述方法包括
在線服務(wù)器對存儲的部分或全部的應(yīng)用軟件的核心代碼進(jìn)行加密;在線服務(wù)器對存儲的應(yīng)用軟件的核心代碼進(jìn)行數(shù)字簽名;
將應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文發(fā)送給智能終端。本發(fā)明提供的一種服務(wù)器,所述服務(wù)器所述系統(tǒng)中的在線服務(wù)器,所述服務(wù)器包括
加密單元,用于對存儲的部分或全部的應(yīng)用軟件的核心代碼進(jìn)行加密;
數(shù)字簽名單元,用于對存儲的應(yīng)用軟件的核心代碼進(jìn)行數(shù)字簽名;
發(fā)送單元,用于將應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文發(fā)送給智能終端。本發(fā)明提供的一種Android平臺軟件保護(hù)方法,適用于所述的系統(tǒng),所述方法包括
智能終端接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密
文;
根據(jù)接收到的文件驗證數(shù)字簽名并解密得到應(yīng)用軟件的核心代碼文件;
將應(yīng)用軟件的核心代碼文件拷貝到內(nèi)存中,調(diào)用修改后的Android操作系統(tǒng)的接口完成核心代碼文件的加載;
根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼;
釋放掉存儲核心代碼的內(nèi)存。進(jìn)一步的,智能終端在接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文之前,向在線服務(wù)器發(fā)送需要應(yīng)用軟件核心代碼的請求。本發(fā)明提供了一種智能終端,所述智能終端為所述系統(tǒng)中的智能終端,所述智能終端包括修改后的Android操作系統(tǒng),還包括
接收單元,用于接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文;
驗證單元,用于根據(jù)接收到的文件驗證數(shù)字簽名并解密得到應(yīng)用軟件的核心代碼文
件;
加載單元,用于將應(yīng)用軟件的核心代碼文件拷貝到內(nèi)存中,調(diào)用修改后的Android操作系統(tǒng)的接口完成核心代碼文件的加載;
調(diào)用單元,用于根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼;
釋放單元,用于釋放掉存儲核心代碼的內(nèi)存。所述的智能終端還包括
發(fā)送單元,用于向在線服務(wù)器發(fā)送需要應(yīng)用軟件核心代碼的請求。本發(fā)明的有益效果是
其一,與現(xiàn)有的軟件保護(hù)方案相比,本發(fā)明所述方法使攻擊者極難獲得應(yīng)用軟件的核心代碼,因而無法對其進(jìn)行逆向分析。首先,公開分發(fā)的應(yīng)用軟件不包含核心代碼,攻擊者無法像以往從軟件市場或下載站點下載到應(yīng)用軟件,直接對其做靜態(tài)的反匯編就能看到所有代碼,要獲得這一部分代碼必須將該應(yīng)用軟件運行起來,使其連接服務(wù)器。其次,在服務(wù)器和智能終端上應(yīng)用軟件之間的通信完全采用加密和數(shù)字簽名,SP便攻擊者抓取了網(wǎng)絡(luò)通信數(shù)據(jù),在沒有密鑰的情況下,無法解出明文的核心代碼。使用數(shù)字簽名,也保證了攻擊者無法在這一過程中偽造出虛假的核心代碼,騙取應(yīng)用軟件加載。
最后,在智能終端的Android操作系統(tǒng)中,核心代碼始終只存在于內(nèi)存中,而且只在應(yīng)用軟件需要其中功能時存在于內(nèi)存中,而沒有以文件形式存在于設(shè)備內(nèi)置的NAND閃存或外置的SD卡中。目前,Android應(yīng)用程序所運行的Dalvik虛擬機(jī)位于獨立的Linux進(jìn)程上,且進(jìn)程權(quán)限為該應(yīng)用程序獨有的用戶創(chuàng)建,攻擊者難以讀取到核心代碼所在的虛擬內(nèi)存空間。即便攻擊者能夠讀到,由于存儲核心代碼的內(nèi)存空間是運行時動態(tài)分配的,考慮到Linux和Dalvik在內(nèi)存管理的復(fù)雜性,攻擊者也很難準(zhǔn)確找到核心代碼在內(nèi)存中具體哪個地址,以及這段內(nèi)存的實際長度。此外,目前的Linux內(nèi)核和Android 4. 0以后都開始采用ASLR (地址空間分布隨機(jī)化)技術(shù),這進(jìn)一步加大了攻擊者定位核心代碼內(nèi)存地址的的難度。再者,即便攻擊者最終獲得了核心代碼,對其逆向分析和修改后,也極難將其植入應(yīng)用軟件所在進(jìn)程的內(nèi)存空間中,更難以要求應(yīng)用程序加載這份被植入的內(nèi)存段(這涉及新的內(nèi)存分配、程序指令的動態(tài)修改等)。因此,無法對應(yīng)用軟件進(jìn)行破解。此外,本發(fā)明所述軟件保護(hù)技術(shù)與其他現(xiàn)有軟件保護(hù)技術(shù)的保護(hù)原理并不相同, 因此也不沖突,可以與現(xiàn)有其他保護(hù)技術(shù)共同使用,例如代碼混淆、更改字符串信息等。因此,這一方案可以與現(xiàn)有技術(shù)共同使用,更為全面地保護(hù)軟件安全。
為了更清楚地說明本發(fā)明或現(xiàn)有技術(shù)中的技術(shù)方案,下面將對實施例或現(xiàn)有技術(shù)描述中所需要使用的附圖作簡單地介紹,顯而易見地,下面描述中的附圖僅僅是本發(fā)明中記載的一些實施例,對于本領(lǐng)域普通技術(shù)人員來講,在不付出創(chuàng)造性勞動的前提下,還可以根據(jù)這些附圖獲得其他的附圖。圖I為本發(fā)明一種Android平臺軟件保護(hù)系統(tǒng)示意 圖2為本發(fā)明一種Android操作系統(tǒng)的源代碼修改方法流程 圖3為本發(fā)明在線服務(wù)器工作流程 圖4為本發(fā)明在線服務(wù)器系統(tǒng)示意 圖5為本發(fā)明智能終端工作流程 圖6為本發(fā)明智能終端系統(tǒng)示意圖。
具體實施例方式為了使本技術(shù)領(lǐng)域的人員更好地理解本發(fā)明實施例中的技術(shù)方案,并使本發(fā)明的上述目的、特征和優(yōu)點能夠更加明顯易懂,下面結(jié)合附圖對本發(fā)明中技術(shù)方案作進(jìn)一步詳細(xì)的說明。首先介紹本發(fā)明提供的一種Android平臺軟件保護(hù)系統(tǒng),如圖I所示,包括智能終端101和在線服務(wù)器102
所述智能終端101包括修改后的Android操作系統(tǒng)和應(yīng)用軟件的非核心代碼;所述修改后的Android操作系統(tǒng)對Android操作系統(tǒng)的源代碼進(jìn)行修改,實現(xiàn)應(yīng)用軟件的核心代碼在內(nèi)存中的動態(tài)加載;所述應(yīng)用軟件的非核心代碼在完整的Android應(yīng)用程序之中,具備應(yīng)用軟件所需要的功能以外的功能,包括向在線服務(wù)器102發(fā)送請求,接收在線服務(wù)器102發(fā)來的核心代碼,經(jīng)過驗證之后在內(nèi)存中加載應(yīng)用軟件的核心代碼,根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼;
在線服務(wù)器102存儲應(yīng)用軟件的核心代碼,接收智能終端101中應(yīng)用軟件非核心代碼發(fā)來的請求,將被請求的核心代碼經(jīng)過處理之后發(fā)送給智能終端101中的應(yīng)用軟件非核心代碼。應(yīng)用軟件的核心代碼包括DEX格式文件和SO格式文件。在線服務(wù)器102存儲應(yīng)用軟件的核心代碼,接收智能終端101中應(yīng)用軟件非核心代碼發(fā)來的請求,將部分或者全部被請求的核心代碼進(jìn)行加密和/或?qū)⒈徽埱蟮暮诵拇a進(jìn)行數(shù)字簽名之后發(fā)送給智能終端101中的應(yīng)用軟件非核心代碼。本發(fā)明包括修改Dalvik虛擬機(jī)和Linux系統(tǒng)的方法,主要流程如圖2所示。S201 :修改 Dalvik 虛擬機(jī) 修改Dalvik虛擬機(jī)的主要工作是,擴(kuò)展Android Framework中dalvik. system.DexClassLoader類的能力,使其接收內(nèi)存中一段DEX格式文件的數(shù)據(jù),以加載DEX格式文件的方式加載這段數(shù)據(jù),并提供與現(xiàn)有接口類似的調(diào)用其中代碼的接口。此外,從安全的角度考慮,還要使加載過程中產(chǎn)生的.odex臨時文件不存儲在設(shè)備內(nèi)置的NAND閃存或外置的SD卡中,而是也保存在內(nèi)存中。在Android 4. 0. l_rl版的源碼中,已經(jīng)實現(xiàn)了上述功能的一部分代碼。具體而言,在源碼的libcore/dalvik/src/main/java/dalvik/system/DexFile.java文件中,存在如下的 JNI 接口聲明native private static int openDexFile (byte []fileContents),該接口的功能是從內(nèi)存中的字節(jié)數(shù)組中讀取一個DEX格式文件。該JNI接口的函數(shù)實現(xiàn)位于源碼的 dalvik/vm/native/dalvik_system_DexFile. cpp 文件(第248 行),函數(shù)名是 Dalvik_dalvik_system_DexFile_openDexFile_bytearray,它調(diào)用了dvmRawDexFiIeOpenArray 函數(shù),后者的實現(xiàn)位于源碼的 dalvik/vm/RawDexFile. cpp 文件(第249行)。分析這兩個函數(shù)可知,它在構(gòu)造一個DEX格式文件結(jié)構(gòu)時,產(chǎn)生的.odex臨時文件也保存在了內(nèi)存里。接下來開始在源碼中增加一些代碼,以完成對Dalvik虛擬機(jī)的修改。在源碼的libcore/dalvik/src/main/java/dalvik/system/DexFile. java 文件中,為 DexFile類增加一個構(gòu)造函數(shù),原型為 private DexFile (byte [] fileContents, intflags),其代石馬與現(xiàn)有的private DexFile (String sourceName, String outputName, intflags)函數(shù)的代碼一樣,但其中的openDexFile調(diào)用使用前面所述的那個JNI接口。在源碼的libcore/dalvik/src/main/java/dalvik/system/DexFile. java 文件中,為 DexFile 類增加一個方法,原型為 static public DexFile IoadDex (byte []fileContents, int flags),其代碼與現(xiàn)有的IoadDex方法相似,區(qū)別是調(diào)用前面實現(xiàn)的這個DexFile構(gòu)造函數(shù)。在源碼的 libcore/dalvik/src/main/java/dalvik/system/DexPathList.java文件中,為DexPathList類增加一個方法,原型為private static DexFileIoadDexFile (byte [] fileContents),其實現(xiàn)代碼與現(xiàn)有IoadDexFile方法相似,但調(diào)用前面實現(xiàn)的DexFile類的IoadDex方法。在源碼的 libcore/dalvik/src/main/java/dalvik/system/DexPathList.java 文件中,為 DexPathList 類增加一個方法,原型為 private static Element[]makeDexElements (byte [] fileContents),其實現(xiàn)代碼與現(xiàn)有的 makeDexElements 方法相似,但在第207行的if■語句中只進(jìn)入第一條分支,并調(diào)用前面實現(xiàn)的DexPathList類的IoadDexFile 方法。在源碼的libcore/dalvik/src/ main/java/dalvik/system/DexPathList. java文件中,為DexPathList類增加一個構(gòu)造函數(shù),原型為public DexPathList (ClassLoaderdefiningContext, byte[] fileContents),其實現(xiàn)代碼與現(xiàn)有構(gòu)造函數(shù)相似,但調(diào)用前面實現(xiàn)的 DexPathList 類的 makeDexElements 方法。在源碼的Iib core/dalvik/src/main/java/dalvik/system/BaseDexClassLoader. java文件中,為BaseDexClassLoader類增加一個構(gòu)造函數(shù),原型為public BaseDexClassLoader (byte [] fileContents),其實現(xiàn)代碼與現(xiàn)有構(gòu)造函數(shù)相似,但調(diào)用前面實現(xiàn)的DexPathList類的構(gòu)造函數(shù)。在源碼的libcore/dalvik/src/ main/java/dalvik/system/DexClassLoader. java文件中,為DexClassLoader類增加一個構(gòu)造函數(shù),原型為publicDexClassLoader (byte[] fileContents),其實現(xiàn)代碼與現(xiàn)有構(gòu)造函數(shù)一樣,但調(diào)用前面實現(xiàn)的BaseDexClassLoader類的構(gòu)造函數(shù)。至此,我們得到了符合本發(fā)明所要求的修改后的Dalvik虛擬機(jī)源代碼。S202 :修改 Linux 系統(tǒng)修改Linux系統(tǒng)的主要目的是,在Android源碼工程中的Linux內(nèi)核和系統(tǒng)庫部分增加部分代碼,使其增加一個接口,該接口的主要功能是從指定的內(nèi)存地址加載一段SO格式文件的數(shù)據(jù)。這一工作目前在業(yè)界已有多種方法實現(xiàn)。例如,在glibc中增加一個dlopen_mem()的系統(tǒng)調(diào)用,原型為 void *dlopen_mem (char *addr, size_t len, int flag),其實現(xiàn)代碼是在glibc標(biāo)準(zhǔn)庫中現(xiàn)有dlopenO系統(tǒng)調(diào)用的源碼基礎(chǔ)上修改而成。具體而言,dlopen ()的第一個參數(shù)是要打開的SO格式文件的磁盤路徑,它會打開這個文件并將其全部內(nèi)容讀取出來。在dlopen_mem()的實現(xiàn)中,直接從參數(shù)addr和Ien讀取數(shù)據(jù),然后繼續(xù)執(zhí)行dlopenO的后續(xù)代碼即可。至此,我們得到了符合本發(fā)明所要求的修改后的Linux系統(tǒng)源代碼。S203 :編譯 Android 工程
采用常規(guī)方法將整個Android源碼工程編譯,生成相應(yīng)的系統(tǒng)鏡像、SDK開發(fā)工具、NDK開發(fā)工具。這樣,在得到的SDK開發(fā)工具中,就可以使用新增的DexClassLoader (byte口fileContents)接口,從內(nèi)存中動態(tài)加載DEX格式文件;在得到的NDK開發(fā)工具中,就可以使用新增的dlopenjnemO系統(tǒng)調(diào)用,從內(nèi)存中動態(tài)加載SO格式文件;在新的系統(tǒng)鏡像中,使用了上述接口和系統(tǒng)調(diào)用的應(yīng)用軟件就可以正常運行。本發(fā)明還提供了存儲核心代碼的在線服務(wù)器的工作流程,如圖3所示,包括
S301 :加密核心代碼
核心代碼以DEX格式文件或SO格式文件的形式存在,對核心代碼的全部或一部分采用通用的密碼學(xué)算法進(jìn)行加密,以保證其在傳輸過程中的保密性??梢允褂脤ΨQ加密,也可以使用非對稱加密。
例如,選擇對稱加密算法AES,使用的密鑰記為akey,對核心代碼所在的文件file進(jìn)行加密,得到加密后的文件file_enc。再選擇一個非對稱加密算法,例如RSA,將使用的公鑰記為rkey_pub,私鑰記為rkey_pri。使用私鑰rkey_pri對AES密鑰akey加密,得到akey的密文akey_enc。在這里,RSA算法使用的公鑰和私鑰在事先就生成,并將公鑰rkey_pub編寫到相應(yīng)的客戶端應(yīng)用軟件中。S302 :簽名核心代碼
對核心代碼采用通用的數(shù)字簽名算法進(jìn)行簽名,以保證文件的完整性。例如,采用一種最經(jīng)典的數(shù)字簽名方法。使用哈希算法SHAl對核心代碼所在文件密文file_enc進(jìn)行數(shù)字摘要,得到一個哈希值hvalue。 使用RSA算法以及上述私鑰rkey_pri對這個哈希值hvalue進(jìn)行加密,得到密文hvalue_enc。S303 :發(fā)送給客戶端
將核心代碼所在文件密文file_enc、AES算法所用密鑰的密文akey_enc、哈希值的密文hvalue_enc, —同發(fā)送給客戶端。相應(yīng)的,本發(fā)明還提供了一種服務(wù)器,如圖4所示,所述服務(wù)器為所述系統(tǒng)中的在線服務(wù)器102,所述服務(wù)器包括
加密單元401,用于對存儲的部分或全部的應(yīng)用軟件的核心代碼進(jìn)行加密;
數(shù)字簽名單元402,用于對存儲的應(yīng)用軟件的核心代碼進(jìn)行數(shù)字簽名;
發(fā)送單元403,用于將應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文發(fā)送給智能終端。本發(fā)明還提供了應(yīng)用軟件中非核心代碼的工作流程,在安裝到客戶端的應(yīng)用軟件中,包含了非核心的代碼。這些代碼可以分為兩部分一、與該軟件具體應(yīng)用相關(guān)的代碼;二、負(fù)責(zé)加載核心代碼的代碼。本發(fā)明只涉及后一部分代碼,下面給出其主要工作流程和實現(xiàn)方法。如圖5所示,包括
S501 :從服務(wù)器接收S303發(fā)送給客戶端的file_enc、akey_enc、hvalue_enc。S502 :驗證數(shù)字簽名,以保證文件的完整性。例如,對S302中所述的簽名方法,首先用事先選擇并編寫到應(yīng)用軟件的RSA公鑰rkey_pub,解密 hvalue_enc,得到哈希值 hvalue。接下來,用SHAl算法對發(fā)送來的file_enc進(jìn)行數(shù)字摘要,得到另一個哈希值hvalue2,比較hvalue和hvalue2是否完全相同。若不相同,則認(rèn)為接收到的核心代碼是不完整的,有可能被篡改,報告異常并退出軟件。若相同,則認(rèn)為接收到的核心代碼是完整的,進(jìn)入下一步。S503 :用 RSA 公鑰 rkey_pub 解密 akey_enc,得到 AES 算法密鑰 akey。用 AES 算法,以akey作為密鑰,解密file_enc,得到核心代碼所在文件file的完整內(nèi)容。S504 :根據(jù)核心代碼所在文件是DEX格式還是SO格式,在Java中或者C中申請該文件大小的內(nèi)存,并將文件內(nèi)容拷貝至其中。具體而言,若文件是DEX格式,貝U采用Java語言中的byte數(shù)組記錄內(nèi)存地址,通過new方法申請內(nèi)存,使用System, arraycopy方法拷貝;若文件是SO格式,則在NDK中使用C語言的char *指針記錄內(nèi)存地址,通過malIoc函數(shù)申請內(nèi)存,使用memcpy函數(shù)拷貝,使用int型變量記錄數(shù)據(jù)長度。S505 :調(diào)用此前修改Dalvik虛擬機(jī)和Linux系統(tǒng)得到的新的函數(shù)接口,從前一步的內(nèi)存中直接加載核心代碼。若文件是DEX 格式,則調(diào)用 S201 中得到的 public DexClassLoader (byte []fileContents)構(gòu)造函數(shù),將內(nèi)存地址作為參數(shù),得到一個DexClassLoader對象,即完成了DEX格式對象的動態(tài)加載;
若文件是SO格式,則調(diào)用 S202 中得到的 void *dlopen_mem(char *addr, size_t len,int flag)系統(tǒng)調(diào)用,其參數(shù)addr為S504中得到的內(nèi)存地址,參數(shù)len為S504中記錄的數(shù)據(jù)長度,參數(shù)flag為0,得到一個void *型的句柄,即完成了 SO格式對象的動態(tài)加載。 S506:根據(jù)應(yīng)用軟件的具體需求,調(diào)用核心代碼中的類、方法、函數(shù)等。若文件是DEX格式,則使用S505中得到的DexClassLoader對象的IoadClassO方法,根據(jù)核心代碼中Java類的名稱得到該類的Class對象;進(jìn)一步,使用該Class對象的getDeclaredMethod方法,根據(jù)核心代碼中的Java類的方法的名稱,得到該類中的方法的Method對象?,F(xiàn)在,就可以調(diào)用這個Method對象的invoke方法,來調(diào)用該方法了。若文件是SO格式,則使用S505中得到的void *型的句柄,根據(jù)核心代碼中C語言函數(shù)的名稱,通過dlsymO系統(tǒng)調(diào)用,得到這個函數(shù)的指針。現(xiàn)在,就可以直接調(diào)用這個函數(shù)指針,來運行其中實現(xiàn)的代碼了。S507 :但應(yīng)用軟件不再需要使用核心代碼時,釋放掉存儲了核心代碼的內(nèi)存。當(dāng)核心代碼所在文件是DEX格式,則調(diào)用Java語言中byte[]對象的delete方法;當(dāng)文件是SO格式,則調(diào)用C語言中的free方法。相應(yīng)的,本發(fā)明還提供了一種智能終端,所述智能終端為所述系統(tǒng)中的智能終端101,所述智能終端101包括修改后的Android操作系統(tǒng),還包括
接收單元601,用于接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文;
驗證單元602,用于根據(jù)接收到的文件驗證數(shù)字簽名并解密得到應(yīng)用軟件的核心代碼文件;
加載單元603,用于將應(yīng)用軟件的核心代碼文件拷貝到內(nèi)存中,調(diào)用修改后的Android操作系統(tǒng)的接口完成核心代碼文件的加載;
調(diào)用單元604,用于根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼;
釋放單元605,用于釋放掉存儲核心代碼的內(nèi)存。所述的智能終端101,還包括
發(fā)送單元600,用于向在線服務(wù)器發(fā)送需要應(yīng)用軟件核心代碼的請求。本說明書中方法的實施例采用遞進(jìn)的方式描述,對于系統(tǒng)的實施例而言,由于其基本相似于方法實施例,所以描述的比較簡單,相關(guān)之處參見方法實施例的部分說明即可。雖然通過實施例描繪了本發(fā)明,本領(lǐng)域普通技術(shù)人員知道,本發(fā)明有許多變形和變化而不脫離本發(fā)明的精神,希望所附的權(quán)利要求包括這些變形和變化而不脫離本發(fā)明的精神。
權(quán)利要求
1.一種Android平臺軟件保護(hù)系統(tǒng),其特征在于,包括智能終端和在線服務(wù)器 所述智能終端包括修改后的Android操作系統(tǒng)和應(yīng)用軟件的非核心代碼;所述修改后的Android操作系統(tǒng)對Android操作系統(tǒng)的源代碼進(jìn)行修改,實現(xiàn)應(yīng)用軟件的核心代碼在內(nèi)存中的動態(tài)加載;所述應(yīng)用軟件的非核心代碼在完整的Android應(yīng)用程序之中,具備應(yīng)用軟件所需要的功能以外的功能,包括向在線服務(wù)器發(fā)送請求,接收在線服務(wù)器發(fā)來的核心代碼,經(jīng)過驗證之后在內(nèi)存中加載應(yīng)用軟件的核心代碼,根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼; 在線服務(wù)器存儲應(yīng)用軟件的核心代碼,接收智能終端中應(yīng)用軟件非核心代碼發(fā)來的請求,將被請求的核心代碼經(jīng)過處理之后發(fā)送給智能終端中的應(yīng)用軟件非核心代碼。
2.如權(quán)利要求I所述的Android平臺軟件保護(hù)系統(tǒng),其特征在于,應(yīng)用軟件的核心代碼包括DEX格式文件和SO格式文件。
3.如權(quán)利要求I所述的Android平臺軟件保護(hù)系統(tǒng),其特征在于,在線服務(wù)器存儲應(yīng)用軟件的核心代碼,接收智能終端中應(yīng)用軟件非核心代碼發(fā)來的請求,將部分或者全部被請求的核心代碼進(jìn)行加密和/或?qū)⒈徽埱蟮暮诵拇a進(jìn)行數(shù)字簽名之后發(fā)送給智能終端中的應(yīng)用軟件非核心代碼。
4.一種Android操作系統(tǒng)的源代碼修改方法,其特征在于,適用于權(quán)利要求I所述的系統(tǒng),所述方法包括 對 Android 操作系統(tǒng)的 Dalvik 虛擬機(jī),擴(kuò)展 Android Framework 中 dalvik. system.DexClassLoader類的功能,擴(kuò)展后的dalvik. system. DexClassLoader類提供調(diào)用接口,接收內(nèi)存中的DEX格式文件,以加載DEX格式文件的方式加載所述的DEX格式文件; 在Android源碼中Linux內(nèi)核和系統(tǒng)庫的源碼部分增加一個接口,所述接口從指定的內(nèi)存地址加載SO格式文件; 編譯整個Android源碼工程,生成相應(yīng)的系統(tǒng)鏡像和開發(fā)工具。
5.如權(quán)利要求4所述的Android操作系統(tǒng)的源代碼修改方法,其特征在于,加載所述的DEX格式文件時產(chǎn)生的.odex臨時文件保存在內(nèi)存中。
6.一種Android平臺軟件保護(hù)方法,其特征在于,適用于權(quán)利要求I所述的系統(tǒng),所述方法包括 在線服務(wù)器對存儲的部分或全部的應(yīng)用軟件的核心代碼進(jìn)行加密; 在線服務(wù)器對存儲的應(yīng)用軟件的核心代碼進(jìn)行數(shù)字簽名; 將應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文發(fā)送給智能終端。
7.一種服務(wù)器,其特征在于,所述服務(wù)器為權(quán)利要求I所述系統(tǒng)中的在線服務(wù)器,所述服務(wù)器包括 加密單元,用于對存儲的部分或全部的應(yīng)用軟件的核心代碼進(jìn)行加密; 數(shù)字簽名單元,用于對存儲的應(yīng)用軟件的核心代碼進(jìn)行數(shù)字簽名; 發(fā)送單元,用于將應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文發(fā)送給智能終端。
8.—種Android平臺軟件保護(hù)方法,其特征在于,適用于權(quán)利要求I所述的系統(tǒng),所述方法包括 智能終端接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文;根據(jù)接收到的文件驗證數(shù)字簽名并解密得到應(yīng)用軟件的核心代碼文件; 將應(yīng)用軟件的核心代碼文件拷貝到內(nèi)存中,調(diào)用修改后的Android操作系統(tǒng)的接口完成核心代碼文件的加載; 根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼; 釋放掉存儲核心代碼的內(nèi)存。
9.如權(quán)利要求8所述的Android平臺軟件保護(hù)方法,其特征在于,智能終端在接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文之前,向在線服務(wù)器發(fā)送需要應(yīng)用軟件核心代碼的請求。
10.一種智能終端,其特征在于所述智能終端為權(quán)利要求I所述系統(tǒng)中的智能終端,所述智能終端包括修改后的Android操作系統(tǒng),還包括 接收單元,用于接收在線服務(wù)器發(fā)送來的應(yīng)用軟件的核心代碼所在的文件以及相應(yīng)的密文; 驗證單元,用于根據(jù)接收到的文件驗證數(shù)字簽名并解密得到應(yīng)用軟件的核心代碼文件; 加載單元,用于將應(yīng)用軟件的核心代碼文件拷貝到內(nèi)存中,調(diào)用修改后的Android操作系統(tǒng)的接口完成核心代碼文件的加載; 調(diào)用單元,用于根據(jù)需要通過API接口調(diào)用應(yīng)用軟件的核心代碼; 釋放單元,用于釋放掉存儲核心代碼的內(nèi)存。
11.如權(quán)利要求10所述的智能終端,其特征在于,還包括 發(fā)送單元,用于向在線服務(wù)器發(fā)送需要應(yīng)用軟件核心代碼的請求。
全文摘要
本發(fā)明主要公開了一種在Android系統(tǒng)中保護(hù)應(yīng)用軟件不受逆向分析和破解系統(tǒng)和方法。主要方法是為Android系統(tǒng)中Dalvik虛擬機(jī)和Linux系統(tǒng)庫增加接口,使Android具有從內(nèi)存中直接加載DEX格式文件和SO格式文件的能力;將應(yīng)用軟件的核心代碼存儲在在線服務(wù)器中,加密并簽名后發(fā)送給安裝在客戶端的應(yīng)用軟件;應(yīng)用軟件接收到核心代碼后驗證簽名并解密,然后將明文存儲在內(nèi)存中,直接加載到系統(tǒng)中,然后調(diào)用其中的代碼,最后釋放內(nèi)存。該方法極大地增加了攻擊者進(jìn)行逆向分析和破解的難度,能有效保護(hù)Android應(yīng)用軟件的安全。
文檔編號G06F21/22GK102760219SQ20111042966
公開日2012年10月31日 申請日期2011年12月20日 優(yōu)先權(quán)日2011年12月20日
發(fā)明者李柏松, 肖梓航 申請人:北京安天電子設(shè)備有限公司