防止JAVA字節(jié)碼反編譯問題解決方案
這里向大家描述一下Java字節(jié)碼加密問題,Class文件能被很輕松的重構(gòu)生成JAVA源文件與最初JAVA字節(jié)碼的設(shè)計(jì)目的和商業(yè)交易有緊密地聯(lián)系。
深入Java字節(jié)碼加密
問:
如果我把我的class文件加密,在運(yùn)行時(shí)用指定的類加載器(classloader)裝入并解密它,這樣子能防止被反編譯嗎?
答:
防止JAVA字節(jié)碼反編譯這個(gè)問題在java語言雛形期就有了,盡管市面上存在一些反編譯的工具可以利用,但是JAVA程序員還是不斷的努力尋找新的更有效的方法來保護(hù)他們的智慧結(jié)晶。在此,我將詳細(xì)給大家解釋這一直來在論壇上有爭(zhēng)議的話題。
Class文件能被很輕松的重構(gòu)生成JAVA源文件與最初JAVA字節(jié)碼的設(shè)計(jì)目的和商業(yè)交易有緊密地聯(lián)系。另外,JAVA字節(jié)碼被設(shè)計(jì)成簡(jiǎn)潔、平臺(tái)獨(dú)立性、網(wǎng)絡(luò)靈活性,并且易于被字節(jié)碼解釋器和JIT(just-in-time)/HotSpot編譯器所分析??梢郧宄亓私獬绦騿T的目的,Class文件要比JAVA源文件更易于分析。
如果不能阻止被反編譯的話,至少可以通過一些方法來增加它的困難性。例如:在一個(gè)分步編譯里,你可以打亂Class文件的數(shù)據(jù)以使其難讀或者難以被反編譯成正確的JAVA源文件,前者可以采用極端函數(shù)重載,后者用操作控制流建立控制結(jié)構(gòu)使其難以恢復(fù)正常次序。有更多成功的商業(yè)困惑者采用這些或其他的技術(shù)來保護(hù)自己的代碼。
不幸的是,哪種方法都必須改變JVM運(yùn)行的代碼,并且許多用戶害怕這種轉(zhuǎn)化會(huì)給他們的程序帶來新的Bug。而且,方法和字段重命名會(huì)調(diào)用反射從而使程序停止工作,改變類和包的名字會(huì)破壞其他的JAVAAPIS(JNDI,URLproviders,etc),除了改變名字,如果字節(jié)碼偏移量和源代碼行數(shù)之間的關(guān)系改變了,在恢復(fù)這有異常的堆棧將很困難。
于是就有了一些打亂JAVA源代碼的選項(xiàng),但是這將從本質(zhì)上導(dǎo)致一系列問題的產(chǎn)生。
加密而不打亂
或許上述可能會(huì)使你問,假如我把字節(jié)碼加密而不是處理字節(jié)碼,并且JVM運(yùn)行時(shí)自動(dòng)將它解密并裝入類加載器,然后JVM運(yùn)行解密后的字節(jié)碼文件,這樣就不會(huì)被反編譯了對(duì)嗎?
考慮到你是第一個(gè)提出這種想法的并且它又能正常運(yùn)行,我表示遺憾和不幸,這種想法是錯(cuò)誤的。
【編輯推薦】
- JAVA字節(jié)碼文件操作技巧
- IBM發(fā)布Java字節(jié)碼配置工具包BIPTK
- JVM.dll裝載過程與源代碼分析
- 巧解使Eclipse崩潰的JVM terminated問題
- 解決JVM Terminated.ExitCode=-1問題行之有效的方法