Android開發中的程式碼混淆
阿新 • • 發佈:2019-02-06
前言
程式碼混淆是在apk功能基本開發完成後進行的程式碼保護操作,混淆後的apk通過dex轉jar進行反編譯後,混淆部分的類名、方法名全部為英文字母,使反編譯者難以理解程式碼,達到程式碼保護的目的
gradle檔案配置
專案的build.gradle檔案配置如下:
buildTypes {
release {
// 開啟混淆
minifyEnabled true
// 載入預設混淆配置檔案
proguardFiles getDefaultProguardFile('proguard-android.txt' ), 'proguard-rules.pro'
// 簽名
signingConfig signingConfigs.release
// 移除無用的resourse資源
shrinkResources true
// Zipalign優化
zipAlignEnabled true
}
debug {
// 簽名
signingConfig signingConfigs.release
}
}
在打Release包時配置混淆即可,打debug包時開啟混淆,時間較慢,降低除錯效率
proguard-rules檔案配置
在專案的build.gradle檔案配置了載入預設混淆配置檔案路徑為專案中的proguard-rules.pro。proguard-rules檔案配置參考了: 5分鐘搞定android混淆 這篇檔案,寫得簡單易懂,值得參考
以下是我的配置內容:
#-------------------------------------------定製化區域----------------------------------------------
#---------------------------------1.實體類---------------------------------
-keep class com.zhumei.commercialscreen.bean.** { *; }
#-------------------------------------------------------------------------
#---------------------------------2.第三方包-------------------------------
# Okhttputils
-dontwarn com.zhy.http.**
-keep class com.zhy.http.**{*;}
# Okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
# Okio
-dontwarn okio.**
-keep class okio.**{*;}
# SwipeRecyclerView
-keepclasseswithmembers class android.support.v7.widget.RecyclerView$ViewHolder {
public final View *;
}
# Filedownloader
# Percent-support-extends
# IjkPlayer
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# Butterknife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-dontwarn butterknife.internal.ButterKnifeProcessor.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson Gson需要配置的javaBean目錄,在實體類中已經配置
# -keep class com.google.gson.examples.android.model.** { *; }
#-------------------------------------------------------------------------
#---------------------------------3.與js互相呼叫的類------------------------
#-------------------------------------------------------------------------
#---------------------------------4.反射相關的類和方法-----------------------
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
#-------------------------------------------基本不用動區域--------------------------------------------
#---------------------------------基本指令區----------------------------------
# 指定程式碼的壓縮級別,0-7之間
-optimizationpasses 5
# 混淆後類名均為小寫
-dontusemixedcaseclassnames
# 不去忽略非公共的庫和類
-dontskipnonpubliclibraryclasses
# 不優化輸入的類檔案
-dontoptimize
# 不去預校驗
-dontpreverify
# 生成原類名和混淆後的類名的對映檔案
-verbose
-printmapping proguardMapping.txt
# 混淆時所採用的演算法
-optimizations !code/simplification/cast,!field/*,!class/merging/*
# 不混淆註解和內部類
-keepattributes *Annotation*,InnerClasses
# 不混淆泛型 如果混淆報錯建議關掉
-keepattributes Signature
# 丟擲異常時保留程式碼行號
-keepattributes SourceFile,LineNumberTable
#----------------------------------------------------------------------------
#---------------------------------預設保留區---------------------------------
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keep class **.R$* {
*;
}
-keepclassmembers class * {
void *(**On*Event);
}
#----------------------------------------------------------------------------
#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, jav.lang.String);
}
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
打包測試
以上配置完成之後,即可打Release包測試混淆是否成功,在打Release包的時候可能會出現報錯情況,比如:
java.io.FileNotFoundException: ...\proguard-rules\release\aapt_rules.txt (系統找不到指定的路徑)
遇到這種情況需在選單欄選擇build –> Clean Project ,然後再build –> Make Project即可,然後就能在這個路徑下找到這個aapt_rules.txt檔案了,再次混淆就不會報同樣錯誤了
如果混淆沒有報錯就可以通過反編譯程式碼,將dex轉jar後,檢視混淆過的類和方法名是否變為字母來判斷是否混淆成功,如圖: