代碼混淆
代碼混淆也只是加大反編譯成本,不能真的防反編譯。最大的功能是對代碼的壓縮與優化。
Proguard配置:
android {
compileSdkVersion 25
defaultConfig {
applicationId "mile.com.jobservicedemo"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
//主要看這部分
zipAlignEnabled true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
常見的混淆配置
- keep 用來保留Java的元素不進行混淆
- dontwarn 引入的library可能存在一些無法找到的引用和其他問題,在build時可能會發出警告會導致build終止。因此爲來保證build繼續,需要使用dontwarn處理這些無法解決的library的警告
# 保持該包名或者類名下的所有不混淆
-keep public class com.droidyue.com.widget.**
# 所有繼承android.view.View的類的子類中的set get 不混淆
-keepclassmembers public class * extends android.view.View
{
void set*(***);
*** get*();
}
# R文件中的靜態自動不被混淆
-keepclassmembers class **.R$* {
public static <fields>;
}
# native方法不混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# android.support.警告忽略
-dontwarn android.support.**
需要keep的情況
- enum枚舉
- Android四大組件
- 自定義控件,繼承View的類
- 實現android.os.Parcelable接口
- 序列化和反序列號的類
- 反射的成員變量或者方法(包括jni,js中的反射)
- 註解
- Native方法
- 三方sdk
字符串混淆
字符編碼混淆:編碼混淆就是先將字符串轉換成16進制的數組或者Unicode編碼,在使用的時候才恢復成字符串。波接着看到後是一串數字或者亂碼,難以分析。
private String encodeString(){
byte[] strBytes = {0x48,0x65,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64};
String str = new String(strBytes);
return str;
}
字符串加密
反編譯工具對抗
花指令
在原始程序中插入一組無用的字節,但又不會改變程序的原始邏輯,程序仍然可以正常運行,然後反編譯工具在反編譯這些字節時會出錯,造成反編譯工具失效,提高破解難度,例如下面的dalvik指令
如果反編譯工具採用線性掃描算法,會錯誤識別花指令導致出錯。
資源混淆
修改aapt
修改aapt處理資源文件相關的源碼,參考proguard方式對APK中資源文件名使用簡單無意義名稱替換,給破解這製作困難,從而做到資源的相對安全。
修改resources.arsc