1. 程式人生 > >Android開發中的程式碼混淆

Android開發中的程式碼混淆

前言

  程式碼混淆是在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後,檢視混淆過的類和方法名是否變為字母來判斷是否混淆成功,如圖:
這裡寫圖片描述

這裡寫圖片描述