android 代码混淆原理,Android 代码混淆
一、混淆基本原理及目的:
目的:讓反編譯app后的代碼很難看懂,只是讓別人很難看的懂而已。
基本原理:把代碼中原來有具體含義的包名,類名,變量名,方法名等名稱全部替換成按順序排列的無意義的英文字母a、b、c….這樣代碼結構沒有變化,還可以運行得到一樣的結果。
功能:【優化】優化java的字節碼,使程序運行更快;【壓縮】減少App大小,在混淆過程中它會找出未被使用過的類和類成員并刪除他們;【混淆】被反編譯,不容易理解。
二、Android中代碼混淆介紹及配置:
Android 的SDK 自帶了混淆工具Proguard,位于SDK根目錄\tools\proguard下面。代碼混淆需要了解以下三個文件:
1.proguard-android.txt:默認混淆規則,包含一些比較常規的規則,位于SDK根目錄\tools\proguard\proguard-android.txt
2.proguard-rules.pro:自己的項目需要特別定義混淆規則,它位于項目根目錄下面,里面的內容需要我們自己編寫
3.aapt_rules.txt:打包時混淆過程中生成的文件,如果混淆過程中遇到錯誤,可以在這里進行定位。文件項目根目錄的:build\intermediates\proguard-rules\release\aapt_rules.txt
在Android Studio中啟用自己的代碼混淆規則,配置如下,在gradle中生產環境,也就是需要發布時的配置添加如下紅框代碼:
image
參數說明:
minifyEnabled : true ,啟用自定義混淆規則,即proguard-rules.pro;false,反之不使用自定義混淆規則
shrinkResources :開啟刪除無用資源,也就是沒有被引用的文件(經過實測是drawable,layout,實際并不是徹底刪除,而是保留文件名,但是沒有內容,等等),但是因為需要知道是否被引用所以需要配合mififyEnable使用,只有當兩者都為true的時候才會起到真正的刪除無效代碼和無引用資源的目的
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' :表示獲取SDK下'proguard-android.txt‘文件中的默認混淆規則, 'proguard-rules.pro'表示使用項目根目錄下的 'proguard-rules.pro'文件中的混淆規則。當然'proguard-rules.pro'文件名可以根據自己需要可以修改。注意:這句代碼意思是混淆規則采用 proguard-android.txt + proguard-rules.pro,所以在自定義混淆規則的時候不要重復了,當然重復了也沒大問題。
三、混淆規則(指令說明+基礎模板):
混淆指令說明:
| 代碼 | 說明 |
| -optimizationpasses 5 | 代碼混淆壓縮比,在0~7之間,默認為5,一般不做修改 |
| -dontusemixedcaseclassnames | 混合時不使用大小寫混合,混合后的類名為小寫 |
| -dontskipnonpubliclibraryclasses | 指定不去忽略非公共庫的類 |
| -verbose | #混淆時是否記錄日志 |
| -dontskipnonpubliclibraryclassmembers | 指定不去忽略非公共庫的類成員 |
| -dontpreverify | 不做預校驗,preverify是proguard的四個步驟之一,Android不需要preverify,去掉這一步能夠加快混淆速度。 |
| -optimizations |
采用的混淆算法:指定混淆是采用的算法,后面的參數是一個過濾器這個過濾器是谷歌推薦的算法,一般不做更改;
-optimizations !code/simplification/cast,!field/,!class/merging/
|
| -dontshrink | 壓縮功能,默認是啟用的。 |
| -dontoptimize | 代碼優化,優化java的字節碼,默認啟用 |
|
-keep ``class XXXX
| 保留類名不變,也就是類名不混淆,而類中的成員名不保證。當然也可以是繼承XXX類的所有類名不混淆 |
|
-keepclasseswithmembers ``class XXXX
| 保留類名和成員名,當然也可以是類中特定方法 |
.........
項目中的公告部分,只需要復制到你的項目中即可,其他的部分根據自己的項目進行添加。如不能混淆的代碼:1、需要反射的代碼;
2、系統接口;3、Jni接口;4、需要序列號和反序列化的代碼(即實現Serializable接口的JavaBean);5、與服務端進行元數據交互的JavaBean(JSON、XML中對應的類);6、實體類,json解析類;7、第三方jar包。等等
#-------------------------公共部分 start-------------------------------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
# 保留了繼承自Activity、Application這些類的子類
# 因為這些子類有可能被外部調用
# 比如第一行就保證了所有Activity的子類不要被混淆
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
#如果有引用v4包可以添加下面這行
-keep public class * extends android.support.v4.app.Fragment
#忽略警告
-ignorewarning
#如果引用了v4或者v7包,
-dontwarn android.support.**
-keep class android.support.** {*;}
-keepclasseswithmembernames class * {
native ;
}
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public (android.content.Context);
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
}
-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 *(**On*Event);
}
#-------------------------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);
}
#-------------------------公共部分 end-------------------------------
總結
以上是生活随笔為你收集整理的android 代码混淆原理,Android 代码混淆的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dynagen0.11+Pemuwrap
- 下一篇: Android-jsoup爬虫