Android代碼混淆與反編譯

1.混淆的目的

用於保護APP不被破解和逆向分析。javascript

2.混淆的意義

proguard經過移除沒有用到的代碼以及經過特定規則重命名類、變量、方法來壓縮、優化、混淆你的代碼。這樣作可讓你的apk更小,更難被逆向分析。因爲能夠提升被逆向分析的難度,對相關功能安全敏感的應用使用它是十分必要的。混淆本質上是不能阻止反編譯的,只能增長反編譯之後閱讀理解的難度罷了。java

3.混淆在代碼優化方面

1.刪除冗餘代碼,記錄代碼和元數據,未使用的資源和本機庫
2.Dex文件的自動分割超過Dex格式強加的大小限制
3.資源和代碼優化android

4.在build.grandle添加

buildTypes {
    release {
        signingConfig signingConfigs.release
        shrinkResources true // 移出無用的res文件
        minifyEnabled true // 是否須要使用下面的混淆文件進行代碼混淆
        zipAlignEnabled true // Zipalign優化
        proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
    }
}

注意:工程中出現多個module時,只須要修改app底下build.gradle中的minifyEnabled true便可。git

5.在proguard-rules.pro中加入混淆規則

# ============================================= 基礎規則 =============================================
# 指定代碼的壓縮級別
-optimizationpasses 5
# 混淆後類名都爲小寫
 -dontusemixedcaseclassnames
# 指定不去忽略非公共的庫的類
-dontskipnonpubliclibraryclasses
# 指定不去忽略非公共的庫的類的成員
-dontskipnonpubliclibraryclassmembers
# 不作預校驗的操做
-dontpreverify
# 混淆時是否記錄日誌
-verbose
# 混淆時所採用的算法
-optimizations !code/simplification/cast,!field/*,!class/merging/* # 不混淆Annotation -keepattributes *Annotation*,InnerClasses # 不混淆泛型 -keepattributes Signature # 拋出異常時保留代碼行號 -keepattributes SourceFile,LineNumberTable # 列出沒有被混淆的類 -printseeds seeds.txt # 列出從APK中移除的代碼 -printusage unused.txt # 混淆先後命名的變化 -printmapping mapping.text # 這些資源爲api資源,保持不被混淆 -dontwarn android.support.** -keep public class * extends android.support.v4.** -keep public class * extends android.support.v7.** -keep public class * extends android.support.annotation.** -keep public class * extends android.app.Application -keep public class * extends android.view.View -keep public class * extends android.app.Service -keep public class * extends android.app.Fragment -keep public class * extends android.app.Activity -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class * extends android.preference.Preference -keep public class * extends android.app.backup.BackupAgentHelper -keep public class com.android.vending.licensing.ILicensingService -keep class android.support.** { *; } -keep class android.support.v4.** { <fields>; <methods>; } -keep interface android.support.v4.app.** { <fields>; <methods>; } -keepclasseswithmembernames class * { native <methods>; } -keepclassmembers public class * extends android.view.View { void set*(***); *** get*(); } -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } # R文件 -keep class **.R$* { *; } # 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); } # ============================================= 自定義混淆 ============================================= # ......

6.jar混淆

默認已經將lib目錄中的 jar 都已經添加到打包腳本中,因此不須要再次手動添加,不然會出現「java.io.IOException: The same input jar is specified twice」 錯誤。github

7.常見的第三方庫混淆代碼

友盟
-dontwarn com.google.android.maps.**
-dontwarn android.webkit.WebView
-dontwarn com.umeng.**
-dontwarn com.tencent.weibo.sdk.**
-dontwarn com.facebook.**
-keep public class javax.** -keep public class android.webkit.** -keep enum com.facebook.** -keepattributes Exceptions,InnerClasses,Signature -keep public interface com.facebook.** -keep public interface com.tencent.** -keep public interface com.umeng.socialize.** -keep public interface com.umeng.socialize.sensor.** -keep public interface com.umeng.scrshot.** -keep class com.android.dingtalk.share.ddsharemodule.** { 
 
   
    *;
}
-keep public class com.umeng.socialize.* { 
 
   
    *;
}
-keep class com.facebook.**
-keep class com.facebook.** {
    *;
}
-keep class com.umeng.scrshot.**
-keep public class com.tencent.** { 
 
   
    *;
}
-keep class com.umeng.socialize.sensor.**
-keep class com.umeng.socialize.handler.**
-keep class com.umeng.socialize.handler.*
-keep class com.umeng.weixin.handler.**
-keep class com.umeng.weixin.handler.*
-keep class com.umeng.qq.handler.**
-keep class com.umeng.qq.handler.*
-keep class UMMoreHandler{
    *;
}
-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {
    *;
}
-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {
    *;
}
-keep class im.yixin.sdk.api.YXMessage {
    *;
}
-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{
    *;
}
-keep class com.tencent.mm.sdk.** {
    *;
}
-keep class com.tencent.mm.opensdk.** {
    *;
}
-dontwarn twitter4j.**
-keep class twitter4j.** {
    *;
}
-keep class com.tencent.** {
    *;
}
-dontwarn com.tencent.**
-keep public class com.umeng.com.umeng.soexample.R$*{ 
 
   
    public static final int *;
}
-keep public class com.linkedin.android.mobilesdk.R$*{ 
 
   
    public static final int *;
}
-keep class com.tencent.open.TDialog$*
-keep class com.tencent.open.TDialog$* {
    *;
}
-keep class com.tencent.open.PKDialog
-keep class com.tencent.open.PKDialog {
    *;
}
-keep class com.tencent.open.PKDialog$*
-keep class com.tencent.open.PKDialog$* {
    *;
}
-keep class com.sina.** {
    *;
}
-dontwarn com.sina.**
-keep class  com.alipay.share.sdk.** {
    *;
}
-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}
-keep class com.linkedin.** {
    *;
}
極光推送
-dontwarn cn.jpush.**
-keep class cn.jpush.** {
    *;
}
-keep class * extends cn.jpush.android.helpers.JPushMessageReceiver {
    *;
}
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** {
    *;
}
OkHttp
-dontwarn okio.**
-dontwarn okhttp3.logging.**
-keep class okhttp3.internal.** {
    *;
}
-dontwarn javax.annotation.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** {
    *;
}
RxJava,RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
   long producerIndex;
   long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
Gson
-dontwarn com.google.**
-keep class com.google.gson.** {
    *;
}
-keep class com.google.gson.stream.** {
    *;
}
-keep class com.google.protobuf.** {
    *;
}
Glide
-keep public class * implements com.bumptech.glide.module.GlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { 
 
    
  **[] $VALUES;
  public *;
}
# Glide自定義(ImageLoaderModule)緩存時添加以下混淆
-keepnames class com.common.imageloader.ImageLoaderModule
Glide v4.0
-keep public class * implements com.bumptech.glide.module.GlideModule -keep public class * extends com.bumptech.glide.AppGlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { 
 
   
  **[] $VALUES;
  public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
# Glide自定義(ImageLoaderModule)緩存時添加以下混淆
-keepnames class com.common.imageloader.ImageLoaderModule

8.經過反編譯檢測混淆是否成功

注:反編譯是不道德的行爲,可根據需求反編譯本身的工程便可。切勿編譯他人工程。
反編譯有多種方式,這裏使用dex2jar進行反編譯。web

  • 下載反編譯工具
點擊下載dex2jar
點擊下載jd-gui-windows


  • 解壓後將你的apk後綴改成zip格式。
    如:sample-app.apk改成sample-app.zip
  • 將sample-app.zip進行解壓。獲得classes.dex文件,將classes.dex複製到與dex2jar解壓後同目錄下。
    classes.dex
  • 調用Dos命令,輸入以下命令進行轉換,(AndroidTools爲我本身經常使用工具目錄下,可根據本身的目錄地址調用)

Dex2jar是將Android的.dex文件轉換成Java的.class格式的文件,這僅是將一種二進制格式轉換成另一種二進制格式,並非轉換Java源代碼。 算法

dex2jar.bat classes.dex
  • 命令執行成功後會生成一個對應的classes_dex2jar.jar文件,用jd-gui-windows打開classes_dex2jar.jar文件即可看到包名和類型都變成了小寫abcd…..等就表明着要混淆的文件已經混淆成功。
    混淆成功示例

本文分享 CSDN - 秦川小將。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。windows

相關文章
相關標籤/搜索