1、XmlClassGuard 简介
XmlClassGuard是一个插件,可以对Android的四大组件、自定义View以及其他任意类进行混淆。
XmlClassGuard是ProGuard的补充,与ProGuard无关且不会产生冲突。
可以迅速修改manifest文件中的package属性,并将其同步到其他文件中。
能够迅速将n个目录移动到其他目录,并实现与其他文件的同步。
可以自动将constraint_referenced_ids属性的值添加到AabResGuard的白名单中,以便进行查找。
XmlClassGuard的主要功能是对xml文件中使用的类进行混淆,因此被命名为XmlClassGuard,以与AndResGuard和AabResGuard相对应。
2、有什么用?
解决ProGuard不混淆四大组件等类的问题
提高aab和apk反编译的难度
我们将大幅度减少aab包的查重率,以避免因过高的查重率而导致上架Google Play后被下架或封号的问题。
关于第三点,如果你曾经在Google Play商店上架过应用,就会知道如果之前的应用被下架或封号,再次上架的概率非常低。其中一个很重要的原因是代码中的类没有进行混淆处理,这容易让Google认为应用包重复,并导致再次封号。因此,为了能够再次上架应用,必须修改四大组件和自定义View等部分的包名和类名以降低查重率。然而,手动完成这项任务对程序员来说非常繁琐耗时。因此诞生了XmlClassGuard插件来自动完成这个任务,只需一个简单操作即可搞定。
3、原理
XmlClassGuard是一种与AndResGuard(apk资源混淆)和AadResGuard(aab资源混淆)不同的方案,它需要在打包之前执行xmlClassGuard任务。该任务会检索AndroidManifest.xml以及navigation和layout文件夹下的xml文件,并找出这些文件中引用的类,例如四大组件和自定义View等。然后,它会修改这些类的包名和类名,并将修改后的内容同步到其他文件中。简单来说,在打包之前,XmlClassGuard会在本地修改包名和类名。
请注意!这是一个警告!!由于此操作是在本地进行的,任务执行后将无法撤销。因此,请务必备份好代码,否则将很难还原。
4、上手
1、在根目录的build.gradle文件中进行配置
在build.gradle(application)中配置如下: ``` buildscript { repositories { maven { url 'https://jitpack.io' } } dependencies { classpath com.github.liujingxing:XmlClassGuard:1.1.1 } } ```修改后的文案如下: ``` apply plugin: xml-class-guard //以下均为非必须 xmlClassGuard { /* * 是否查找约束布局的constraint_referenced_ids属性的值,并添加到AabResGuard的白名单中, * true的话,要求你在XmlClassGuard前依赖AabResGuard插件,默认false */ findConstraintReferencedIds = true //用于增量混淆等配置 } ```5、任务介绍
XmlClassGuard插件总共包含4个任务,分别是findConstraintReferencedIds、moveDir、packageChange和xmlClassGuard。这4个任务之间并没有任何关联。接下来将逐一介绍它们。
5.1、findConstraintReferencedIds
该任务需要配合AabResGuard插件使用,如果你未使用AabResGuard插件,可忽略。
这里简单介绍一下,由于约束布局的constraint_referenced_ids属性的值是通过getIdentifier方法获取具体的id,因此我们需要将constraint_referenced_ids属性的值添加到AabResGuard的白名单中。否则,在打包时,id会被混淆,并且打包后constraint_referenced_ids属性会失效,导致UI出现异常情况。
然而,在项目中可能会有很多地方都使用到constraint_referenced_ids属性,并且值非常多。要一个个找出来并手动添加到AabResGuard的白名单中,无疑是一项繁琐的工作。因此,findConstraintReferencedIds任务就派上了用场。它是在打包时自动查找constraint_referenced_ids属性并添加进AabResGuard的白名单中,非常实用的功能。你只需要在XmlClassGurad的配置中将findConstraintReferencedIds设置为true即可,如下所示:
findConstraintReferencedIds任务会在打包(aab)时自动执行,无需手动操作。5.2、moveDir
moveDir是一个用于移动目录的任务,它具备同时移动任意一个目录的能力。该任务可以将原目录下的所有文件(包括子目录)迁移到另外一个文件夹,并将移动结果同步到其他文件中。以下是配置信息:
以下是改写后的文案: ``` xmlClassGuard { // 移动目录 moveDir = [ com.ljx.example: ef.gh, com.ljx.example.test: ff.gg ] } ``` 上述代码中的`moveDir`是一个Map对象,其中key代表要移动的目录,value代表目标目录。 上述任务将会把`com.ljx.example`目录下的所有文件移动到`ef.gh`目录下,并将`com.ljx.example.test`目录下的所有文件移动到 `ff.gg` 目录下。5.3、packageChange
packageChange是一个任务,用于修改manifest文件中的package属性,即修改应用程序包名的任务(不会更改applicationId)。完成修改后,将同步更新结果到其他文件中(不会更改项目结构)。配置如下:
xmlClassGuard { //更改manifest文件的package属性,即包名 packageChange = ["com.ljx.example": "ab.cd"]}复制代码
以上packageChange是一个Map对象,key为原始package属性,value为要更改的package属性,原始package属性不匹配,将更改失败
5.4、xmlClassGuard
xmlClassGuard是一个用于混淆类的任务。该任务会检索AndroidManifest.xml以及navigation和layout文件夹下的xml文件,找出这些文件中引用到的类,包括四大组件和自定义View等。然后,它会修改这些类的包名和类名,并将修改结果同步到其他文件中。最后,它会将混淆映射写入mapping文件中。配置如下:
``` xmlClassGuard { // 用于增量混淆的 mapping 文件 mappingFile = file(xml-class-mapping.txt) } ``` 上述配置中的mappingFile可以是一个不存在的文件,在混淆完成后,将会把混淆映射写入到该文件中,具体如下所示:dir mapping: com.ljx.example -> e com.ljx.example.activity -> dhclass mapping: com.ljx.example.AppHolder -> e.B com.ljx.example.activity.MainActivity -> dh.C复制代码
dir mapping是混淆的目录列表,class mapping是具体类的混淆列表
5.5、混淆任意类
xmlClassGuard任务是支持增量混淆的,如果你需要混淆指定的类com.ljx.example.test.Test,便可以在dir mapping下写入com.ljx.example.test -> h,此时再次执行xmlClassGuard任务,便会将com.ljx.example.test目录下的所有类(不包含子目录下的类)移动到h文件夹中,并将所有类名混淆,再次混淆的后mapping文件如下:
dir mapping: com.ljx.example -> e com.ljx.example.activity -> dh com.ljx.example.test -> hclass mapping: com.ljx.example.AppHolder -> e.B com.ljx.example.activity.MainActivity -> dh.C com.ljx.example.test.Test -> h.D复制代码
手动输入混淆规则,需要注意以下几条规则
5.6、每次混淆产生不一样的结果
每次混淆操作的默认结果都是相同的。混淆过程中,包名是根据哈希算法生成的,而类名则以大写字母A开头,并按照递增顺序依次命名(类似于26进制字符串:A、B、C...Y、Z、BA、BB...ZY、ZZ、BAA...)。
只需两步,即可每次产生不同的混淆结果。
对于每一个包名,你需要进行配置。
当涉及到类名时,尽管可以为每个类都进行配置,但是当类的数量过多时,逐一进行配置就会变得繁琐。此时只需要配置一个即可解决问题。
如果我们对上述的mapping文件进行修改,修改后如下所示:
执行xmlClassGuard任务会产生以下不同的结果: dir mapping: com.ljx.example -> hh com.ljx.example.activity -> jk com.ljx.example.test -> et class mapping: com.ljx.example.AppHolder -> hh.Zdir mapping:com.ljx.example -> hhcom.ljx.example.activity -> jkcom.ljx.example.test -> etclass mapping:com.ljx.example.AppHolder -> hh.Zcom.ljx.example.activity.MainActivity -> jk.BAcom.ljx.example.test.Test -> et.BC复制代码
可以看到,包名完全是根据自定义生成的结果,而类名便从Z开始,依次递增Z BA BC ..., 这里可以把包名看成26进制的字符串依次递增
6、注意事项⚠️
为了避免误杀情况,在进行类名替换时,应当避免与其他类同名的混淆类。
类混淆后,类的包名(路径)也会被混淆,所以,如果你用到一些三方库,有配置包名的地方,记得手动更改
请手动更改proguard-rules.pro文件的内容,因为XmlClassGuard不会自动修改该文件。在进行类混淆后,如果该文件中仍然包含未经混淆的类或目录,请务必记得手动进行相应的修改。
XmlClassGuard只会协助你修改包名和类名,并确保其他文件与之同步,而不会改变你的任何代码逻辑。如果在混淆后出现部分功能异常的问题,需要自行查找原因。如果是XmlClassGuard引起的问题,欢迎提issue或PR进行反馈。
如果您遇到任何关于谷歌和苹果应用上架的问题,我都可以帮助您解决。请联系我,我的微信号是:@ruirui025。
还木有评论哦,快来抢沙发吧~