專利名稱:一種防止Java程序被反編譯的方法
技術(shù)領(lǐng)域:
本發(fā)明是用于阻止對Java字節(jié)碼文件進(jìn)行反編譯以獲取Java程序源代碼,即用 于Java程序的保護(hù)。
背景技術(shù):
Java是一種跨平臺的、解釋型語言。Java編譯工具將Java源代碼被編譯成為Java 字節(jié)碼文件,由Java虛擬機(jī)負(fù)責(zé)對Java字節(jié)碼文件進(jìn)行解釋執(zhí)行。與本地目標(biāo)代碼不同, Java字節(jié)碼文件中仍然保留了方法名稱、變量名稱,并且通過這些名稱來訪問變量和方法, 這些符號往往帶有許多語義信息。因此,對Java字節(jié)碼文件進(jìn)行反編譯就顯得比較容易。 有許多Java的反編譯工具都能夠從Java字節(jié)碼文件生成高質(zhì)量的源代碼。為阻止對Java 字節(jié)碼文件進(jìn)行反編譯,目前主要采用的有以下幾種方法(1)隔離Java程序是指將關(guān)鍵的Java字節(jié)碼文件放在服務(wù)器端,客戶端通過訪 問服務(wù)器的相關(guān)接口來獲得服務(wù),而不是直接訪問Java字節(jié)碼文件。這樣黑客就無法反編 譯Java字節(jié)碼文件。但是對于單機(jī)運(yùn)行的程序是無法采用這種方法進(jìn)行隔離的。(2)字節(jié)碼混淆主要是通過將定義的類、變量、方法和包的名字改為無意義的字 符串、使用非法的字符代替變量符號和在軟件中添加一些無關(guān)的指令或永遠(yuǎn)執(zhí)行不到的指 令等手段來增加反編譯和對反編譯后源代碼閱讀的難度。但這種方法并不能真正阻止反編 譯,而且混淆都有一定的規(guī)律可循,如果掌握這些規(guī)律,在反編譯時仍然可以得到一定質(zhì)量 的源代碼。(3)轉(zhuǎn)換本地代碼即將Java程序像C/C++程序一樣編譯成本機(jī)可執(zhí)行的二進(jìn)制 代碼。但是這樣做使得Java程序失去其跨平臺的特性,而且這種技術(shù)目前并不十分成熟, 因此不適用于大型應(yīng)用程序。(4)自定義類加載器是指首先將Java字節(jié)碼文件進(jìn)行加密處理,然后自已編寫 一個Java類裝載器在Java字節(jié)碼文件裝載時再進(jìn)行解密處理。這種方法的缺點(diǎn)在于雖然 經(jīng)過加密的Java字節(jié)碼文件無法被反編譯,但自定義的類加載器本身卻不能防止被反編 譯。因此,加密過的Java字節(jié)碼文件仍然是不安全的。
發(fā)明內(nèi)容
為了解決現(xiàn)有的技術(shù)中阻止對Java字節(jié)碼文件進(jìn)行反編譯的方法應(yīng)用范圍局 限、不能從根本上杜絕Java字節(jié)碼文件被反編譯的技術(shù)問題,本發(fā)明提供一種防止Java程 序被反編譯的方法。本發(fā)明的技術(shù)解決方案 一種防止Java程序被反編譯的方法,其特殊之處在于包括以下步驟1采用加密算法對要發(fā)布的Java字節(jié)碼文件進(jìn)行加密;2采用Java虛擬機(jī)工具接口監(jiān)聽Java虛擬機(jī)初始化事件;3采用Java虛擬機(jī)工具接口為步驟2中Java虛擬機(jī)監(jiān)聽到的Java虛擬機(jī)初始化事件指定Hook函數(shù);
4IJava虛擬機(jī)初始化完成時自動調(diào)用相應(yīng)的Hook函數(shù),并在的Hook函數(shù)中使用 Java本地接口將Java虛擬機(jī)在生成類對象時調(diào)用的函數(shù)注冊為自定義的代理函數(shù);
5Java虛擬機(jī)在生成某個類對象時調(diào)用相應(yīng)的自定義的代理函數(shù),在自定義的代 理函數(shù)中對在步驟1中加密過的Java字節(jié)碼文件進(jìn)行解密處理;
6將解密后的Java字節(jié)碼文件生成相應(yīng)的類對象后返回給Java虛擬機(jī)。
上述步驟4中所述Java虛擬機(jī)在生成類對象時調(diào)用的函數(shù)是函數(shù)java. lang. ClassLoader. defineclassl0
本發(fā)明所具有的優(yōu)點(diǎn)
1、保持了 Java程序的跨平臺特性Java虛擬機(jī)工具接口和Java本地接口是Java 虛擬機(jī)提供的機(jī)制,在所有支持Java虛擬機(jī)的平臺上都可以應(yīng)用本方法。
2、保持了 Java虛擬機(jī)的通用性不需要修改源代碼重新生成Java虛擬機(jī)。
3、解密過程對用戶透明解密過程被嵌入到了 Java虛擬機(jī)的類裝載過程中,不保 存解密后的Java字節(jié)碼文件。
4、保證了解密過程的安全性使用Java虛擬機(jī)工具接口和Java本地接口編寫的 程序(包括解密程序)全部編譯為本機(jī)可執(zhí)行的二進(jìn)制代碼。
圖1為本發(fā)明中與java虛擬機(jī)工具接口進(jìn)行交互的時序圖2為Java虛擬機(jī)的初始化過程
其中圖a為現(xiàn)有的Java虛擬機(jī)的初始化過程;圖b為使用本發(fā)明方法時Java虛 擬機(jī)的初始化過程;
圖3為Java虛擬機(jī)加載Java字節(jié)碼的過程
其中圖a為不使用本發(fā)明方法時Java虛擬機(jī)加載Java字節(jié)碼的過程;圖b為使 用本發(fā)明方法后Java虛擬機(jī)加載Java字節(jié)碼的過程;
圖4是Java反編譯軟件對Java字節(jié)碼文件的處理結(jié)果
其中圖a為Java反編譯軟件對沒有經(jīng)過本發(fā)明方法加密的Java字節(jié)碼文件的處 理結(jié)果;圖b為Java反編譯軟件對經(jīng)本分明方法加密的Java字節(jié)碼文件的處理結(jié)果。
具體實施方式
本發(fā)明的目的是提供一種在保持Java跨平臺特性和不修改Java虛擬機(jī)基礎(chǔ)上的 能夠?qū)⒔饷苓^程嵌入到Java虛擬機(jī)的類裝載過程中的方法。這種方法使解密過程對Java 軟件的使用者完全透明,且Java程序的使用者無法得到解密后的Java字節(jié)碼文件。本方 法的目的是通過下述的步驟實現(xiàn)的
1使用加密算法對要發(fā)布的Java字節(jié)碼文件進(jìn)行加密。
2使用Java虛擬機(jī)工具接口監(jiān)聽Java虛擬機(jī)初始化事件。
3使用Java虛擬機(jī)工具接口為第1步中監(jiān)聽到的Java虛擬機(jī)初始化事件指定 Hook函數(shù)。這樣在Java虛擬機(jī)初始化完成時會自動調(diào)用該Hook函數(shù)。
4在第3步指定的Hook函數(shù)中使用Java本地接口將Java虛擬機(jī)在生成類對象時必然會調(diào)用的函數(shù)注冊為自定義的一個代理函數(shù),當(dāng)Java虛擬機(jī)在生成某個類的對象 時,它會調(diào)用自定義的代理函數(shù)。5在第4步中注冊的代理函數(shù)中對在第1步中加密過的Java字節(jié)碼文件進(jìn)行解 密處理。6將解密后的Java字節(jié)碼文件生成相應(yīng)的類對象后返回給Java虛擬機(jī)。本方法的關(guān)鍵點(diǎn)是第4步中如何確定Java虛擬機(jī)在生成類對象時必然會 調(diào)用的函數(shù)。通過對Java虛擬機(jī)源代碼的分析可知加載用戶自定義類的加載器為 AppClassLoader, AppClassLoader 繼 7承于 URLClassLoader, URLClassLoader 繼 7承于 SecureClassLoader, SecureClassLoader ^lI T^i ClassLoader0 · ClassLoader 中 類對象的函數(shù)中除defineclassO和define class2外其他都必須調(diào)用defineclassl,經(jīng) 大量測試(即向Java虛擬機(jī)輸入大量的Java字節(jié)碼文件,然后分別在這三個函數(shù)中讀取 這些Java字節(jié)碼文件)表明在defineclassO中無法得到任何的Java字節(jié)碼文件;在 defineclass2中能夠得到極少數(shù),只有在defineclassl中能夠得到所有輸入的Java字節(jié) 碼文件。綜合對源代碼的分析及測試數(shù)據(jù)可以得出結(jié)論defineclassl是Java虛擬機(jī)在 生成類對象時必然會調(diào)用的函數(shù)。實施例在保持Java跨平臺特性和不修改Java虛擬機(jī)基礎(chǔ)上的能夠?qū)⒔饷苓^程嵌入到 Java虛擬機(jī)的類裝載過程中的方法。(1)創(chuàng)建一個動態(tài)鏈接庫項目。(2)將Java虛擬機(jī)提供的Java虛擬機(jī)工具接口和Java本地接口相關(guān)的支持頭文 件引入到第1步中建立的項目里。(3)在第1步中建立的項目里創(chuàng)建名為AgentJtaLoad的函數(shù),在該函數(shù)中通過 GetEnv函數(shù)獲取Java虛擬機(jī)工具接口環(huán)境。(4)通過jvmti接口函數(shù)向Java虛擬機(jī)預(yù)定VMInit事件的通知,并設(shè)置VMInit 事件的回調(diào)函數(shù)。(5)在第4步中創(chuàng)建的回調(diào)函數(shù)中利用jni接口將自定義的本地代理方法注冊到 JVM 的類對象生成方法(java. lang. ClassLoader. defineclassl)上。(6)完成自定義的本地代理函數(shù),在該函數(shù)中實現(xiàn)對字節(jié)碼的解密。(7)調(diào)用java. dll中的接口函數(shù)將解密后的字節(jié)碼轉(zhuǎn)換為Class對象并將這個對 象作為AgentJtaLoad函數(shù)的返回值返回給Java虛擬機(jī)。(8)構(gòu)建第1步中建立的項目生成動態(tài)鏈接庫。實施例(假設(shè)在上述第8步中生成的動態(tài)鏈接庫的名稱為agentlib. dll)WEB 應(yīng)用程序假設(shè)用戶的 Java Web Server 為 Tomcat,平臺為 Windows,Tomcat 的存放目錄為 C:\Tomcat 5. 5,agentlib. dll 存放在 c \windows 目錄中,在 Tomcat 的 bin 目錄中新建一個文件 setenv. bat, setenv. bat 中的內(nèi)容:setJAVA_0PTS = -agentlib c \ windows\agentlib% JAVA_0PTS%,保存 setenv. bat 文件,重新啟動 Tomcat 后就可以正確 加載加密類了。獨(dú)立的Java應(yīng)用程序:Test. class文件的package為com. test,在運(yùn) 行Test, class或Jar時使用以下方式j(luò)ava_agentlib〈agentlib. dll的存放目錄>\agentlib<-classpath jar 文件 >com. test. Test。這樣就可以運(yùn)行力口密過的 Test, class 文件了。
Eclipse插件將加密過的插件放到Eclipse平臺的pluging目錄下。打 開Eclipse目錄下的eclipse, ini文件,在“-vmargs”的下一行添加如下內(nèi)容 “-agentlib:<agentlib. dll 的存放目錄 >\agentlib”,保存 eclipse, ini 文件,重新啟動 Eclipse平臺后就可以運(yùn)行加密過的插件了。
權(quán)利要求
1.一種防止Java程序被反編譯的方法,其特征在于包括以下步驟 1采用加密算法對要發(fā)布的Java字節(jié)碼文件進(jìn)行加密;2采用Java虛擬機(jī)工具接口監(jiān)聽Java虛擬機(jī)初始化事件;3采用Java虛擬機(jī)工具接口為步驟2中Java虛擬機(jī)監(jiān)聽到的Java虛擬機(jī)初始化事 件指定Hook函數(shù);4IJava虛擬機(jī)初始化完成時自動調(diào)用相應(yīng)的Hook函數(shù),并在的Hook函數(shù)中使用Java 本地接口將Java虛擬機(jī)在生成類對象時調(diào)用的函數(shù)注冊為自定義的代理函數(shù);5IJava虛擬機(jī)在生成某個類對象時調(diào)用相應(yīng)的自定義的代理函數(shù),在自定義的代理函 數(shù)中對在步驟1中加密過的Java字節(jié)碼文件進(jìn)行解密處理;6將解密后的Java字節(jié)碼文件生成相應(yīng)的類對象后返回給Java虛擬機(jī)。
2.根據(jù)權(quán)利要求1所述的防止Java程序被反編譯的方法,其特征在于包括以下 步驟所述步驟4中所述Java虛擬機(jī)在生成類對象時調(diào)用的函數(shù)是函數(shù)java. lang. ClassLoader. defineclass I0
全文摘要
本發(fā)明涉及一種防止Java程序被反編譯的方法,包括以下步驟1)對要發(fā)布的Java字節(jié)碼文件進(jìn)行加密;2)用Java虛擬機(jī)工具接口監(jiān)聽它初始化事件;3)為Java虛擬機(jī)初始化事件指定Hook函數(shù);4)Java虛擬機(jī)初始化完成時自動調(diào)用Hook函數(shù),并在的Hook函數(shù)中使用Java本地接口將Java虛擬機(jī)在生成類對象時調(diào)用的函數(shù)注冊為自定義的代理函數(shù);5)Java虛擬機(jī)在生成某個類對象時調(diào)用自定義的代理函數(shù),在自定義的代理函數(shù)中對加密過的Java字節(jié)碼文件進(jìn)行解密處理;6)將解密后的Java字節(jié)碼文件生成相應(yīng)的類對象后返回給Java虛擬機(jī)。本發(fā)明解決了現(xiàn)有的技術(shù)中阻止對Java字節(jié)碼文件進(jìn)行反編譯的方法應(yīng)用范圍局限的技術(shù)問題,本發(fā)明保持了Java程序的跨平臺特性、保持了Java虛擬機(jī)的通用性。
文檔編號G06F21/24GK102043932SQ20101062015
公開日2011年5月4日 申請日期2010年12月31日 優(yōu)先權(quán)日2010年12月31日
發(fā)明者張旻, 田丹, 胡林平, 賈璐 申請人:中國航空工業(yè)集團(tuán)公司第六三一研究所