Android 開發怎樣做程式碼加密或混淆?
歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。
在大公司怎麼做android程式碼混淆的?發現他們的軟體用apktool反編譯居然沒看到classes.dex檔案和當前安卓APP加固到底該如何做到防篡改?這兩個問題中有過相應回答,現搬運要點過來。
網易資深安全工程師鍾亞平在今年的安卓巴士全球開發者論壇上做了《安卓APP逆向與保護》的演講(完整演講內容請見這裡:一文了解安卓APP逆向分析與保護機制),其中就談到了關於程式碼混淆的問題。
Java程式碼是非常容易反編譯的,為了很好地保護Java原始碼,開發者往往會對編譯好的class檔案進行混淆處理。
混淆就是對釋出出去的程式進行重新組織和處理,使得處理後的程式碼與處理前程式碼完成相同的功能,而混淆後的程式碼很難被反編譯,即使反編譯成功也很難得出程式的真正語義。ProGuard就是一個混淆程式碼的開源專案,能夠對位元組碼進行混淆、縮減體積、優化等處理。
Proguard處理流程圖如下所示,包含壓縮、優化、混淆、預檢四個主要環節:
<
1. 壓縮(Shrink):檢測並移除程式碼中無用的類、欄位、方法和特性(Attribute);
2. 優化(Optimize):對位元組碼進行優化,移除無用的指令。優化程式碼,非入口節點類會加上private/static/final,沒有用到的引數會被刪除,一些方法可能會變成內聯程式碼;
3. 混淆(Obfuscate):使用a、b、c、d這樣簡短而無意義的名稱,對類、欄位和方法進行重新命名;
4. 預檢(Preveirfy):在Java平臺上對處理後的程式碼進行預檢,確保載入的class檔案是可執行的。
利用Proguard,對Dex2jar進行反編譯處理後的Apk效果示例:
處理前
Proguard處理後
Proguard混淆器不僅能夠保護程式碼,而且能夠精簡編譯後的程式大小,減少記憶體佔用。
混淆程式碼逆向分析
如果想要反編譯混淆程式碼,鍾亞平分享了一個國外的工具DEGUADR,它能夠通過統計的方式來解混淆。雖然這個工具的正確率達不到100%,但是能在一定程度上幫助反編譯程式碼。
使用DEGUADR解混淆的示例:
com.xxxxx.common.util.CryptoUtil網站也提供了一種反編譯服務,如下所示:
java.lang.String a(byte[]) -> encodeToString java.lang.String a(byte[],boolean,java.lang.String) -> a byte[] a(byte[],byte[]) -> encrypt byte[] b(byte[]) -> getKey byte[] b(byte[],byte[]) -> decrypt byte[] d(java.lang.String) -> getKey java.lang.String a(byte,char[]) -> a java.lang.String a(java.io.File) -> getHash java.lang.String a(java.lang.String) -> c java.lang.String b(java.lang.String) -> encode
對 DEX 檔案進行加殼防護仍然是需要的,我們可以選擇整體 DEX 加固或者拆分 DEX 加固的方式,隱藏原始碼防止直接性的反編譯。拆分 DEX 加固需要注意 DEX 檔案的資料結構,選取 classdata 和 classcode 這兩部分,即使拆分出來也不會洩露 class 資料和位元組碼資料,反編譯出來也不完整,安全性較高。尤其是虛擬機器加固的方式,對位元組做一些變化處理,即使把替換後的資料恢復了,也不會變形成為之前的位元組碼,安全係數較高。
網易雲 Android 應用加固 免費試用,有效防止應用被逆向分析、反編譯、二次打包,核心功能包括 DEX 加固,SO 加密保護,記憶體防 Dump 保護,防偵錯程式,防模擬器等。
相關文章:
【推薦】 【專家坐堂】四種併發程式設計模型簡介
【推薦】 Kubernetes網路方案的三大類別和六個場景