search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

Android混淆總結篇

前言

這陣子自己的心又長草了,靜不下來~又挺迷茫的!在這個紛紛跳槽的季節,感覺還是應該讓自己靜下心來多學習學習。還是寫寫博客,總結總結~梳理下心裡的野草。

上個月跟朋友討論了這麼一問題:「項目上線之後由於代碼被混淆的緣故,導致收集到的異常信息看著很困難」,剛好最近在複習混淆方面的知識,在總結混淆的知識點的同時,順便探討總結下這問題。項目上線肯定避免不了的是對項目進行混淆、打包、簽名和發布,可能還有APK加固等等,其實這流程並不複雜,都有一套明確的流程,所以整起來也不是很困難。而上面提到的「混淆導致上線后的異常信息查看起來挺困難」這問題,這幾天也大概探討完,打算記錄在下篇文章~~那麼這篇文章先開始扯淡吧!

Ⅰ.簡述

混淆的概念:將Android項目進行打包之時,可以將項目里的包名、類名、變數名進行更改,使得代碼不容易泄露,類似於對其apk中的文件加密.

混淆的作用

  • 1.增加Apk反編譯之後代碼泄露的困難性
  • 2.生成的apk體積會縮小

什麼是混淆?

Android SDK 本身就提供混淆的功能,將混淆開關進行開啟后,開發者需要做的是對Android Studio工程項目中的proguard-rules.pro文件進行混淆白名單的配置.

那麼什麼是混淆白名單呢?其實就是指定一些包名、類名、變數等不可以被混淆。假設沒指定白名單就進行混淆打包,而某某類的類名被混淆了(假設變成了a),那麼可能其他引用或使用該類的類就找不到該類,說不定應用就會因此崩潰或是導致相應的功能無法使用.

那麼所謂的混淆也就是配置混淆白名單,那麼下面看看混淆之後的apk的內部結構.可以看到紅圈圈出來的部分都是進行混淆的,而有部分是沒有進行混淆的,比如黑圈圈出來的屬性動畫兼容庫nineoldandroids,其包名類名就沒有變成abc這樣的代替符

上面我是用apk逆向助手對apk進行反編譯,市場上的反編譯工具有很多種,可以自行Google搜索。

補充

本篇文章記錄的混淆知識點主要基於Android Studio開發工具。

Ⅱ.開始混淆

1.開啟混淆開關

混淆的開關在項目/app/build.gradle文件里,看下面的截圖,將minifyEnabled設置為true就是開啟混淆,關於下面的配置代碼可以直接寫在build.gradle文件的android節點下

代碼混淆一般是在上線前的apk打包才會去配置混淆開啟,要是忘記配置的代碼,那怎麼辦呢?直接進去Project Structrue,然後根據下面截圖所標識的進行設置,如此這般,只要打release包就是開啟混淆進行打包的.

2.設置混淆白名單

基於Android Studio創建的項目里有一文件名稱為」proguard-rules.pro」的文件,路徑是」項目/app/proguard-rules.pro」,沒經過編輯之前,裡面只有一些註釋的代碼,如下圖

那麼設置的混淆白名單又該怎麼寫呢?Google搜索的話會有很多博客上的模板可以複製進行套用.如下圖,那麼就可以進行參考,下面第三部分將常用的混淆指令和對應的註釋都列舉出來,基本常用的都有,有疏漏的那就自行搜索下.

Ⅲ.實際混淆指令

在應用中,大多數的混淆指令是已經確定的了,比如下面的基本指令部分,基本不用修改的。而其他的混淆指令,比如第三方的SDK/框架的混淆指令一般在其官方文檔都可以找到,所以相對來說還是比較方便的,下面將這幾天歸類的混淆指令總結下.

基本指令:

# 設置混淆的壓縮比率 0 ~ 7 -optimizationpasses 5 # 混淆后類名都為小寫 Aa aA -dontusemixedcaseclassnames # 指定不去忽略非公共庫的類 -dontskipnonpubliclibraryclasses #不做預校驗的操作 -dontpreverify # 混淆時不記錄日誌 -verbose # 混淆採用的演算法. -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #保留代碼行號,方便異常信息的追蹤 -keepattributes SourceFileLineNumberTable #dump文件列出apk包內所有class的內部結構 -dump class_files.txt #seeds.txt文件列出未混淆的類和成員 -printseeds seeds.txt #usage.txt文件列出從apk中刪除的代碼 -printusage unused.txt #mapping文件列出混淆前後的映射 -printmapping mapping.txt

避免混淆Android基本組件,下面是兼容性比較高的規則:

-keep public class * extendsandroid.app.Activity -keep public class * extendsandroid.app.Application -keep public class * extendsandroid.app.Service -keep public class * extendsandroid.content.BroadcastReceiver -keep public class * extendsandroid.content.ContentProvider -keep public class * extendsandroid.app.backup.BackupAgentHelper -keep public class * extendsandroid.preference.Preference -keep public classcom.android.vending.licensing.ILicensingService #不提示V4包下錯誤警告 -dontwarn android.support.v4.** #保持下面的V4兼容包的類不被混淆 -keep classandroid.support.v4.**{*;}

; }-keep

publicclass * extendsandroid.view.View{

*** get*;

void

set*(***);

public

(android.content.Context);

public

(android.content.Context, android.util.AttributeSet);

public

(android.content.Context, android.util.AttributeSet,

int

); }

避免混淆枚舉類

-keepclassmembers enum * { publicstatic ** values; publicstatic ** valueOf(java.lang.String); }

避免混淆序列化類

#不混淆Parcelable和它的實現子類,還有Creator成員變數 -keep class * implementsandroid.os.Parcelable {publicstaticfinal android.os.Parcelable$Creator *; } #不混淆Serializable和它的實現子類、其成員變數 -keepclassmembers class * implementsjava.io.Serializable {staticfinallong serialVersionUID; privatestaticfinal java.io.ObjectStreamField serialPersistentFields; privatevoid writeObject(java.io.ObjectOutputStream); privatevoid readObject(java.io.ObjectInputStream); java.lang.Object writeReplace; java.lang.Object readResolve; }

避免混淆JSON類的構造函數

#使用GSON、fastjson等框架時,所寫的JSON對象類不混淆,否則無法將JSON解析成對應的對象 -

keepclassmembers class * {

public(org.json.JSONObject); }

避免混淆第三方SDK

# ==================環信混淆start================= -keep class com.hyphenate.** {*;} -dontwarn com.hyphenate.** # ==================環信endspan># ==================bugly startspan> -dontwarn com.tencent.bugly.** -keep public interface com.tencent.** -keep public class com.tencent.** {*;} -keep public class com.tencent.bugly.**{*;}# ==================bugly endspan># ===============百度定位 startspan> -keep class vi.com.gdi.** { *; } -keep public class com.baidu.** {*;} -keep public class com.mobclick.** {*;} -dontwarn com.baidu.mapapi.utils.* -dontwarn com.baidu.platform.comapi.b.* -dontwarn com.baidu.platform.comapi.map.* # ===============百度定位 endspan> //備註:其他的第三方包的混淆指令可以到其官方文檔去拷貝

避免混淆第三方框架

# ==================picasso框架 start=============== -

keep classcom.parse.*{ *; }

-

dontwarn com.parse.**

-

dontwarn com.squareup.picasso.**

-

keepclasseswithmembernames class * {

native; } # ==================picasso end # ==================EventBus start================= -

keep classorg.greenrobot.** {*;}

-

keep classde.greenrobot.** {*;}

-

keepclassmembers class ** {

public void onEvent*(**); void onEvent*(**); } # ==================EventBus end=================== # ==================okhttp start=================== -

dontwarn com.squareup.okhttp.**

-

keep classcom.squareup.okhttp.** { *;}

-

dontwarn okio.**

-

keep classokio.**{*;}

-

keep interface okio.**{*;}

# ==================okhttp end

//備註:其它框架的混淆指令可以到其官方文檔去拷貝

其它混淆指令

#避免混淆屬性動畫兼容庫 -dontwarn com.nineoldandroids.* -keep class com.nineoldandroids.** { *;} #不混淆泛型 -keepattributes Signature #避免混淆註解類 -dontwarn android.annotation -keepattributes *Annotation* #避免混淆內部類 -keepattributes InnerClasses #避免混淆實體類,修改成你對應的包名 -keep class com.wyk.test.bean.** { *; } -keep class com.wyk.test.event.** { *; } -keep public class com.wyk.test.utils.eventbus.** { *;}#避免混淆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;.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; } #避免混淆js相關的介面 -keepattributes *JavascriptInterface* -keep class com.wyk.test.js.** { *; }

Ⅳ.混淆配置注意點

1.假設當配置 「-libraryjars libs/jpush-android-2.1.6.jar」 對jar包進行混淆白名單化,如果gradle報錯的話,可以考慮註釋掉(格式:-libraryjars [jar包名])這樣的配置信息.採用下面的配置信息進行替換

-dontwarn cn.jpush.** -keep classcn.jpush.** { *; }

2.下面是對屬性動畫兼容庫的混淆白名單配置信息,剛開始覺得只是保持com.nineoldandroids包下的類不被混淆,後來經過反編譯混淆后的apk包,發現效果是」不混淆該class com.nineoldandroids包下的類、子包和子包的類,也不混淆其中類的成員變數.

-keep classcom.nineoldandroids.** { *;}

Ⅴ.其它

1.混淆套用模板

個人覺得下面鏈接的博文就寫得非常好,所以可以進行參考.

參考博文:5分鐘搞定android混淆

2.資源混淆

Proguard混淆只是針對代碼進行混淆,解壓之後的apk包還是能看到項目的資源文件和其名稱,比如布局、logo圖片等等.這時可以選擇對資源文件進行混淆,下面兩個鏈接是騰訊推出的資源混淆工具相關的博文,可以參考.

資源混淆工具相關的博文

http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=42

3.加固

為了使得apk更加不容易被破解,混淆之後還可以對apk進行加固,現今市面上的加固技術有很多種,有360加固、愛加密加固、梆梆加固等等,可以自行選擇,加固技術就相當於給apk包加多一個殼,相應的體積也會增大,大概增大1M~2M左右,需要的話可以自行搜索,加固還是挺簡單的.

4.參考鏈接



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦