咨詢(xún)電話(huà)
微信掃一掃
新聞動(dòng)態(tài)
Java jar 如何防止被反編譯?代碼寫(xiě)的太爛,害怕被人發(fā)現
網(wǎng)站建設 發(fā)布者:ou3377 2021-12-07 11:12 訪(fǎng)問(wèn)量:130
java作為解釋型的語(yǔ)言,其高度抽象的特性意味其很容易被反編譯,容易被反編譯,自然有防止反編譯措施存在。
常用的保護技術(shù)
由于Java字節碼的抽象級別較高,因此它們較容易被反編譯。本節介紹了幾種常用的方法,用于保護Java字節碼不被反編譯。通常,這些方法不能夠絕對防止程序被反編譯,而是加大反編譯的難度而已,因為這些方法都有自己的使用環(huán)境和弱點(diǎn)。
最簡(jiǎn)單的方法就是讓用戶(hù)不能夠訪(fǎng)問(wèn)到Java Class程序,這種方法是最根本的方法,具體實(shí)現有多種方式。例如,開(kāi)發(fā)人員可以將關(guān)鍵的Java Class放在服務(wù)器端,客戶(hù)端通過(guò)訪(fǎng)問(wèn)服務(wù)器的相關(guān)接口來(lái)獲得服務(wù),而不是直接訪(fǎng)問(wèn)Class文件。這樣黑客就沒(méi)有辦法[反編譯Class文件。目前,通過(guò)接口提供服務(wù)的標準和協(xié)議也越來(lái)越多,例如 HTTP、Web Service、RPC等。但是有很多應用都不適合這種保護方式,例如對于單機運行的程序就無(wú)法隔離Java程序。這種保護方式見(jiàn)圖所示。
為了防止Class文件被直接反編譯,許多開(kāi)發(fā)人員將一些關(guān)鍵的Class文件進(jìn)行加密,例如對注冊碼、序列號管理相關(guān)的類(lèi)等。在使用這些被加密的類(lèi)之前,程序首先需要對這些類(lèi)進(jìn)行解密,而后再將這些類(lèi)裝載到JVM當中。這些類(lèi)的解密可以由硬件完成,也可以使用軟件完成。
在實(shí)現時(shí),開(kāi)發(fā)人員往往通過(guò)自定義ClassLoader類(lèi)來(lái)完成加密類(lèi)的裝載(注意由于安全性的原因,Applet不能夠支持自定義的 ClassLoader)。自定義的ClassLoader首先找到加密的類(lèi),而后進(jìn)行解密,最后將解密后的類(lèi)裝載到JVM當中。在這種保護方式中,自定義的ClassLoader是非常關(guān)鍵的類(lèi)。由于它本身不是被加密的,因此它可能成為黑客最先攻擊的目標。如果相關(guān)的解密密鑰和算法被攻克,那么被加密的類(lèi)也很容易被解密。這種保護方式見(jiàn)示意圖。
將程序轉換成本地代碼也是一種防止反編譯的有效方法。因為本地代碼往往難以被反編譯。開(kāi)發(fā)人員可以選擇將整個(gè)應用程序轉換成本地代碼,也可以選擇關(guān)鍵模塊轉換。如果僅僅轉換關(guān)鍵部分模塊,Java程序在使用這些模塊時(shí),需要使用JNI技術(shù)進(jìn)行調用。
當然,在使用這種技術(shù)保護Java程序的同時(shí),也犧牲了Java的跨平臺特性。對于不同的平臺,我們需要維護不同版本的本地代碼,這將加重軟件支持和維護的工作。不過(guò)對于一些關(guān)鍵的模塊,有時(shí)這種方案往往是必要的。
為了保證這些本地代碼不被修改和替代,通常需要對這些代碼進(jìn)行數字簽名。在使用這些本地代碼之前,往往需要對這些本地代碼進(jìn)行認證,確保這些代碼沒(méi)有被黑客更改。如果簽名檢查通過(guò),則調用相關(guān)JNI方法。這種保護方式見(jiàn)示意圖。
代碼混淆是對Class文件進(jìn)行重新組織和處理,使得處理后的代碼與處理前代碼完成相同的功能(語(yǔ)義)。但是混淆后的代碼很難被[反編譯,即[反編譯后得出的代碼是非常難懂、晦澀的,因此[反編譯人員很難得出程序的真正語(yǔ)義。從理論上來(lái)說(shuō),黑客如果有足夠的時(shí)間,被混淆的代碼仍然可能被破解,甚至目前有些人正在研制反混淆的工具。但是從實(shí)際情況來(lái)看,由于混淆技術(shù)的多元化發(fā)展,混淆理論的成熟,經(jīng)過(guò)混淆的Java代碼還是能夠很好地防止[反編譯。下面我們會(huì )詳細介紹混淆技術(shù),因為混淆是一種保護Java程序的重要技術(shù)。下圖是代碼混淆的示圖。
幾種技術(shù)的總結 以上幾種技術(shù)都有不同的應用環(huán)境,各自都有自己的弱點(diǎn),表1是相關(guān)特點(diǎn)的比較。
混淆技術(shù)介紹
表1 不同保護技術(shù)比較表
到目前為止,對于Java程序的保護,混淆技術(shù)還是最基本的保護方法。Java混淆工具也非常多,包括商業(yè)的、免費的、開(kāi)放源代碼的。Sun公司也提供了自己的混淆工具。它們大多都是對Class文件進(jìn)行混淆處理,也有少量工具首先對源代碼進(jìn)行處理,然后再對Class進(jìn)行處理,這樣加大了混淆處理的力度。目前,商業(yè)上比較成功的混淆工具包括JProof公司的1stBarrier系列、Eastridge公司的JShrink和 4thpass.com的SourceGuard等。主要的混淆技術(shù)按照混淆目標可以進(jìn)行如下分類(lèi),它們分別為符號混淆(Lexical Obfuscation)、數據混淆(Data Obfuscation)、控制混淆(Control Obfuscation)、預防性混淆(Prevent Transformation)。
在Class中存在許多與程序執行本身無(wú)關(guān)的信息,例如方法名稱(chēng)、變量名稱(chēng),這些符號的名稱(chēng)往往帶有一定的含義。例如某個(gè)方法名為 getKeyLength(),那么這個(gè)方法很可能就是用來(lái)返回Key的長(cháng)度。符號混淆就是將這些信息打亂,把這些信息變成無(wú)任何意義的表示,例如將所有的變量從vairant_001開(kāi)始編號;對于所有的方法從method_001開(kāi)始編號。這將對反編譯帶來(lái)一定的困難。對于私有函數、局部變量,通??梢愿淖兯鼈兊姆?,而不影響程序的運行。但是對于一些接口名稱(chēng)、公有函數、成員變量,如果有其它外部模塊需要引用這些符號,我們往往需要保留這些名稱(chēng),否則外部模塊找不到這些名稱(chēng)的方法和變量。因此,多數的混淆工具對于符號混淆,都提供了豐富的選項,讓用戶(hù)選擇是否、如何進(jìn)行符號混淆。
數據混淆是對程序使用的數據進(jìn)行混淆?;煜姆椒ㄒ灿卸喾N,主要可以分為改變數據存儲及編碼(Store and Encode Transform)、改變數據訪(fǎng)問(wèn)(Access Transform)。
改變數據存儲和編碼可以打亂程序使用的數據存儲方式。例如將一個(gè)有10個(gè)成員的數組,拆開(kāi)為10個(gè)變量,并且打亂這些變量的名字;將一個(gè)兩維數組轉化為一個(gè)一維數組等。對于一些復雜的數據結構,我們將打亂它的數據結構,例如用多個(gè)類(lèi)代替一個(gè)復雜的類(lèi)等。
另外一種方式是改變數據訪(fǎng)問(wèn)。例如訪(fǎng)問(wèn)數組的下標時(shí),我們可以進(jìn)行一定的計算,圖5就是一個(gè)例子。
在實(shí)踐混淆處理中,這兩種方法通常是綜合使用的,在打亂數據存儲的同時(shí),也打亂數據訪(fǎng)問(wèn)的方式。經(jīng)過(guò)對數據混淆,程序的語(yǔ)義變得復雜了,這樣增大了反編譯的難度。
控制混淆就是對程序的控制流進(jìn)行混淆,使得程序的控制流更加難以[反編譯,通??刂屏鞯母淖冃枰黾右恍╊~外的計算和控制流,因此在性能上會(huì )給程序帶來(lái)一定的負面影響。有時(shí),需要在程序的性能和混淆程度之間進(jìn)行權衡??刂苹煜募夹g(shù)最為復雜,技巧也最多。這些技術(shù)可以分為如下幾類(lèi):
增加混淆控制通過(guò)增加額外的、復雜的控制流,可以將程序原來(lái)的語(yǔ)義隱藏起來(lái)。例如,對于按次序執行的兩個(gè)語(yǔ)句A、B,我們可以增加一個(gè)控制條件,以決定B的執行。通過(guò)這種方式加大反匯編的難度。但是所有的干擾控制都不應該影響B(tài)的執行。圖6就給出三種方式,為這個(gè)例子增加混淆控制。
控制流重組重組控制流也是重要的混淆方法。例如,程序調用一個(gè)方法,在混淆后,可以將該方法代碼嵌入到調用程序當中。反過(guò)來(lái),程序中的一段代碼也可以轉變?yōu)橐粋€(gè)函數調用。另外,對于一個(gè)循環(huán)的控制流,為可以拆分多個(gè)循環(huán)的控制流,或者將循環(huán)轉化成一個(gè)遞歸過(guò)程。這種方法最為復雜,研究的人員也非常多。
這種混淆通常是針對一些專(zhuān)用的反編譯器而設計的,一般來(lái)說(shuō),這些技術(shù)利用反編譯器的弱點(diǎn)或者Bug來(lái)設計混淆方案。例如,有些反編譯器對于 Return后面的指令不進(jìn)行反編譯,而有些混淆方案恰恰將代碼放在Return語(yǔ)句后面。這種混淆的有效性對于不同反編譯器的作用也不太相同的。一個(gè)好的混淆工具,通常會(huì )綜合使用這些混淆技術(shù)。
在實(shí)踐當中,保護一個(gè)大型Java程序經(jīng)常需要綜合使用這些方法,而不是單一使用某一種方法。這是因為每種方法都有其弱點(diǎn)和應用環(huán)境。綜合使用這些方法使得Java程序的保護更加有效。另外,我們經(jīng)常還需要使用其它的相關(guān)安全技術(shù),例如安全認證、數字簽名、PKI等。
本文給出的例子是一個(gè)Java應用程序,它是一個(gè)SCJP(Sun Certificate Java Programmer)的模擬考試軟件。該應用程序帶有大量的模擬題目,所有的題目都被加密后存儲在文件中。由于它所帶的題庫是該軟件的核心部分,所以關(guān)于題庫的存取和訪(fǎng)問(wèn)就成為非常核心的類(lèi)。一旦這些相關(guān)的類(lèi)被反編譯,則所有的題庫將被破解?,F在,我們來(lái)考慮如何保護這些題庫及相關(guān)的類(lèi)。
在這個(gè)例子中,我們考慮使用綜合保護技術(shù),其中包括本地代碼和混淆技術(shù)。因為該軟件主要發(fā)布在Windows上,因此轉換成本地代碼后,僅僅需要維護一個(gè)版本的本地代碼。另外,混淆對Java程序也是非常有效的,適用于這種獨立發(fā)布的應用系統。
在具體的方案中,我們將程序分為兩個(gè)部分,一個(gè)是由本地代碼編寫(xiě)的題庫訪(fǎng)問(wèn)的模塊,另外一個(gè)是由Java開(kāi)發(fā)的其它模塊。這樣可以更高程度地保護題目管理模塊不被[反編譯。對于Java開(kāi)發(fā)的模塊,我們仍然要使用混淆技術(shù)。該方案的示意圖參見(jiàn)圖7。
對于題目管理模塊,由于程序主要在Windows下使用,所以使用C++開(kāi)發(fā)題庫訪(fǎng)問(wèn)模塊,并且提供了一定的訪(fǎng)問(wèn)接口。為了保護題庫訪(fǎng)問(wèn)的接口,我們還增加了一個(gè)初始化接口,用于每次使用題庫訪(fǎng)問(wèn)接口之前的初始化工作。它的接口主要分為兩類(lèi):
在使用題庫模塊之前,我們必須先調用初始化接口。在調用該接口時(shí),客戶(hù)端需要提供一個(gè)隨機數作為參數。題庫管理模塊和客戶(hù)端通過(guò)這個(gè)隨機數,按一定的算法同時(shí)生成相同的SessionKey,用于加密以后輸入和輸出的所有數據。通過(guò)這種方式,只有授權(有效)的客戶(hù)端才能夠連接正確的連接,生成正確的 SessionKey,用于訪(fǎng)問(wèn)題庫信息。非法的客戶(hù)很難生成正確的SessionKey,因此無(wú)法獲得題庫的信息。如果需要建立更高的保密級別,也可以采用雙向認證技術(shù)。
認證完成之后,客戶(hù)端就可以正常的訪(fǎng)問(wèn)題庫數據。但是,輸入和輸出的數據都是由SessionKey所加密的數據。因此,只有正確的題庫管理模塊才能夠使用題庫管理模塊。圖8時(shí)序圖表示了題庫管理模塊和其它部分的交互過(guò)程。
來(lái)源 | www.cnblogs.com/dartagnan/
【推薦閱讀】
關(guān)鍵字: Java jar
文章連接: http://www.gostscript.com/wzjss/775.html
版權聲明:文章由 晨展科技 整理收集,來(lái)源于互聯(lián)網(wǎng)或者用戶(hù)投稿,如有侵權,請聯(lián)系我們,我們會(huì )立即刪除。如轉載請保留
晨展解決方案
晨展新聞