proguard语法
通配符*
*
:类名、方法名、字段名**
:包名、参数类型***
:get/set的入参类型和返回类型
类成员维度
## 满足签名规则的方法
-keepclassmembers class * {
void *(**On*Event);
}
## 入参类型满足规则的方法
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
## 方法名和入参类型满足规则的方法
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
## 具体类型和名称的方法和字段
-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 * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
## get/set以及构造方法
-keep public class * extends android.view.View {
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
具体类
## 仅类名
-keep class com.example.Bean
## 类名+类成员
-keep class com.example.Bean {*;}
包维度
-keep class com.example.** {*;}
规则维度
## 忽略包名+内部类
-keep class **.R$* {*;}
## 方法满足规则的类
-keepclasseswithmembernames class * {
native <methods>;
}
## 继承某个父类
-keep public class * extends android.app.Activity
## 实现某个接口
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
混淆复原
proguard产物
proguard处理之后除了会使代码混淆,还会在<module>/build/outputs/mapping/<variant>
目录下生成如下文件:
├── configuration.txt:混淆规则合集,即所有的proguard文件内容合并之后的结果
├── mapping.txt:原始与混淆过的类、方法和字段名称之间的转换关系
├── missing_rules.txt:AGP编译过程中生成的抑制编译告警的建议,都是一些**-dontwarn**规则
├── seeds.txt:未进行混淆的类和成员
├── usage.txt:从APK移除的代码,以Android SDK里面没有被引用的代码居多
└── dump.txt:APK中所有类文件的内部结构
这其中比较有用的就是mapping文件,其可用于混淆后代码堆栈的还原,方便线上问题排查。
自动备份mapping文件
android {
applicationVariants.all { v ->
// apk改名
v.outputs.all {
outputFileName = v.buildType.name == 'release' ?
"${v.versionName}_${v.flavorName}_${buildTime()}.apk" :
"${v.versionName}_${v.flavorName}.apk"
}
// mapping备份
if (v.buildType.isMinifyEnabled()) {
v.assemble.doLast{
copy {
from v.mappingFile
into "${rootProject.rootDir}/output/mapping"
rename { String name->
"mapping-${project.name}-${v.name}.txt"
}
}
}
}
}
...
}
crash堆栈还原
还原工具由Android SDK提供,位于sdk\tools\proguard\bin
目录下:
.
├── proguard.sh:混淆代码
├── proguardgui.sh:混淆工具GUI
└── retrace.sh:逆混淆代码
其中后两者都能实现堆栈还原工作。
retrace用法
retrace -verbose mapping.txt crash.txt
proguardgui用法
如图切换到retrace按提示操作即可: