微信的AndResGuard工具是用于Android资源的混淆,作用有两点:一是通过混淆资源ID长度同时利用7z深度压缩,减小了apk包大小;二是混淆后在安全性方面有一点提升,提高了逆向破解难度。本文从源码角度,来探寻AndResGuard实现原理。
阅读本文需要前提知识:掌握Android应用程序打包编译过程,尤其是对资源的编译和打包过程;熟悉resource.arsc文件格式。
推荐罗升阳文章:http://blog.csdn.net/luoshengyang/article/details/8744683
微信资源混淆工具源码地址:https://github.com/shwenzhang/AndResGuard
附上来自网络神图:
0、程序入口CliMain.main()
该函数处理命令行参数、并解析自定义配置文件,混淆工具可以根据配置项进行特定处理,具体参考config.xml内容,针对其中特定内容,我们会在后面提到。然后进入真正混淆的入口函数resourceProgurad()
特别说明一下解析Configuration中关键点,处理复用旧的mapping文件:
1、processOldMappingFile()
private void processOldMappingFile() throws IOException {
...
try {
String line = br.readLine();
while (line != null) {
if (line.length() > 0) {
Matcher mat = MAP_PATTERN.matcher(line);
if (mat.find()) {
String nameAfter = mat.group(2);
String nameBefore = mat.group(1);
nameAfter = nameAfter.trim();
nameBefore = nameBefore.trim();
//如果有这个的话,那就是mOldFileMapping
if (line.contains("/")) {
mOldFileMapping.put(nameBefore, nameAfter);
} else {
//这里是resid的mapping
int packagePos = nameBefore.indexOf(".R.");
if (packagePos == -1) {
throw new IOException(
String.format(
"the old mapping file packagename is malformed, " +
"it should be like com.tencent.mm.R.attr.test, yours %s\n", nameBefore)
);
}
String packageName = nameBefore.substring(0, packagePos);
int nextDot = nameBefore.indexOf(".", packagePos + 3);
String typeName = nameBefore.substring(packagePos + 3, nextDot);
String beforename = nameBefore.substring(nextDot + 1);
String aftername = nameAfter.substring(nameAfter.indexOf(".", packagePos + 3) + 1);
HashMap<String, HashMap<String, String>> typeMap;
if (mOldResMapping.containsKey(packageName)) {
typeMap = mOldResMapping.get(packageName);
} else {
typeMap = new HashMap<>();
}
HashMap<String, String> namesMap;
if (typeMap.containsKey(typeName)) {
namesMap = typeMap.get(typeName);
} else {
namesMap = new HashMap<>();
}
namesMap.put(beforename, aftername);
typeMap.put(typeName, namesMap);
mOldResMapping.put(packageName, typeMap);
}
}
}
line = br.readLine();
}
}
...
}
}
该函数主要功能是&#x