关于Android混淆知识点的两篇好文章:写给 Android 开发者的混淆使用手册, Android混淆从入门到精通

参考的资料:饿了么全面混淆插件 Mess,android 防破解, 代码混淆,代码保护

Mess是用来解决什么问题的

首先,在之前学过的关于Android混淆知识中我们知道,Android默认是不会混淆四大组件和自定义View的,或者换一个说法,出现在 xml 里的相关 Java 类默认是不会被混淆的。

你不禁会问,为什么Android默认要这么做?

答:因为 Proguard 原本是为 Java 打造的,它无法搜索到我们 AndroidManifest、布局等文件中引用了哪些 Java 类,因此如果 Java 代码变了而 XML 文件中的引用没变,就会造成反射失败,所以android默认这些被 XML 使用到的类需要 keep 住。

关于这一点,我们可以简单的验证一下:

打开build/intermediates/proguard-files/路径下的proguard-android.txt文件,这里面帮我们声明了许多混淆规则内容,包括:keep 所有继承自 View 的类,keep 所有继承自 Activity 的类,keep 所有 JavascriptInterface、native 方法声明,以及 keep 一些注解了 @Keep 的内容,例如:

好,说了这么多,Mess这个插件的目的就是在混淆的时候把这些顽固分子一起收拾了,让你的应用混淆的更彻底,更安全!

Mess的主要构成

Mess的项目地址:https://github.com/eleme/Mess

我把它下载到了本地,其主要一共就四个groovy文件:

                                        

MessExtension:用来存放需要被忽略的Proguard,比如那些本身也配置了相关混淆配置的依赖库,Mess会对这些依赖库                              进行混淆

Util:混淆时的工具类,这里面提供了一些方法如下

         renameProguardTxt(...):对Proguard文件进行重命名,然后存放到指定的路径

         hideProguardTxt(...):备份要被删除的proguard.txt 文件,用于最后的恢复

         recoverProguardTxt(...):恢复proguard.txt 文件

         sortMapping(...):根据传进来的Map的key的长短来排序

RewriteComponentTask:根据映射文件 mapping.txt 找到原先的类名,然后替换AndroidManifest,layout,menu和

                                          values 这些xml文件中的JAVA类,完成对其的混淆

MessPlugin:对transformClassesAndResourcesWithProguardForRelease这项Task的流程的调度,包括先后顺序等

Mess执行的具体步骤和流程

  1. 清空aapt_rules.txt 中的内容

aapt_rules.txt中记录着所有在 xml 里声明的 java 类(四大组件和自定义View等),并将它们都 keep 住,这个文件最终会被添加到 app 的混淆配置中,所以既然Mess想实现更全面的混淆,就必须删除它。在build/intermediates/proguard-rules/release下,你可以找到aapt_rules.txt,截了一部分代码如下:

既然知道要删掉它,首先需要找到aapt_rules.txt是从哪里生成的,系统的ProcessAndroidResources类中有这样一段代码:

该方法的名字就是获得AndroidResources进程中的Proguard输出文件,继续追踪我们发现,该方法所在的是一个名为VariantScope的接口,在它的实现类VariantScopeImpl中我终于看到了下面的这段代码:

到这里aapt_rules.txt的出生点已经找到,拿到路径后,在MessPlugin中是这样删除它的:

   2.如果需要混淆依赖库,则删除依赖库中的 proguard.txt 文件

Mess中采用的方式简单粗暴,直接将 proguard.txt 文件名最后加上 ~  ,这在linux中表示备份,以便之后文件的恢复。在Util中提供了如下方法:

对proguard.txt的备份和恢复的逻辑都在这里,然后在MessPlugin中先后调用:

  3.hook transformClassesAndResourcesWithProguard 获取混淆后的类映射关系 Map

注:hook翻译过来是钩子的意思,它能够将自身的代码「融入」被勾住(Hook)的程序的进程中,成为目标进程的一个部分

在一开始没有混淆之前:xml中的java类←→class文件

经过前面的步骤之后:xml中的java类←→混淆过的class文件

所以现在需要做的就是找到混淆过的class在xml中的原有java类名,然后把它给替换掉,也就是把它给混淆了。

这个映射关系要从/build/outputs/mapping/release/路径下的mapping.txt中找,它里面存放着混淆前后类、方法、类成员等的对照表,如下:

这一个个的箭头就是代表着一一对应的关系:混淆前和混淆后。Mess在RewriteComponentTask中用Map解析并存储了这些映射关系,相关代码如下:

在这段代码下边有一段注释:

“如果我们不对这个map进行长短的排序,就会出现这样的情况:

me.ele.foo -> me.ele.a

me.ele.fooNew -> me.ele.b(本该是这样)

 me.ele.fooNew -> me.ele.aNew(但不排序的话,会变成这样)

像这样,一个类的类名是另一个类名的开始部分,后面的替换就会出现bug。所以在存储完映射关系后,Mess调用了sortMapping(...)方法来进行排序,该方法的代码如下:

  4.通过映射 Map 替换 AndroidManifest.xml 里的 Java 原类名

在RewriteComponentTask中,紧接着上面的步骤,你就会看到下面的代码:

从这里就开始着手替换 AndroidManifest.xml中的Java原类名了,writeLine(...)方法如下所示:

逐行读取,然后进行相应的替换。

  5.通过映射 Map 替换 layout、menu 和 value 文件夹下的 xml 的 Java 原类名

还是在RewriteComponentTask中,有这样一个方法:

 很明显,它的作用就是用来判断文件路径是否是 layout、menu 和 value,它在处理完AndroidManifest.xml后随即被调用:

上图中的第二个红色框部分执行了相应的替换工作。

  6.再次执行 ProcessAndroidResources Task

经过前面的5个步骤之后,xml中的java类已经全部混淆,接下来需要再重新编译一次资源文件,即再次执行 ProcessAndroidResources Task。

到这里Mess六个步骤已经全部走完,再来回顾一下:

  1. 清空aapt_rules.txt 中的内容
  2. 如果需要混淆依赖库,则删除依赖库中的 proguard.txt 文件
  3. hook transformClassesAndResourcesWithProguard 获取混淆后的类映射关系 Map
  4. 通过映射 Map 替换 AndroidManifest.xml 里的 Java 原类名
  5. 通过映射 Map 替换 layout、menu 和 value 文件夹下的 xml 的 Java 原类名
  6. 再次执行 ProcessAndroidResources Task

Mess的开始工作的时间点

说了这么多,那么Mess是什么时候开始工作的呢

答:Mess在 class 打包成 dex 前完成所有的工作

 

 

 

 

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 一款常用的 Squid 日志分析工具
  3. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  4. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  5. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  6. Android压缩图片和libjpeg库
  7. [Android] AOSP 开发并刷入Pixel
  8. 从Java类加载初始化到Android热修复
  9. 制作不暴露源码的Android(安卓)Library Project

随机推荐

  1. Android利用LocalSocket实现Java端进程与
  2. android使用adb向AS自带虚拟机里安装apk
  3. 针对 android端模拟教务系统登陆,主要针对
  4. Android(安卓)tv 动画效果faq (放大动画
  5. 实现android上传多张图片和文字给php后台
  6. 用Qt制作的Android独立游戏《吃药了》发
  7. Android(安卓)RadioGroup单选框变成多选
  8. 生活中android应用开发有很广阔的天地
  9. 如何完全退出单例模式下的android应用程
  10. android 长连接的心跳及推送机制