Android代碼混淆使用

Apk文件被反編譯出來能被獲取到里面的代碼。對于這種情況捂齐,我們可以對項目代碼進行混淆蛮放,隨機生成難理解的類名,方法名奠宜,讓代碼難以閱讀包颁,加大功能被盜取的難度⊙拐妫混淆可以起到壓縮Apk娩嚼,混淆文件,預檢滴肿,優(yōu)化的作用岳悟。

1. 使用方式,在gradle文件中設置minifyEnabled為true即可開啟混淆

    buildTypes {
        release {
            minifyEnabled ture  //是否開啟代碼混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

混淆內容在proguard-android.txt或者proguard-rules.pro文件中寫泼差。

2. 混淆設置參數(shù)

-optimizationpasses 4 代碼混淆的壓縮比例贵少,值介于0-7

-dontusemixedcaseclassnames 混淆后類型都為小寫

-dontskipnonpubliclibraryclasses 不去忽略非公共的庫類

-dontoptimize 不優(yōu)化輸入的類文件

-dontpreverify 不做預校驗的操作

-ignorewarnings 忽略警告

-verbose 混淆時是否記錄日志

-keepattributes Annotation 保護注解

-printmapping proguardMapping.txt 生成原類名和混淆后的類名的映射文件mapping文件

-optimizations !code/simplification/cast,!field/,!class/merging/ 指定混淆是采用的算法

3. 保持不被混淆的設置

保持某個包下所有類不混淆
-keep class 你的實體類所在的包.** { *; }
四大組件、View體系等不混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.multidex.MultiDexApplication
-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.preference.Preference
-keep public class * extends android.view.View
-keep class android.support.** {*;}
-keep public class * extends android.support.v4.**

-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);
}

-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}
保持 native 方法不被混淆
-keepclasseswithmembernames class * {  
    native <methods>;
}
Serializable
-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();
}
保持枚舉enum類不被混淆
-keepclassmembers enum * {  
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {   
    public static final android.os.Parcelable$Creator *;
}
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);
}
support design
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
然后就是項目中使用到的第三方包不混淆拴驮,下面有示例春瞬。

4. 完整混淆示例:

#---------------------------------基本指令區(qū)-----------------------

-optimizationpasses 5  #指定代碼的壓縮級別
-dontpreverify  #預校驗
-verbose  #指定日志級別
-dontskipnonpubliclibraryclassmembers
-dontusemixedcaseclassnames  #包名不混合大小寫
-ignorewarnings  #忽略警告
-printmapping proguardMapping.txt  #生成原類名和混淆后的類名的映射文件
-optimizations !code/simplification/cast,!field/*,!class/merging/*  #混淆時所采用的算法
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable


#---------------------------------默認保留區(qū)------------------------

#四大組件柴信、View體系等
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.multidex.MultiDexApplication
-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.preference.Preference
-keep public class * extends android.view.View
-keep class android.support.** {*;}

-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);
}

-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

#Serializable
-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 *(*Event);
}

#enum
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclassmembers class * {
   public <init> (org.json.JSONObject);
}

-keepclasseswithmembernames class * {
    native <methods>;
}

#Parcelable
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

#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);
}

# support design
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }


#---------------------------------第三方包示例-------------------------

#okhttp3.x
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.{*;}
-dontwarn javax.annotation.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.ConscryptPlatform

#retrofit
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-dontwarn okio.**

#Rxjava RxAndroid
-dontwarn rx.*
-dontwarn sun.misc.**

#Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

#Gson
-keep class com.google.gson.** {*;}
-keep class com.google.**{*;}
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }

#Lambda表達式
-keep class java.lang.invoke.** {*;}
-dontwarn java.lang.invoke.**

#高徳地圖
#3D 地圖
-keepclass com.amap.api.mapcore.**{*;}
-keepclass com.amap.api.maps.**{*;}
-keepclass com.autonavi.amap.mapcore.*{*;}
#定位
-keepclass com.amap.api.location.**{*;}
-keepclass com.loc.**{*;}
-keepclass com.amap.api.fence.**{*;}
-keepclass com.autonavi.aps.amapapi.model.**{*;}
# 搜索
-keepclass com.amap.api.services.**{*;}
# 2D地圖
-keepclass com.amap.api.maps2d.**{*;}
-keepclass com.amap.api.mapcore2d.**{*;}
# 導航
-keepclass com.amap.api.navi.**{*;}
-keepclass com.autonavi.**{*;}


#ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

#eventbus 3.0
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

#ARouter組件化
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep public class com.alibaba.android.arouter.facade.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}

自己試著用一個簡單的項目加入混淆套啤,打個包試試效果吧。

混淆sdk和避免混淆部分類實戰(zhàn):

1.在proguard-rules.pro文件下配置混淆參數(shù)和-keep的類或者包:

# 混淆時所采用的算法
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
#指定代碼的壓縮級別
-optimizationpasses 5
-allowaccessmodification
# 優(yōu)化 不優(yōu)化輸入的類文件
-dontoptimize
# 預校驗
-dontpreverify
# 包名不混合大小寫
-dontusemixedcaseclassnames
# 混淆時是否記錄日志
-verbose
# 保護注解
-keepattributes *Annotation*
# 忽略警告
-ignorewarnings

-printconfiguration build/intermediates/proguard-files/full-r8-config.txt

# 保持哪些類不被混淆
#保持sdk中需要暴露功能的包下所有類不被混淆
-keep class com.libo.networkmonitor.api.**{*;}
-keep class com.libo.networkmonitor.impl.NetWorkListener

2.設置release模式下開啟混淆:

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
            proguardFiles 'proguard-rules.pro'
        }
    }

3.打出sdk的aar包随常,并進行引用查看混淆情況:


可以看到潜沦,打出來的aar包,keep的類可以看到原寫法绪氛,因為上面NetworkMonitor的類避免了混淆可以看得到唆鸡,其余被混淆的類變成了看不出來的字母。

Mapping文件使用

列出了原始的類枣察,方法和字段名與混淆后代碼間的映射争占。這個文件很重要,當你從release版本中收到一個bug報告時序目,混淆后的文件看不出問題臂痕,可以用它來翻譯被混淆的代碼。
mapping目錄在 \app\build\outputs\mapping\release
示例:


或者將mapping文件上傳到監(jiān)測平臺猿涨,報出問題就能直接閱讀了握童。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叛赚,隨后出現(xiàn)的幾起案子澡绩,更是在濱河造成了極大的恐慌稽揭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肥卡,死亡現(xiàn)場離奇詭異溪掀,居然都是意外死亡,警方通過查閱死者的電腦和手機步鉴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門膨桥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人唠叛,你說我怎么就攤上這事只嚣。” “怎么了艺沼?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵册舞,是天一觀的道長。 經(jīng)常有香客問我障般,道長调鲸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任挽荡,我火速辦了婚禮藐石,結果婚禮上,老公的妹妹穿的比我還像新娘定拟。我一直安慰自己于微,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布青自。 她就那樣靜靜地躺著株依,像睡著了一般。 火紅的嫁衣襯著肌膚如雪延窜。 梳的紋絲不亂的頭發(fā)上恋腕,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音逆瑞,去河邊找鬼荠藤。 笑死,一個胖子當著我的面吹牛获高,可吹牛的內容都是我干的哈肖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谋减,長吁一口氣:“原來是場噩夢啊……” “哼牡彻!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤庄吼,失蹤者是張志新(化名)和其女友劉穎缎除,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體总寻,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡器罐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了渐行。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轰坊。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖祟印,靈堂內的尸體忽然破棺而出肴沫,到底是詐尸還是另有隱情,我是刑警寧澤蕴忆,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布颤芬,位于F島的核電站,受9級特大地震影響套鹅,放射性物質發(fā)生泄漏站蝠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一卓鹿、第九天 我趴在偏房一處隱蔽的房頂上張望菱魔。 院中可真熱鬧,春花似錦吟孙、人聲如沸澜倦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肥隆。三九已至既荚,卻和暖如春稚失,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恰聘。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工句各, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晴叨。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親耻矮。 傳聞我的和親對象是個殘疾皇子贸毕,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容