<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:如何防止 Java 源碼被反編譯??我:...

          共 4713字,需瀏覽 10分鐘

           ·

          2021-10-16 12:12




          面試官:如何防止 Java 源碼被反編譯?


          java作為解釋型的語(yǔ)言,其高度抽象的特性意味其很容易被反編譯,容易被反編譯,自然有防止反編譯措施存在。今天就拜讀了一篇相關(guān)的文章,受益匪淺,知彼知己嘛!!


          之所以會(huì)對(duì)java的反編譯感興趣,那是因?yàn)樽约涸趯W(xué)習(xí)的過(guò)程中,常常需要借鑒一下別人的成果(你懂的...)。或許反編譯別人的代碼不怎么道德,這個(gè)嘛......


          廢話不多說(shuō),正文如下:


          由于Java字節(jié)碼的抽象級(jí)別較高,因此它們較容易被反編譯。本節(jié)介紹了幾種常用的方法,用于保護(hù)Java字節(jié)碼不被反編譯。通常,這些方法不能夠絕對(duì)防止程序被反編譯,而是加大反編譯的難度而已,因?yàn)檫@些方法都有自己的使用環(huán)境和弱點(diǎn)。


          ?

          1

          隔離Java程序


          最簡(jiǎn)單的方法就是讓用戶不能夠訪問(wèn)到Java Class程序,這種方法是最根本的方法,具體實(shí)現(xiàn)有多種方式。例如,開(kāi)發(fā)人員可以將關(guān)鍵的Java Class放在服務(wù)器端,客戶端通過(guò)訪問(wèn)服務(wù)器的相關(guān)接口來(lái)獲得服務(wù),而不是直接訪問(wèn)Class文件。


          這樣黑客就沒(méi)有辦法反編譯Class文件。


          目前,通過(guò)接口提供服務(wù)的標(biāo)準(zhǔn)和協(xié)議也越來(lái)越多,例如 HTTP、Web Service、RPC等。但是有很多應(yīng)用都不適合這種保護(hù)方式,例如對(duì)于單機(jī)運(yùn)行的程序就無(wú)法隔離Java程序。這種保護(hù)方式見(jiàn)圖1所示。


          圖1隔離Java程序示意圖:



          ?

          2

          對(duì)Class文件進(jìn)行加密


          為了防止Class文件被直接反編譯,許多開(kāi)發(fā)人員將一些關(guān)鍵的Class文件進(jìn)行加密,例如對(duì)注冊(cè)碼、序列號(hào)管理相關(guān)的類等。在使用這些被加密的類之前,程序首先需要對(duì)這些類進(jìn)行解密,而后再將這些類裝載到JVM當(dāng)中。這些類的解密可以由硬件完成,也可以使用軟件完成。


          在實(shí)現(xiàn)時(shí),開(kāi)發(fā)人員往往通過(guò)自定義ClassLoader類來(lái)完成加密類的裝載(注意由于安全性的原因,Applet不能夠支持自定義的 ClassLoader)。自定義的ClassLoader首先找到加密的類,而后進(jìn)行解密,最后將解密后的類裝載到JVM當(dāng)中。


          在這種保護(hù)方式中,自定義的ClassLoader是非常關(guān)鍵的類。由于它本身不是被加密的,因此它可能成為黑客最先攻擊的目標(biāo)。如果相關(guān)的解密密鑰和算法被攻克,那么被加密的類也很容易被解密。這種保護(hù)方式示意圖見(jiàn)圖2。


          圖2 對(duì)Class文件進(jìn)行加密示意圖



          ?

          3

          轉(zhuǎn)換成本地代碼


          將程序轉(zhuǎn)換成本地代碼也是一種防止反編譯的有效方法。因?yàn)楸镜卮a往往難以被反編譯。開(kāi)發(fā)人員可以選擇將整個(gè)應(yīng)用程序轉(zhuǎn)換成本地代碼,也可以選擇關(guān)鍵模塊轉(zhuǎn)換。如果僅僅轉(zhuǎn)換關(guān)鍵部分模塊,Java程序在使用這些模塊時(shí),需要使用JNI技術(shù)進(jìn)行調(diào)用。


          當(dāng)然,在使用這種技術(shù)保護(hù)Java程序的同時(shí),也犧牲了Java的跨平臺(tái)特性。對(duì)于不同的平臺(tái),我們需要維護(hù)不同版本的本地代碼,這將加重軟件支持和維護(hù)的工作。不過(guò)對(duì)于一些關(guān)鍵的模塊,有時(shí)這種方案往往是必要的。


          為了保證這些本地代碼不被修改和替代,通常需要對(duì)這些代碼進(jìn)行數(shù)字簽名。在使用這些本地代碼之前,往往需要對(duì)這些本地代碼進(jìn)行認(rèn)證,確保這些代碼沒(méi)有被黑客更改。如果簽名檢查通過(guò),則調(diào)用相關(guān)JNI方法。這種保護(hù)方式示意圖見(jiàn)圖3。


          圖3 轉(zhuǎn)換成本地代碼示意圖



          ?

          4

          代碼混淆


          代碼混淆是對(duì)Class文件進(jìn)行重新組織和處理,使得處理后的代碼與處理前代碼完成相同的功能(語(yǔ)義)。但是混淆后的代碼很難被反編譯,即反編譯后得出的代碼是非常難懂、晦澀的,因此反編譯人員很難得出程序的真正語(yǔ)義。


          從理論上來(lái)說(shuō),黑客如果有足夠的時(shí)間,被混淆的代碼仍然可能被破解,甚至目前有些人正在研制反混淆的工具。但是從實(shí)際情況來(lái)看,由于混淆技術(shù)的多元化發(fā)展,混淆理論的成熟,經(jīng)過(guò)混淆的Java代碼還是能夠很好地防止反編譯。下面我們會(huì)詳細(xì)介紹混淆技術(shù),因?yàn)榛煜且环N保護(hù)Java程序的重要技術(shù)。圖4是代碼混淆的示圖。


          圖4 代碼混淆示意圖



          幾種技術(shù)的總結(jié)


          以上幾種技術(shù)都有不同的應(yīng)用環(huán)境,各自都有自己的弱點(diǎn),表1是相關(guān)特點(diǎn)的比較。 


          表1 不同保護(hù)技術(shù)比較表 



          到目前為止,對(duì)于Java程序的保護(hù),混淆技術(shù)還是最基本的保護(hù)方法。Java混淆工具也非常多,包括商業(yè)的、免費(fèi)的、開(kāi)放源代碼的。Sun公司也提供了自己的混淆工具。它們大多都是對(duì)Class文件進(jìn)行混淆處理,也有少量工具首先對(duì)源代碼進(jìn)行處理,然后再對(duì)Class進(jìn)行處理,這樣加大了混淆處理的力度。


          目前,商業(yè)上比較成功的混淆工具包括JProof公司的1stBarrier系列、Eastridge公司的JShrink和 4thpass.com的SourceGuard等。主要的混淆技術(shù)按照混淆目標(biāo)可以進(jìn)行如下分類,它們分別為符號(hào)混淆(Lexical Obfuscation)、數(shù)據(jù)混淆(Data Obfuscation)、控制混淆(Control Obfuscation)、預(yù)防性混淆(Prevent Transformation)。

           

          符號(hào)混淆


          在Class中存在許多與程序執(zhí)行本身無(wú)關(guān)的信息,例如方法名稱、變量名稱,這些符號(hào)的名稱往往帶有一定的含義。例如某個(gè)方法名為 getKeyLength(),那么這個(gè)方法很可能就是用來(lái)返回Key的長(zhǎng)度。符號(hào)混淆就是將這些信息打亂,把這些信息變成無(wú)任何意義的表示,例如將所有的變量從vairant_001開(kāi)始編號(hào);對(duì)于所有的方法從method_001開(kāi)始編號(hào)。這將對(duì)反編譯帶來(lái)一定的困難。


          對(duì)于私有函數(shù)、局部變量,通常可以改變它們的符號(hào),而不影響程序的運(yùn)行。但是對(duì)于一些接口名稱、公有函數(shù)、成員變量,如果有其它外部模塊需要引用這些符號(hào),我們往往需要保留這些名稱,否則外部模塊找不到這些名稱的方法和變量。因此,多數(shù)的混淆工具對(duì)于符號(hào)混淆,都提供了豐富的選項(xiàng),讓用戶選擇是否、如何進(jìn)行符號(hào)混淆。


          數(shù)據(jù)混淆


          圖5 改變數(shù)據(jù)訪問(wèn)



          數(shù)據(jù)混淆是對(duì)程序使用的數(shù)據(jù)進(jìn)行混淆。混淆的方法也有多種,主要可以分為改變數(shù)據(jù)存儲(chǔ)及編碼(Store and Encode Transform)、改變數(shù)據(jù)訪問(wèn)(Access Transform)。


          改變數(shù)據(jù)存儲(chǔ)和編碼可以打亂程序使用的數(shù)據(jù)存儲(chǔ)方式。例如將一個(gè)有10個(gè)成員的數(shù)組,拆開(kāi)為10個(gè)變量,并且打亂這些變量的名字;將一個(gè)兩維數(shù)組轉(zhuǎn)化為一個(gè)一維數(shù)組等。對(duì)于一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu),我們將打亂它的數(shù)據(jù)結(jié)構(gòu),例如用多個(gè)類代替一個(gè)復(fù)雜的類等。


          另外一種方式是改變數(shù)據(jù)訪問(wèn)。例如訪問(wèn)數(shù)組的下標(biāo)時(shí),我們可以進(jìn)行一定的計(jì)算,圖5就是一個(gè)例子。


          在實(shí)踐混淆處理中,這兩種方法通常是綜合使用的,在打亂數(shù)據(jù)存儲(chǔ)的同時(shí),也打亂數(shù)據(jù)訪問(wèn)的方式。經(jīng)過(guò)對(duì)數(shù)據(jù)混淆,程序的語(yǔ)義變得復(fù)雜了,這樣增大了反編譯的難度。


          控制混淆


          控制混淆就是對(duì)程序的控制流進(jìn)行混淆,使得程序的控制流更加難以反編譯,通常控制流的改變需要增加一些額外的計(jì)算和控制流,因此在性能上會(huì)給程序帶來(lái)一定的負(fù)面影響。有時(shí),需要在程序的性能和混淆程度之間進(jìn)行權(quán)衡。控制混淆的技術(shù)最為復(fù)雜,技巧也最多。這些技術(shù)可以分為如下幾類:


          增加混淆控制通過(guò)增加額外的、復(fù)雜的控制流,可以將程序原來(lái)的語(yǔ)義隱藏起來(lái)。例如,對(duì)于按次序執(zhí)行的兩個(gè)語(yǔ)句A、B,我們可以增加一個(gè)控制條件,以決定B的執(zhí)行。通過(guò)這種方式加大反匯編的難度。但是所有的干擾控制都不應(yīng)該影響B(tài)的執(zhí)行。圖6就給出三種方式,為這個(gè)例子增加混淆控制。


          圖6 增加混淆控制的三種方式



          控制流重組重組控制流也是重要的混淆方法。例如,程序調(diào)用一個(gè)方法,在混淆后,可以將該方法代碼嵌入到調(diào)用程序當(dāng)中。反過(guò)來(lái),程序中的一段代碼也可以轉(zhuǎn)變?yōu)橐粋€(gè)函數(shù)調(diào)用。另外,對(duì)于一個(gè)循環(huán)的控制流,為可以拆分多個(gè)循環(huán)的控制流,或者將循環(huán)轉(zhuǎn)化成一個(gè)遞歸過(guò)程。這種方法最為復(fù)雜,研究的人員也非常多。


          預(yù)防性混淆


          這種混淆通常是針對(duì)一些專用的反編譯器而設(shè)計(jì)的,一般來(lái)說(shuō),這些技術(shù)利用反編譯器的弱點(diǎn)或者Bug來(lái)設(shè)計(jì)混淆方案。例如,有些反編譯器對(duì)于 Return后面的指令不進(jìn)行反編譯,而有些混淆方案恰恰將代碼放在Return語(yǔ)句后面。這種混淆的有效性對(duì)于不同反編譯器的作用也不太相同的。一個(gè)好的混淆工具,通常會(huì)綜合使用這些混淆技術(shù)。


          案例分析


          在實(shí)踐當(dāng)中,保護(hù)一個(gè)大型Java程序經(jīng)常需要綜合使用這些方法,而不是單一使用某一種方法。這是因?yàn)槊糠N方法都有其弱點(diǎn)和應(yīng)用環(huán)境。綜合使用這些方法使得Java程序的保護(hù)更加有效。另外,我們經(jīng)常還需要使用其它的相關(guān)安全技術(shù),例如安全認(rèn)證、數(shù)字簽名、PKI等。


          本文給出的例子是一個(gè)Java應(yīng)用程序,它是一個(gè)SCJP(Sun Certificate Java Programmer)的模擬考試軟件。該應(yīng)用程序帶有大量的模擬題目,所有的題目都被加密后存儲(chǔ)在文件中。由于它所帶的題庫(kù)是該軟件的核心部分,所以關(guān)于題庫(kù)的存取和訪問(wèn)就成為非常核心的類。一旦這些相關(guān)的類被反編譯,則所有的題庫(kù)將被破解。現(xiàn)在,我們來(lái)考慮如何保護(hù)這些題庫(kù)及相關(guān)的類。


          在這個(gè)例子中,我們考慮使用綜合保護(hù)技術(shù),其中包括本地代碼和混淆技術(shù)。因?yàn)樵撥浖饕l(fā)布在Windows上,因此轉(zhuǎn)換成本地代碼后,僅僅需要維護(hù)一個(gè)版本的本地代碼。另外,混淆對(duì)Java程序也是非常有效的,適用于這種獨(dú)立發(fā)布的應(yīng)用系統(tǒng)。


          在具體的方案中,我們將程序分為兩個(gè)部分,一個(gè)是由本地代碼編寫的題庫(kù)訪問(wèn)的模塊,另外一個(gè)是由Java開(kāi)發(fā)的其它模塊。這樣可以更高程度地保護(hù)題目管理模塊不被反編譯。對(duì)于Java開(kāi)發(fā)的模塊,我們?nèi)匀灰褂没煜夹g(shù)。該方案的示意圖參見(jiàn)圖7。


          圖7 SCJP保護(hù)技術(shù)方案圖



          對(duì)于題目管理模塊,由于程序主要在Windows下使用,所以使用C++開(kāi)發(fā)題庫(kù)訪問(wèn)模塊,并且提供了一定的訪問(wèn)接口。為了保護(hù)題庫(kù)訪問(wèn)的接口,我們還增加了一個(gè)初始化接口,用于每次使用題庫(kù)訪問(wèn)接口之前的初始化工作。它的接口主要分為兩類:


          1. 初始化接口


          在使用題庫(kù)模塊之前,我們必須先調(diào)用初始化接口。在調(diào)用該接口時(shí),客戶端需要提供一個(gè)隨機(jī)數(shù)作為參數(shù)。題庫(kù)管理模塊和客戶端通過(guò)這個(gè)隨機(jī)數(shù),按一定的算法同時(shí)生成相同的SessionKey,用于加密以后輸入和輸出的所有數(shù)據(jù)。


          通過(guò)這種方式,只有授權(quán)(有效)的客戶端才能夠連接正確的連接,生成正確的 SessionKey,用于訪問(wèn)題庫(kù)信息。非法的客戶很難生成正確的SessionKey,因此無(wú)法獲得題庫(kù)的信息。如果需要建立更高的保密級(jí)別,也可以采用雙向認(rèn)證技術(shù)。


          2. 數(shù)據(jù)訪問(wèn)接口


          認(rèn)證完成之后,客戶端就可以正常的訪問(wèn)題庫(kù)數(shù)據(jù)。但是,輸入和輸出的數(shù)據(jù)都是由SessionKey所加密的數(shù)據(jù)。因此,只有正確的題庫(kù)管理模塊才能夠使用題庫(kù)管理模塊。圖8時(shí)序圖表示了題庫(kù)管理模塊和其它部分的交互過(guò)程。



          來(lái)源博客:https://www.cnblogs.com/dartagnan/


          PS:防止找不到本篇文章,可以收藏點(diǎn)贊,方便翻閱查找哦。


          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享 ?最新整理全集,找項(xiàng)目不累啦 04版

          堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開(kāi)放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開(kāi)放下載!

          歡迎添加程序汪個(gè)人微信 itwang008? 進(jìn)粉絲群或圍觀朋友圈

          瀏覽 37
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  激情乱伦文学 | 国产传媒一区二区 | 国产黄色视频免费在线观看 | 黄色网址 | 91黄页免费观看视频 |