代码混淆
代码混淆也只是加大反编译成本,不能真的防反编译。最大的功能是对代码的压缩与优化。
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