Android代码混淆

常用混淆规则

#不混淆某个类
-keep public class com.webi.demo.TestClass {*;}

#不混淆某个包的所有类
-keep class com.webi.demo.** {*;}

#不混淆某个类的子类
-keep public class * extends com.webi.demo.TestClass {*;}

#不混淆某个接口的实现
-keep class * implements com.webi.demo.TestInterface {*;}

#不混淆某个类的特定方法
-keepclassmembers class com.webi.demo.TestClass{
    public void test(java.lang.String);
}

#不混淆某个类的内部类
-keep class com.webi.demo.TestClass$* {*;}

什么是混淆

把代码中原来有具体含义的包名、类名、变量名、方法名等名称全部替换成无意义的字母a/b/c…

为什么要混淆

由于Android是基于Java语言的,而Java属于高层抽象语言,易于反编译,其编译后的程序包中包含了大量的源代码变量、方法名、数据结构等近乎源码的信息,等同于将源码拱手送人。因此为了保护自己的劳动成果以及项目私密问题,我们需要给自己的项目加上混淆。

混淆会出现什么问题

不难理解,由于混淆后,各种变量、方法、类等信息变成了无意义的字母a/b/c,所以会出现ClassNotFoundException的错误,为了避免出现这样的错误,我们需要添加一系列的规则,来标注出我们不希望混淆的地方。

常见的保持相关元素不参与混淆的几种指令

命令 作用
-keep 防止类和成员被移除和被重命名
-keepclassmembers 防止成员被移除和被重命名
-keepnames 防止类和成员被重命名
-keepclassmembernames 防止成员被重命名
-keepclasseswithmembers 防止拥有该成员的类和成员被移除或重命名
-keepclasseswithmembernames 防止拥有该成员的类和成员被重命名

没有规则

none.png

默认值,如果你没有指定任何类型的keep指令,那么它会压缩(删除未使用的代码)并对类和类成员进行模糊处理(即重命名)

-keep

keep.png

-keep为不压缩、不混淆。

-keepclassmembers

keepclassmembers.png

使用这个规则,如果一个类未被使用,则会被删除。如果一个类被使用了,则会重命名这个的类的名字,它所有的成员都还在,并且还是原来的名字。

-keepnames

keepnames.png

允许类和成员压缩,但不能混淆。也就是说,任何未使用的代码都将被删除,但保留下来的代码将保留其原始名称。

-keepclassmembernames

keepclassmembernames.png

删除未使用的类和成员变量,混淆类名,保留成员的原始名称。

-keepclasseswithmembers

与-keep相同,不同之处在于它仅适用于具有类规范中所有成员的类。

-keepclasseswithmembernames

此规则与-keepnames相同。不同的是,它仅适用于具有类规范中所有成员的类。

更多详细的请到官网

保持元素不参与混淆的规则

[保持命令] [类] {
    [成员]
}

[类]表示类相关的限定条件,它将最终定位到某些符合该限定条件的类。它的内容可以使用:

  • 具体的类
  • 访问修饰符(public、protected、private)
  • 通配符*,匹配任意长度字符,但不含包名分隔符.
  • 通配符**,匹配任意长度字符,并且包含包名分隔符.
  • extends,即可以指定类的基类
  • implement,匹配实现了某接口的类
  • $,内部类

[成员]代表类成员相关的限定条件,它将最终定位到某些符合该限定条件的类成员。它的内容可以使用:

  • <init>匹配所有构造器
  • <methods>匹配所有方法
  • 通配符*,匹配任意长度字符,但不含包名分隔符.
  • 通配符**,匹配任意长度字符,并且包含包名分隔符.
  • 通配符***,匹配任意参数类型
  • ...,匹配任意长度的任意类型参数。比如void test(...)就能匹配任意void test(String a)或者是void test(int a, int b)这些方法
  • 访问修饰符(public、protected、private)
    例如,需要将com.demo.test包下所有继承Activity的public类及其构造函数都保持住,可以这么写:
-keep public class com.webi.mixdemo.*** extends Android.app.Avtivty{
    <init>
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本篇文章:自己在混淆的时候整理出比较全面的混淆方法,比较实用,自己走过的坑,淌出来的路。请大家不要再走回头路,可能...
    Zane_Samuel阅读 55,557评论 8 93
  • 混淆是 Android 打包过程中最重要的流程之一,基本上所有 app 都应该开启混淆,增加app的安全性。混淆其...
    shenhuniurou阅读 5,493评论 0 2
  • 声明 这篇文章更多的是做一个整理,内容来自于ProGuard官方文档以及各种博客等,相关文章的链接在参考目录里,感...
    夷陵小祖阅读 9,089评论 0 23
  • 概述 Java源代码编译成的class文件(Android中编译成dex文件类似)中有大量包含语义的变量名、方法名...
    ElvenShi阅读 3,627评论 0 2
  • 知道简爱跑步法,是听时间管理课程时了解到的,简爱跑步法是跑步达人吴栋老师在长期的跑步和比赛中得出的跑步方法,可以帮...
    夏沫er阅读 1,463评论 0 2

友情链接更多精彩内容