美文网首页
Java 混淆那些事(四):玩转 ProGuard 过滤器

Java 混淆那些事(四):玩转 ProGuard 过滤器

作者: QuincySx | 来源:发表于2019-03-20 23:56 被阅读0次

    本文已授权微信公众号「玉刚说」独家发布。

    欢迎大家来看「Java 混淆那些事」的第四篇,到目前我们现在已经可以进行编写混淆规则了,但是有个很严重问题,我们写的规则会出现很多重复的 keep 规则,我们随便举几个例子。

    1. 所有 Event 结尾的类里面的所有内容都不能混淆。
    2. 所有 XXX 子类中的 x() 方法都不混淆。
      ...

    那么这些问题有没有什么办法来解决呢?有,就是今天我们要讲的过滤器。

    类规范模板

    先放张上一篇博客提到的图,讲到后面我们需要参考。

    过滤器

    过滤器是什么呢?就是类似正则的规则过滤器。

    首先我先把几种不同类型的过滤器用几张表格列出来,然后讲述一下功能。这一篇我能用话说明白的绝对不用代码。自我感觉在博客中放代码体验太差了。

    类相关的过滤器

    1. 类名过滤器
    符号 功能
    ? 可以匹配任意一个字符,但是 package 的分隔符(.)除外,例如:com.example.T?st,可以匹配 com.example.Testcom.example.T2st,但是 com.example.T12stcom.example.Tstcom.example.T.st 不可以。
    * 可以匹配任意一部分连续的字符,但是 package 的分隔符(.)除外,例如 com.example.*Test,可以匹配 com.example.Testcom.example.AnyTest,但是 com.example.xxx.Test 不可以,还有一个特例 com.example.* 只能匹配当前包下的类,com.example.xxx.Test 就匹配不到。
    ** 可以匹配任意一部分连续的字符,例如 com**,可以匹配 com.Testcom.example.Testcom.example.java.Test
    <n> 在同一匹配规则中匹配和第 n 个通配符一致的内容。例如:*Any<1>,可以匹配到 TestAnyTestTestAnytest 不可以。
    2. 字段和方法名过滤器
    符号 功能
    <init> 匹配所有构造方法
    <fields> 匹配所有字段方法
    <methods> 匹配所有方法
    * 匹配所有方法和字段,包括构造方法。
    ? 匹配方法名称中的任何单个字符。
    <n> 在同一匹配规则中匹配和第 n 个通配符一致的内容。

    注:

    1. <fields> 用法如下,就代表所有字段。
    -keep class DownloadClient {
        <fields>;
    }
    
    1. <methods> 用法如下,就代表所有方法。
    -keep class DownloadClient {
        <methods>;
    }
    

    看到了 <fields>、<methods> 的用法,参照文章开始的类规范的图可知,我们可以再前面添加 public 之类的关键字,但是后面是添加不了东西的。
    <init> 的后面必须存在一个参数列表。

    3. 类型过滤器
    符号 功能
    % 匹配所有基本类型
    ? 匹配类名中的任何单个字符
    * 匹配不包含包分隔符的类名的任何部分。
    ** 匹配类名的任何部分,可能包含任意数量的包分隔符。
    *** 匹配所有任何类型
    ... 匹配任何类型任何数量的参数
    <n> 在同一匹配规则中匹配和第 n 个通配符一致的内容。

    注:?,* 和 ** 通配符不可以匹配原始类型,比如:int,float。包装类和普通类是可以匹配的,比如:Integer,String。

    文件相关的过滤器

    除了上述和类相关的过滤器之外还有和文件过滤器,如果需要自己独立使用 ProGuard 写配置规则或者需要写其他的配置,那么肯定要写那些文件需要输入,输出到哪等等的问题,往往我们的项目很大不能挨个文件去写规则,所以就需要过滤器。下一章我们介绍一些不常用的 ProGuard 选项,也能用到文件相关的过滤器。

    符号 功能
    ? 匹配文件名中的任何单个字符。
    * 匹配不包含目录分隔符的文件名的任何部分。
    ** 匹配文件名的任何部分,可能包含任意数量的目录分隔符。

    小结

    到此基本的过滤器我们也大概了解了,大家可以看到有好几个长得一样的过滤器,但是作用在不同地方功能不同,我们仔细去看他们的作用,其实也没有什么本质变化。
    那么,我们回归一下先前的两个问题。

    1. 所有 Event 结尾的类里面的所有内容都不能混淆。
    -keep class **Event { *; }
    
    1. 所有 XXX 子类中的 x() 方法不混淆。
    -keep class ** extends XXX { 
        void x();
    }
    

    但是 XXX 类被混淆了,如果不想 XXX 被混淆,那就在另写一条匹配规则。

    相关文章

      网友评论

          本文标题:Java 混淆那些事(四):玩转 ProGuard 过滤器

          本文链接:https://www.haomeiwen.com/subject/gzxfvqtx.html