因?yàn)轫?xiàng)目源碼安全需要馏慨,最近研究了下proguard混淆源碼展东,在這里做一些分享。以下分享基于Android Studio滨达。
如何啟用Proguard
通常項(xiàng)目新建完成后,build.gradle文件中會有如下一段配置:
buildTypes {
debug {
minifyEnabledtrue
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
signingConfig signingConfigs.config
}
release {
minifyEnabledtrue
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
如上截圖帮掉,將minifyEnabled設(shè)置為true弦悉,開啟混淆代碼,可以同時(shí)配置多個(gè)混淆文件蟆炊。
配置中默認(rèn)加入了sdk的混淆文件稽莉,proguard-android.txt
Proguard配置
百度了一些語法,方便以后查閱涩搓。
保留選項(xiàng)(配置不進(jìn)行處理的內(nèi)容)
-keep {Modifier} {class_specification} 保護(hù)指定的類文件和類的成員
-keepclassmembers {modifier} {class_specification} 保護(hù)指定類的成員污秆,如果此類受到保護(hù)他們會保護(hù)的更好
-keepclasseswithmembers {class_specification} 保護(hù)指定的類和類的成員劈猪,但條件是所有指定的類和類成員是要存在。
-keepnames {class_specification} 保護(hù)指定的類和類的成員的名稱(如果他們不會壓縮步驟中刪除)
-keepclassmembernames {class_specification} 保護(hù)指定的類的成員的名稱(如果他們不會壓縮步驟中刪除)
-keepclasseswithmembernames {class_specification} 保護(hù)指定的類和類的成員的名稱良拼,如果所有指定的類成員出席(在壓縮步驟之后)
-printseeds {filename} 列出類和類的成員-keep選項(xiàng)的清單战得,標(biāo)準(zhǔn)輸出到給定的文件
壓縮
-dontshrink 不壓縮輸入的類文件
-printusage {filename}
-whyareyoukeeping {class_specification}
優(yōu)化
-dontoptimize 不優(yōu)化輸入的類文件
-assumenosideeffects {class_specification} 優(yōu)化時(shí)假設(shè)指定的方法,沒有任何副作用
-allowaccessmodification 優(yōu)化時(shí)允許訪問并修改有修飾符的類和類的成員
混淆
-dontobfuscate 不混淆輸入的類文件
-obfuscationdictionary {filename} 使用給定文件中的關(guān)鍵字作為要混淆方法的名稱
-overloadaggressively 混淆時(shí)應(yīng)用侵入式重載
-useuniqueclassmembernames 確定統(tǒng)一的混淆類的成員名稱來增加混淆
-flattenpackagehierarchy {package_name} 重新包裝所有重命名的包并放在給定的單一包中
-repackageclass {package_name} 重新包裝所有重命名的類文件中放在給定的單一包中
-dontusemixedcaseclassnames 混淆時(shí)不會產(chǎn)生形形色色的類名
-keepattributes {attribute_name,…} 保護(hù)給定的可選屬性庸推,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string} 設(shè)置源文件中給定的字符串常量
后面的文件名常侦,類名,或者包名等可以使用占位符代替
贬媒?表示一個(gè)字符
可以匹配多個(gè)字符聋亡,但是如果是一個(gè)類,不會匹配其前面的包名
** 可以匹配多個(gè)字符际乘,會匹配前面的包名坡倔。
在android中在android Manifest文件中的activity,service脖含,provider罪塔, receviter,等都不能進(jìn)行混淆养葵。一些在xml中配置的view也不能進(jìn)行混淆征堪,android提供的默認(rèn)配置中都有。(未知原因)
Proguard輸出文件
混淆之后港柜,會給我們輸出一些文件请契,在build/outputs/mapping/debug目錄下咳榜。
分別有以下文件:
dump.txt 描述apk文件中所有類文件間的內(nèi)部結(jié)構(gòu)夏醉。
mapping.txt 列出了原始的類,方法涌韩,和字段名與混淆后代碼之間的映射畔柔。
seeds.txt 列出了未被混淆的類和成員
usage.txt 列出了從apk中刪除的代碼
Proguard案例文件
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-dontoptimize
-dontpreverify
-keepattributesSignature
-keepattributes*Annotation*
-keepclass sun.misc.Unsafe { *; }
-keepclass com.eastelsoft.zk.bean.** { *; }
-keepclass * implements org.coreframe.ui.I_KJActivity { *; }
-dontwarncom.igexin.**
-keepclass com.igexin.**{*;}
-keepclass com.baidu.**{*;}
-keepclass vi.com.gdi.bgl.**{*;}
-keepclassmembersclass * {
public (org.json.JSONObject);
}
-keepclass com.umeng.**
-keeppublic class com.idea.fifaalarmclock.app.R$*{
public static final int *;
}
-keeppublic class com.umeng.fb.ui.ThreadView {
}
-dontwarncom.umeng.**
-dontwarnorg.apache.commons.**
-keeppublic class * extends com.umeng.**
-keepclass com.umeng.** {*; }
-keepclasseswithmembernamesclass * {
native ;
}
-keepclassmemberspublic class * extends android.view.View {
void set*(***);
*** get*();
}
-keepclassmembersclass * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembersenum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclass * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembersclass **.R$* {
public static ;
}
-dontwarnandroid.support.**
配置過程中遇到的坑
1.項(xiàng)目中使用了許多第三方庫,如百度地圖臣樱,友盟靶擦,Gson等包,需要根據(jù)官方上的說明進(jìn)行分別配置雇毫,
e.g. 百度地圖
-keepclass com.baidu.**{*;}
-keepclass vi.com.gdi.bgl.**{*;}
2. 第一次配置完后玄捕,軟件跑起來各種問題,后面發(fā)現(xiàn)全是gson解析失敗棚放,所以對model進(jìn)行了keep操作枚粘,也沒找到更好的方法。
-keepclass com.eastelsoft.zk.bean.** { *; }
3.項(xiàng)目中如果用了反射飘蚯,需要額外配置一些.
-keepattributesSignature
-keepattributes*Annotation*
-keepclass * implements org.coreframe.ui.I_KJActivity { *; }
這里對接口進(jìn)行了keep操作馍迄。
當(dāng)你用了proguard配置后如果出現(xiàn)問題福也,要一步一步去分析,如果發(fā)現(xiàn)按鈕不能點(diǎn)擊的問題攀圈, 就嘗試看看activity中的代碼是否出現(xiàn)問題暴凑,先keep一些類,逐步調(diào)試赘来,最后解決問題现喳。