前言
前段時(shí)間有用戶反饋下載的App有廣告的彈窗目锭,但是我們的項(xiàng)目并沒有插入廣告的功能的限府∪搴埃考慮到可能是因?yàn)槲覀兩暇€的項(xiàng)目并沒有做混淆的處理,就被有心人植入了廣告后豫。所以當(dāng)務(wù)之急就是添加混淆悉尾,順便復(fù)習(xí)一下混淆。
混淆簡(jiǎn)介
- Android代碼混淆是一種應(yīng)用源代碼保護(hù)技術(shù)挫酿,用來(lái)防止別人對(duì)apk進(jìn)行逆向分析构眯;
- 從Android2.3開始,Google就在SDK中加入了ProGuard的工具早龟,使用它來(lái)進(jìn)行代碼的混淆惫霸。
- ProGuard是一個(gè)壓縮、優(yōu)化和混淆Java字節(jié)碼文件的免費(fèi)工具拄衰, 其作用有以下幾點(diǎn):
- 刪除代碼中的注釋它褪;
- 刪除代碼中沒有用到的類、字段翘悉、方法和屬性茫打;
- 會(huì)把代碼中的包名、類名妖混、方法名老赤,變量名等修改為abcd...這種沒有意義的名字,使得反編譯出來(lái)的代 碼難以閱讀制市,從而達(dá)到防止apk被破解和逆向分析的目的抬旺;
- 經(jīng)過ProGuard混淆后,apk安裝包會(huì)變邢殚埂开财;
- 在實(shí)際項(xiàng)目中,有些Java類不能進(jìn)行混淆误褪,需要配置混淆規(guī)則责鳍;
- 在實(shí)際項(xiàng)目中,打包apk時(shí)一般都需要進(jìn)行混淆處理兽间;
- 混淆后會(huì)生成mapping.txt文件历葛,該文件需要存檔以便用來(lái)還原和查看混淆后的出錯(cuò)日志;
開啟混淆
在項(xiàng)目的build.gradle文件中打開混淆的開關(guān)嘀略,然后在proguard-rules.pro文件中添加混淆規(guī)則即可
buildTypes {
debug {
//是否進(jìn)行混淆
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true //開啟混淆只需要設(shè)置為true即可
//添加混淆規(guī)則的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
添加混淆規(guī)則
首先介紹一下添加混淆規(guī)則中常用到的一些命令的含義恤溶,方便我們理解并能夠自行添加屬于我們項(xiàng)目中的一些混淆規(guī)則,然后再介紹一下項(xiàng)目中一些通用的混淆規(guī)則帜羊。
1. 混淆規(guī)則常用到的命令含義:
- 保留該包下的類名不會(huì)被混淆咒程,但是該包的子包的類名還是會(huì)被混淆
-keep class packageName.*
- 保留該包及其子包的類名不會(huì)被混淆
-keep class packageName.**
- 保留類名及其該類的內(nèi)容不會(huì)被混淆(包括變量名,方法名等)
-keep class packageName.* {*;}
- 不保留類名只保留該類的方法名讼育、變量名等不會(huì)被混淆
-keepclassmembers class packageName.*{*;}
- 保留所有繼承某類的子類不會(huì)被混淆(implement同理)
-keep public class * extends android.app.Activity
- 保留該內(nèi)部類中所有的public方法名帐姻、變量名不會(huì)被混淆
-keepclassmembers class packageName$內(nèi)部類名 { //"$"的含義是保留某類的內(nèi)部類不會(huì)被混淆
public *;
}
- <init>粮宛、<fields>、 <methods>的含義和使用
<init>; //匹配所有的構(gòu)造器
<fields>; //匹配所有的域
<methods>; //匹配所有的方法
//可以在以上的命令前加上public卖宠、private、native等來(lái)進(jìn)一步指定不被混淆的內(nèi)容
//也可以在以上的命令后面加上參數(shù)忧饭,來(lái)指定含有特定的參數(shù)構(gòu)造方法或者方法名不會(huì)被混淆
-keep class packageName{
public <init>; //保留所有的public的構(gòu)造方法不會(huì)被混淆
}
-keep class packageName{
public <init>(java.lang.String); //保留所有的public的構(gòu)造方法并且參數(shù)是String對(duì)象扛伍,不會(huì)被混淆
}
-keep class packageName{ //保留所有的private的方法名不會(huì)被混淆
private <methods>;
}
- 含有Keep關(guān)鍵字的含義(移除是指在壓縮時(shí)(Shrinking)是否會(huì)被刪除,需要開啟壓縮)
保留 | 防止被移除或者被重命名 | 防止被重命名 |
---|---|---|
類和類成員 | -keep | -keepnames |
僅類成員 | -keepclassmembers | -keepclassmembernames |
如果擁有某成員词裤,保留類和類成員 | -keepclasseswithmembers | -keepclasseswithmembernames |
2. 通用的一些混淆規(guī)則:
注:四大組件刺洒、Fragment、自定義控件不需要添加混淆規(guī)則吼砂,因?yàn)檫@些默認(rèn)是不會(huì)被混淆的逆航,所以網(wǎng)上很多四大組件的混淆規(guī)則是沒必要添加的。
- 注解
-keepattributes *Annotation*
- R文件下面的資源
-keep class **.R$* {*;}
- 本地的native方法(JNI)
-keepclasseswithmembernames class * {
native <methods>;
}
- 反射(該packageName是被反射類的包名)
-keep class packageName{*;}
- JavaBean中的泛型
-keepattributes Signature
- JavaBean(如果使用了Gson進(jìn)行解析Json字符串渔肩,就需要添加JavaBean的混淆規(guī)則因俐,因?yàn)?strong>Gson使用了反射的原理)
-keep class packageName**
-keep class packageName**{*;}
- 枚舉
# 保留枚舉類不被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
- Parcelable序列化和Creator靜態(tài)成員變量
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
- Serializable序列化
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
- 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);
}
- 與JS交互
#Android4.2以上需要添加以下的兩個(gè)混淆配置
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
-keepclassmembers class packageName$內(nèi)部類名 {
public *;
}
- 第三方的Jar包、依賴周偎、SDK等
這個(gè)就需要查看項(xiàng)目中添加了那些第三方的Jar包抹剩、依賴、SDK了蓉坎,然后在其官網(wǎng)上或者Github找相應(yīng)的混淆規(guī)則澳眷,一般都會(huì)有的,如果沒有可以自己寫混淆規(guī)則蛉艾。根據(jù)上面介紹的一些常用的命令含義钳踊,一般都能滿足自己寫混淆規(guī)則了。