一、為什么要混淆
為了避免apk在發(fā)布后被用戶(hù)通過(guò)反編譯拿到源代碼和資源文件,然后修改資源和代碼之后就變成一個(gè)新的apk。而經(jīng)過(guò)混淆后的APK,即使被反編譯,也難以閱讀,注意混淆不是讓apk不能閱讀,而是加大閱讀的難度,為了避免勞動(dòng)成果被竊取,也避免出現(xiàn)安全漏洞和隱患,所以在apk發(fā)布之前一定要進(jìn)行混淆。
二、混淆的原理
Java是一種跨平臺(tái)、解釋型語(yǔ)言,Java源代碼編譯成的class文件中有大量包含語(yǔ)義的變量名、方法名的信息,很容易被反編譯為Java源代碼。為了防止這種現(xiàn)象,我們可以對(duì)Java字節(jié)碼進(jìn)行混淆?;煜粌H能將代碼中的類(lèi)名、字段、方法名變?yōu)闊o(wú)意義的名稱(chēng),保護(hù)代碼,也由于移除無(wú)用的類(lèi)、方法,并使用簡(jiǎn)短名稱(chēng)對(duì)類(lèi)、字段、方法進(jìn)行重命名縮小了程序的大小。
ProGuard由shrink、optimize、obfuscate和preverify四個(gè)步驟組成,每個(gè)步驟都是可選的,需要哪些步驟都可以在腳本中配置。參見(jiàn)ProGuard官方介紹。
壓縮(Shrink):默認(rèn)開(kāi)啟,偵測(cè)并移除代碼中無(wú)用的類(lèi)、字段、方法和特性,減少應(yīng)用體積,并且會(huì)在優(yōu)化動(dòng)作執(zhí)行之后再次執(zhí)行(因?yàn)閮?yōu)化后可能會(huì)再次暴露一些未使用的類(lèi)和成員)。
-dontshrink 關(guān)閉混淆
優(yōu)化(Optimize):默認(rèn)開(kāi)啟,分析和優(yōu)化字節(jié)碼,讓?xiě)?yīng)用運(yùn)行的更快。
-dontoptimize 關(guān)閉優(yōu)化,默認(rèn)混淆配置文件開(kāi)始
-optimizationpasses n 表示proguard對(duì)代碼進(jìn)行迭代優(yōu)化的次數(shù),Android一般為5
混淆(Obfuscate):默認(rèn)開(kāi)啟,使用a、b、c、d這樣簡(jiǎn)短而無(wú)意義的名稱(chēng),對(duì)類(lèi)、字段和方法進(jìn)行重命名,增大反編譯難度。
-dontobfuscate 關(guān)閉混淆
上面三個(gè)步驟使代碼大小更小、更高效,也更難被逆向工程。
預(yù)檢(Preverify):在java平臺(tái)上對(duì)處理后的代碼進(jìn)行預(yù)檢。
混淆流程圖:
Proguard讀入input jars(or wars,zip or directories),經(jīng)過(guò)四個(gè)步驟生成處理之后的jars(or wars,ears,zips or directories),Optimization步驟可選擇多次進(jìn)行。
為了確定哪些代碼應(yīng)該被保留,哪些代碼應(yīng)該被移除或混淆,需要確定一個(gè)或多個(gè)Entry Point。Entry Point經(jīng)常是帶有main methods,applets,midlets的classes,它們?cè)诨煜^(guò)程中會(huì)被保留。
Proguard的幾個(gè)步驟如何處理Entry Points。
(1).在壓縮階段,Proguard從上述E