專利名稱:安卓系統(tǒng)中java應(yīng)用程序的保護(hù)方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計算機(jī)安全領(lǐng)域,特別是一種保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法。通過將待保護(hù)的JAVA類對象的若干方法指令代碼進(jìn)行加密變換,在程序運行時根據(jù)調(diào)用需求對加密的方法代碼進(jìn)行實時的解密運行,使得應(yīng)用程序難以進(jìn)行反編譯和靜態(tài)分析,實現(xiàn)了對JAVA程序的有效保護(hù)。
背景技術(shù):
安卓系統(tǒng)(Android)是一種以Linux為基礎(chǔ)的開放源碼操作系統(tǒng),主要使用于便攜設(shè)備。安卓系統(tǒng)是當(dāng)前手機(jī)和平板電腦等移動設(shè)備中使用的主流操作系統(tǒng)之一。安卓系統(tǒng)中的應(yīng)用程序通常是用JAVA語言編寫,編譯生成JAVA程序文件安裝后運行。由于JAVA屬于中間語言,其編譯后的可執(zhí)行文件中包含大量源代碼的結(jié)構(gòu)和設(shè)計 信息,加之安卓系統(tǒng)是基于Linux的操作系統(tǒng),其開放性和豐富的各種程序分析工具,使得JAVA程序很容易被反編譯和靜態(tài)分析,因此安卓系統(tǒng)中對應(yīng)用程序的版權(quán)保護(hù)非常薄弱。應(yīng)用程序的安裝文件很易于復(fù)制和傳播,盜版者可以很方便的在網(wǎng)絡(luò)上獲得并在其它未授權(quán)的設(shè)備中安裝使用。即使開發(fā)者在應(yīng)用程序中實現(xiàn)了一些軟件保護(hù)手段,諸如對硬件設(shè)備或用戶身份的驗證和功能綁定,但盜版者仍可以很容易分析應(yīng)用程序的運行邏輯,繞開或去除程序中的相應(yīng)保護(hù)功能,生成可以自由使用的破解版本。目前常見的一種保護(hù)方法是采用“加殼”的方式,即將應(yīng)用程序的全部或部分指令進(jìn)行加密或其它方式的變換,運行時用一個脫殼程序?qū)ζ溥M(jìn)行反變換后加載到內(nèi)存中執(zhí)行。在脫殼程序中加入一些控制保護(hù)措施,例如對用戶身份的認(rèn)證,應(yīng)用程序的完整性校驗等。這種方法雖然可以防止對應(yīng)用程序直接的反編譯,但其“脫殼操作”是一次性操作,“脫殼”后程序的所有指令代碼都在內(nèi)存中,破解者可以很方便的在程序被脫殼加載后保存下內(nèi)存數(shù)據(jù),還原原始程序;另外,脫殼程序的功能邏輯是固定的,易于被解密者分析破解,因此這種加殼的方式對應(yīng)用軟件的保護(hù)能力不強(qiáng)。由于以上原因,目前安卓系統(tǒng)的軟件盜版現(xiàn)象十分嚴(yán)重,付費軟件的權(quán)益無法得到保障,導(dǎo)致很多在ios系統(tǒng)中很成功的軟件放棄安卓系統(tǒng)或者將軟件在安卓系統(tǒng)中以免費加廣告的形式發(fā)布??梢姡琂AVA程序的保護(hù)機(jī)制缺失嚴(yán)重制約了安卓系統(tǒng)中的軟件市場的發(fā)展。
發(fā)明內(nèi)容
為了克服現(xiàn)有技術(shù)中JAVA應(yīng)用程序缺乏安全保護(hù)機(jī)制的弊端,本發(fā)明提供了一種對安卓系統(tǒng)中JAVA應(yīng)用程序進(jìn)行保護(hù)的方法,通過將待保護(hù)的JAVA類對象的若干方法指令代碼進(jìn)行變換存儲,在程序運行時根據(jù)調(diào)用需求對加密的方法代碼進(jìn)行實時的解密運行,使得應(yīng)用程序難以被反編譯和靜態(tài)分析,實現(xiàn)了對JAVA應(yīng)用程序的有效保護(hù)。在JAVA語言中,類對象的方法函數(shù)有兩種類型普通方法和本地方法。普通方法是由JAVA語言編寫編譯成JAVA指令代碼,運行時由JAVA虛擬機(jī)(JAVA Virtual Machine,JVM)執(zhí)行;另一類本地方法(Native Method),它是通過 JNI( JAVA Native Interface, JAVA本地調(diào)用)的接口訪問外部的運行在本地操作系統(tǒng)的庫。JNI實現(xiàn)了 JAVA程序和外部庫之間的相互調(diào)用,通常用來為JAVA程序提供非JAVA語言實現(xiàn)的功能。本發(fā)明將某個由JAVA語言實現(xiàn)的類對象的方法數(shù)據(jù)內(nèi)容進(jìn)行加密,并將其改為對特定的JNI保護(hù)函數(shù)接口的調(diào)用,在該JNI保護(hù)函數(shù)接口中將解密還原原始的指令代碼,然后再對已還原的原始指令代碼進(jìn)行調(diào)用。保護(hù)JAVA應(yīng)用程序的步驟是
1.在JAVA程序文件中定位待保護(hù)的功能單元(比如,待保護(hù)的類對象的某個普通方法,用于實現(xiàn)特定功能),將其更改為本地方法;
2.為該類對象創(chuàng)建一個新的普通方法(即對應(yīng)于功能單元的副本單元),該新的普通方法是上述被保護(hù)的普通方法的副本方法,令新的普通方法的指令代碼空間與被保護(hù)的普通方法的指令代碼空間相等,并將新的普通方法的指令代碼空間全部填充為空指令;
3.生成一個JNI庫(JAVA本地調(diào)用庫),導(dǎo)出被保護(hù)的普通方法的接口。將被保護(hù)的普通方法的原始指令代碼加密后存儲在JNI庫的資源中。4.擦除被保護(hù)的普通方法的原始指令代碼。對于其它需要保護(hù)的方法,執(zhí)行上述相同的步驟。執(zhí)行被保護(hù)的JAVA應(yīng)用程序,當(dāng)調(diào)用被保護(hù)的普通方法時,由于被保護(hù)的普通方法已被更改為本地方法,因此JVM會調(diào)用JNI庫中的被保護(hù)的普通方法的接口,此時,在JNI庫中執(zhí)行以下步驟
1.從JNI庫的資源中找到被保護(hù)的普通方法的加密數(shù)據(jù),將該數(shù)據(jù)解密后,填回到副本方法的指令代碼空間中;
2.調(diào)用、執(zhí)行副本方法;
3.擦除副本方法的指令代碼空間中的指令代碼,即將副本方法整個擦除;
4.返回被保護(hù)的普通方法的調(diào)用。上述加密過程中所使用的密鑰,可以由被保護(hù)的JAVA應(yīng)用程序的信息生成,使得每個JAVA應(yīng)用程序所使用的密鑰不同;比如,所述信息包括但不限于軟件基本信息,APPID,版本號等。也可以將由被保護(hù)的JAVA應(yīng)用程序的信息和被授權(quán)使用該JAVA應(yīng)用程序的用戶的信息組合后生成密鑰,使得每個用戶的安裝程序不同,防止了安裝程序的非授權(quán)復(fù)制使用。如,用戶信息包括但不限于用戶103 10、版本號、瓜0。上述的加密方法,可以采用各種對稱或非對稱算法,比如,對稱算法包括但不限于AES、DES、TDES等;非對稱算法包括但不限于RSA、ECC)??梢允枪_的或私有的加密算法,也可以是其它的數(shù)據(jù)變換與反變換方法,比如,對代碼數(shù)據(jù)字節(jié)進(jìn)行特定的變換轉(zhuǎn)換成其他字節(jié)碼或加密數(shù)據(jù),反變換采用相同規(guī)則獲取原始數(shù)據(jù)。上述加密和解密執(zhí)行過程中可以進(jìn)一步采用一些方法,增加反編譯和靜態(tài)分析,或動態(tài)調(diào)試的難度,方法包括
I.采用自定義的非標(biāo)準(zhǔn)JAVA程序文件格式。比如,可自行定義文件格式,比如.sense或其他格式,將內(nèi)容存儲至該文件內(nèi),然后使用時使用自己創(chuàng)建的加載器來加載此格式的文件。文件存儲加載可采用加密或定義的格式方式,因為采用此種文件格式,一般人不知道文件格式,不知如何加載,從而增加反編譯難度。2.去除某些不影響程序運行的源程序的信息(比如變量名)。例如,去除相關(guān)內(nèi)部變量名,或者內(nèi)部一些邏輯代碼(例如switch等)進(jìn)行混淆或者去除。當(dāng)反編譯時,運行到此邏輯部分就中斷無法進(jìn)行下去,增加復(fù)雜性。3.運行JAVA應(yīng)用程序時使用反調(diào)試技術(shù),當(dāng)JAVA應(yīng)用程序監(jiān)測到調(diào)試器正在對本程序進(jìn)行調(diào)試時,停止解密和加載運行過程。反調(diào)試技術(shù)是在JAVA應(yīng)用程序代碼里加入監(jiān)測是否有調(diào)試器調(diào)試的相關(guān)代碼,在運行JAVA應(yīng)用程序時,代碼中的反調(diào)試代碼會監(jiān)測是否存在調(diào)試器調(diào)試,如果有,則停止解密和加載運行過程??稍谌魏芜^程中進(jìn)行反調(diào)試。當(dāng)監(jiān)測到調(diào)試器正在對本程序進(jìn)行調(diào)試時,會停止解密和加載運行過程,停止后無法調(diào)試,增加了調(diào)試的難度,當(dāng)然也就進(jìn)一步提高了反編譯的難度。
本發(fā)明可以對任意的類對象的多個方法進(jìn)行加密保護(hù),在程序運行時只在被保護(hù)的普通方法被調(diào)用時才被動態(tài)地解密和加載執(zhí)行,并調(diào)用完成后立即擦除其副本方法的指令代碼空間中的指令代碼(擦除整個副本方法內(nèi)容,即擦除其副本方法的指令代碼),內(nèi)存中始終不存在完整的程序代碼,因此破解者很難恢復(fù)出程序文件進(jìn)行反編譯和靜態(tài)分析,防止了 JAVA應(yīng)用程序被盜版的問題。
圖I為本發(fā)明中加密受保護(hù)的方法的流程圖。圖2為本發(fā)明中執(zhí)行調(diào)用受保護(hù)方法的流程圖。
具體實施例方式
下面通過實例說明本發(fā)明的具體實施方式
。例如要保護(hù)類ClassA的普通方法M (即實現(xiàn)特定功能的功能單元),根據(jù)本發(fā)明的一個實施例,進(jìn)行以下步驟
I.在JAVA程序文件(源文件)中定位ClassA. M。根據(jù)本發(fā)明的一個具體實施方式
,定位就是先找到ClassA類,然后在ClassA中找到M方法。通過代碼形式定位則為ClassAtest=new ClassAO ; test. M方法即可獲得。將方法ClassA. M (即要保護(hù)的類ClassA的普通方法M)更改為本地方法。通過關(guān)鍵字native將普通方法更改為本地方法,更改后即為本地方法。2.為類ClassA創(chuàng)建一個新的普通方法M1(M1即對應(yīng)于上述功能單元M的副本單元)。根據(jù)本發(fā)明的一個實施例,在類ClassA的類代碼內(nèi)創(chuàng)建,通過代碼生成一個普通方法Ml。令新的普通方法Ml的指令代碼空間與ClassA. M的指令代碼空間相等。根據(jù)本發(fā)明的一個實施例,根據(jù)M方法的代碼內(nèi)容來計算該方法占有多少空間,通過計算得出M方法的代碼空間具體大小,在生成新的普通方法Ml時,就設(shè)置Ml的大小為上述M的大小。然后將Ml的指令空間全部填充為空指令。根據(jù)本發(fā)明的一個實施例,該Ml為空方法,只包含方法的聲明,方法體內(nèi)不包含代碼,方法體的代碼空間與M指令代碼空間大小一致。3.生成一個JNI庫,導(dǎo)出ClassA. M接口。具體而言,
根據(jù)本發(fā)明的一個具體實施例,生成JNI的步驟包括(I)編寫JAVA代碼,注明要訪問的本地動態(tài)連接庫和本地接口方法;(2)使用javac命令編譯所編寫的java類,使用(javah -jni java類名)生成擴(kuò)展名為h的頭文件;(3)使用c/c++實現(xiàn)(2)中生成的.h文件中聲明的各函數(shù);(4)編譯c/c++實現(xiàn)代碼生成動態(tài)連接庫(dll/so文件);(5)生成jar包供調(diào)用;定義接口等都包含在上述步驟中。根據(jù)本發(fā)明的一個具體實施例,導(dǎo)出ClassA. M接口即是上述生成JNI步驟中的用c/c++實現(xiàn)步驟2中生成的.h文件中聲明的各函數(shù),ClassA. M的接口名稱格式為JAVA_再加上java程序的package路徑再加函數(shù)名組成。4.將ClassA. M中的原始指令代碼加密后存儲在JNI庫的資源中。加密方法可以是對稱或非對稱加密算法,可以是公開或私有的加密算法,也可以是其它的數(shù)據(jù)變換與反變換方法。此外,將ClassA. M的原始指令代碼通過上述加密方式加密存儲至JNI庫的資源中,例如對代碼的字節(jié)進(jìn)行加密然后將加密后的字符串存放在資源中,當(dāng)需解密時,根據(jù)相同規(guī)則解密出資源的加密內(nèi)容。5.擦除ClassA. M的指令代碼,即刪除ClassA. M方法的指令代碼。 對于其它需要保護(hù)的方法,執(zhí)行上述相同的步驟。執(zhí)行被保護(hù)的JAVA應(yīng)用程序,當(dāng)調(diào)用其中的普通方法ClassA. M時,由于ClassA.M以及被修改為本地方法,因此JVM會調(diào)用JNI庫中的ClassA. M接口,在JNI庫中執(zhí)行以下步驟
1.從JNI庫的資源中找到ClassA.M的加密數(shù)據(jù)(加密時,存儲的資源位置會變成已知位置,根據(jù)此位置即可找到加密數(shù)據(jù)),對加密數(shù)據(jù)進(jìn)行解密。然后將解密后的數(shù)據(jù)填回。具體而言,數(shù)據(jù)填回的方式為找到ClassA. Ml的方法位置,然后將解密數(shù)據(jù)寫入ClassA. Ml的指令代碼空間中;
2.JAVA應(yīng)用程序調(diào)用ClassA. Ml ;
3.擦除ClassA.Ml指令代碼;
4.返回ClassA.M調(diào)用。
權(quán)利要求
1.一種保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于, 在JAVA應(yīng)用程序源文件中定位待保護(hù)的功能單元,將所述功能單元更改為本地方法;創(chuàng)建所述功能單元的副本單元,使得所述副本單元的指令代碼空間與所述功能單元的指令代碼空間相等; 將所述副本單元的指令代碼空間全部填充為空指令; 生成JAVA本地調(diào)用庫,導(dǎo)出所述功能單元的接口 ; 將所述功能單元的原始指令代碼加密后存儲在所述JNI庫的資源中; 擦除所述功能單元中的原始指令代碼。
2.根據(jù)權(quán)利要求I所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于, 當(dāng)調(diào)用所述功能單元時,通過Java虛擬機(jī)調(diào)用JAVA本地調(diào)用庫中的所述功能單元的接口,在所述JAVA本地調(diào)用庫中執(zhí)行以下步驟 從所述JAVA本地調(diào)用庫的資源中找到所述功能單元的加密數(shù)據(jù),將所述數(shù)據(jù)解密; 將解密后的數(shù)據(jù)填回到所述副本單元的指令代碼空間中; 調(diào)用、執(zhí)行所述副本單元; 擦除所述副本單元的指令代碼空間中的指令代碼; 返回所述功能單元的調(diào)用。
3.根據(jù)權(quán)利要求1、2所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于,所述加密過程中所使用的密鑰,由所述JAVA應(yīng)用程序的信息生成。
4.根據(jù)權(quán)利要求1、2所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于,所述加密過程中所使用的密鑰,由所述JAVA應(yīng)用程序的信息和被授權(quán)使用所述JAVA應(yīng)用程序的用戶的信息組合后生成密鑰。
5.根據(jù)權(quán)利要求1-4所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于,加密方法是對稱或非對稱算法,或者是公開的或私有的加密算法,或者是其它的數(shù)據(jù)變換與反變換方法。
6.根據(jù)權(quán)利要求1-5所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于,在上述加密或解密過程中,采用自定義的非標(biāo)準(zhǔn)JAVA程序文件格式。
7.根據(jù)權(quán)利要求1-5所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于,在上述加密或解密過程中,去除不影響所述JAVA應(yīng)用程序運行的源程序的信息。
8.根據(jù)權(quán)利要求1-5所述的保護(hù)安卓系統(tǒng)中JAVA應(yīng)用程序的方法,其特征在于,在上述解密過程中,在運行所述JAVA應(yīng)用程序時,當(dāng)監(jiān)測到正在對所述JAVA應(yīng)用程序進(jìn)行調(diào)試時,停止解密和加載運行過程。
全文摘要
本發(fā)明涉及計算機(jī)安全領(lǐng)域,特別是一種保護(hù)安卓系統(tǒng)中應(yīng)用程序的方法。通過將待保護(hù)的JAVA類對象的若干方法指令代碼進(jìn)行加密變換,在程序運行時根據(jù)調(diào)用需求對加密的方法代碼進(jìn)行實時的解密運行,使得應(yīng)用程序難以進(jìn)行反編譯和靜態(tài)分析,實現(xiàn)了對安卓系統(tǒng)中JAVA程序的有效保護(hù)。
文檔編號G06F21/00GK102708322SQ20121014580
公開日2012年10月3日 申請日期2012年5月12日 優(yōu)先權(quán)日2012年5月12日
發(fā)明者不公告發(fā)明人 申請人:北京深思洛克軟件技術(shù)股份有限公司