Android Apk 程式碼混淆與資原始檔混淆實戰
Android專案在完工釋出時,需要對程式碼和資原始檔進行混淆,目的有兩個:
1⃣️減小壓縮包的體積
2⃣️防止程式碼被反編譯後惡意利用
Android Apk混淆分兩步走:
1⃣️混淆程式碼
2⃣️混淆資原始檔
本人的開發環境為:
Operation System:Mac OS 10.10.5
Android Studio:2.0 Preview 5
Gradle Plugin:2.0.0-alpha3
buildToolsVersion:23.0.2
minSdkVersion:14
compileSdkVersion :23
targetSdkVersion:23
一.混淆程式碼
1.在build.gradle(Module app)檔案中開啟混淆器Proguard
buildTypes {
release {
minifyEnabled true //開啟混淆
shrinkResources true //去掉未使用的資原始檔
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
這裡介紹一下ProGuard,它是AndroidStudio裡新的混淆打包工具。它通過重新命名類名、變數名以及方法名等方式達到優化、混淆程式碼的效果。處理之後的程式碼程式碼名稱短小且亂序無規律,從而可以達到減小Apk的體積以及加大反編譯的難度的目的。
2.通過上面的一步,我們就再次打包之後的Apk的程式碼就已經被混淆了。如果你覺得這就結束了,那你就太天真了。
事實上,有一些程式碼我們是不能混淆的,否則會出現各種各樣的錯誤。官網給出了三種可能會發生錯誤的情況:
1⃣️一個只在AndroidManifest.xml檔案中引用的類
2⃣️一個被JNI層函式呼叫的函式
3⃣️動態呼叫的類或方法(反射…)
我們可以通過 如下方式指出不想被混淆的程式碼:
-keep public class <MyClass>
關於不同程式碼型別的混淆方式,請參考官網的 ProGuard Usage。
一般一個完整的專案裡會用到各種各樣的開源框架以及第三方類庫,也需要給出對應的混淆規則。一般的框架以及類庫都會給出對應的混淆規則,拿我最喜歡用的註解框架
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
如果你的專案裡使用了ButterKnife,而且你又想混淆你的程式碼,那就需要把上面的混淆規則全部加入你的proguard-rules.pro檔案中。
注意:ProGuard預設不混淆四大元件(Activity,Service,BroadcastReceiver,ContentProvider)及其子類。
二.混淆資原始檔
經過上面的程式碼混淆,我們已經能夠實現程式碼的混淆。很大程度上減小了Apk的大小,增加了反編譯的難度。但是這還不夠。如果你把Apk檔案直接解壓出來,你會看到下面的結果:
可以看到,資原始檔都是可以清楚地拿到的,這樣就可能很容易就被看懂,甚至被惡意利用。現在我們就要設法把他們的名字都混淆一下,讓其他人反編譯了也看不懂,從而保護我們的軟體不受侵害。
關於資原始檔的混淆,這裡推薦兩個教程,一個是從更改原始碼的方式入手,一個是從resources.arsc入手。大家可以看一下參考一下: