Android混淆Proguard

一、简介

Android打包APP后为了增加反编译后阅读代码的难度,增加一些混淆操作,也就是将源代码中类名、方法名、属性名用其他的字符串(比如a、b、c)等,同时代码经过混淆压缩之后体积会明显的减小,达到优化APP的作用。

二、Proguard的作用

  • 压缩 Shrinking:默认开启,移除未使用的类和成员,并在优化Optimization 之后还会再次执行,移除无用的类,减少APP中方法数,也可避免造成64K的问题。
  • 优化 Optimization:默认开启,字节码层级进行优化,加快应用运行速度。
  • 混淆 Obfuscation :默认开启,增大反编译难度,除了在混淆文件中添加keep保持的类和类成员都会被随机命名。

他们都是可以在proguard-rules.pro文件中重新定义进行关闭,一般的话不要关闭它,要不然混淆就没有意义了

-dontshrink       # 关闭压缩
-dontoptimize     # 关闭优化
-dontobfuscate    # 关闭混淆

三、Android中开启混淆

如需要开启混淆,只需要在build.gradle文件中配置minifyEnabled true即可,剩下的需要在proguard-rules.pro编写混淆规则

android {....buildTypes {release {//            zipAlignEnabled trueminifyEnabled true//强制打开R8编译器 代码收缩、混淆和优化shrinkResources true //资源优化 移除无用资源proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}
}

混淆开启后进行打包操作后,会在项目的proguard目录下生成3个文件,分别是

  • mapping.txt 这个文件说明项目中的类、属性、方法和混淆后的文件是怎么进行一一映射的,这个文件非常重要,如果被别人拿到了,就可以根据里面的映射规则进行代码的还原。
  • seeds.txt 没有混淆的类和成员
  • unsed.txt 列出从APP中删除的代码

注意:编写proguard-rules.pro混淆规则文件是为了保持部分类不会被混淆,防止因混淆造成类解析失败导致应用出现问题

四、基本规则

1)、语法关键词

keep 保持类和类成员不被移除或重命名

keepclassmembers 保持类成员不被移除或重命名

keepclasseswithmembers 如果某成员存在,保持该类和类成员不被移除或重命名

如果后面加上了names,则只会保持不被重命名

防止被移出或重命名 防止被重命名 保持范围
-keep -keepnames 类和类成员
-keepclassmembers -keepclassmembernames 仅类成员
-keepclasseswithmembers -keepclasseswithmembernames 如果存在某成员,保留该成员和类
2)、各种匹配符
  • 星号 *

    匹配指定包下的类或者类的子类,写法如下:

    -keep class yc.com.physician.model.bean.*;
    -keep class yc.com.physician.model.bean.**
    

    说明:

    ①、一个*号表示只保持该包(yc.com.physician.model.bean)下的类名不被混淆,而子包下的类名还是会混淆,比如bean下面有个subbean子包,它里面的类会被混淆。

    ②、两个*号表示保持该包(yc.com.physician.model.bean)下及该包下子包的包名不被混淆。

    ③、如果只写上面的配置,表示只保持类名不会混淆,而类中的方法和成员变量的名称还是被混淆改变了,如果既想保持类名,又想保持方法和成员变量不被混淆,需要使用以下方式:

    -keep class yc.com.physician.model.bean.*{*;}
    

    ④、混淆规则中同样可以使用类似Java中extends、implements等规则进行配置

    # 保持继承了BaseActivity的public修饰的类名不被混淆
    -keep public class * extends yc.com.physician.base.BaseActivity # 内部类使用 $ 号,保持 PhysicianWebSubjectActivity 中 内部类 Test的所有 public 修饰的都不被混淆掉
    -keepclassmembers class yc.com.physician.ui.activity.PhysicianWebSubjectActivity$Test{public *;
    }
    
  • 特定匹配

    <init>   # 匹配所有构造函数
    <fields>  # 匹配所有成员变量
    <methods> # 匹配所有的方法
    

    可以在这些匹配前面加上private、public进行更精细的限制范围,比如保持 User 类中 所有 public 方法不被混淆:

    -keep class yc.com.physician.ui.bean.User {public <methods>;
    }
    

    也可以指定类中某个特定的构造函数或方法不被混淆

    -keep class * extends com.bumptech.glide.module.AppGlideModule {<init>(...);
    }
    # 保持User类的public修饰,参数是String类型的方法不被混淆
    -keep class yc.com.physician.ui.bean.User {public <methods>(String);
    }
    
3)、不能设置混淆的方法或成员
  • JNI 项目中jni方法不能混淆,因为需要和native方法保持一致

    #保持 native 方法不被混淆
    -keepclasseswithmembernames class * {native <methods>;
    }
    
  • 反射用到的类不能混淆

  • Androidmanifest.xml 中的类不能混淆,所以四大组件和 Application子类,Framework 层下所有的类默认是不会进行混淆的。所以不需要手动添加混淆规则

  • 自定义的 View 默认不会被混淆

  • 与服务端交互解析成的实体对象不能设置混淆,否则不能解析出正确的对象。

    -keep class yc.com.physician.model.bean.*{*;} # 自定义数据模型的bean目录
    
  • 引用第三方 SDK 时,需要根据它的文档加入对应的混淆规则。

  • Parceable 子类和 Creator 静态成员变量不能混淆,否则产生异常。

    #保持 Parcelable 不被混淆
    -keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *;
    }
    
  • 枚举类需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用

    #保持枚举 enum 类不被混淆
    -keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);
    }
    
  • 使用Webview时自定义的js接口调用类不能被混淆,

    -keepclassmembers class yc.com.physician.ui.activity.PhysicianWebSubjectActivity$Test{public *;
    }
    
4)、通用的配置选项
  • -verbose 控制台输出详细的Proguard日志
  • -dontnote [class filter] 不提示过滤器中的类名。
  • -dontwarn [class filter] 不要警告过滤器中的类,忽略警告继续proguard。这个对于忽略第三方类库中的类的警告很有用。
  • -ignorewarnings 控制台输出所有未解析的应用和其他重要的问题,但是忽略,继续执行proguard。
  • -printconfiguration [filename] 指定输出所有的配置到指定文件中。这些配置包括混淆文件和替换的变量。
  • -dump [filename] 写出处理后的类文件的结构。

五、通用的混淆规则

有些混淆规则在任何APP中都使用,所以总结出来要用的时候直接复制就好

#--------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
#指定代码的压缩级别
-optimizationpasses 5
#包名不混合大小写
-dontusemixedcaseclassnames
#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses#优化  不优化输入的类文件
#-dontoptimize#预校验
-dontpreverify#混淆时是否记录日志
-verbose# 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护注解
-keepattributes *Annotation*#忽略警告
#-ignorewarning
##记录生成的日志数据,gradle build时在本项目根目录输出##
#apk 包内所有 class 的内部结构
-dump proguard/class_files.txt
#未混淆的类和成员 打印出那些被keep住的类和成员,结果输出到指定文件里。
-printseeds proguard/seeds.txt
#列出从 apk 中删除的代码 打印指定输出那些没用的代码(dead code)到文件中。
-printusage proguard/unused.txt
#混淆前后的映射 打印混淆前后的名称对应关系到文件中,以便crash后进行对照。
-printmapping proguard/mapping.txt
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######
#如果引用了v4或者v7包
-dontwarn android.support.**
# ————————————————————————————————————————————————
-keepclassmembers class * implements java.io.Serializable {static final long serialVersionUID;private static final java.io.ObjectStreamField[] serialPersistentFields;private void writeObject(java.io.ObjectOutputStream);private void readObject(java.io.ObjectInputStream);java.lang.Object writeReplace();java.lang.Object readResolve();
}
-keepclassmembers class **.R$* {pulic static <fields>;
}-keepclassmembers class * {void *(*Event);
}-keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *;
}
#// natvie 方法不混淆
-keepclasseswithmembernames class * {native <methods>;
}#保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *;
}
#----------------------------------------------------------------------------#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {public void *(android.webkit.WebView, jav.lang.String);
}
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
#---------------------------------实体类---------------------------------

Android混淆介绍相关推荐

  1. Android混淆规则介绍

    Android混淆规则介绍 写在前面的话 APP上线推广,免不得是需要混淆加固的,况且劳动成果不易又会有谁希望自己的APP被破解抄袭呢.鉴于此方显本片文章的通用型和重要意义. 混淆简介 Android ...

  2. android命令行工具 混淆,Android 混淆代码学习以及Android加密工具--APKProtect的使用ZZ...

    一:情景分析 有时候看到其他应用App的一些效果很炫,或者是功能实现很好就想着参考参考,于是乎,下载APK----反编译APK---查看源码....,但是悲剧来了....源码都是些a,b,c...等等 ...

  3. Android混淆详解

    综述 毫无疑问,混淆是打包过程中最重要的流程之一,在没有特殊原因的情况下,所有 app 都应该开启混淆. 首先,这里说的的混淆其实是包括了代码压缩.代码混淆以及资源压缩等的优化过程.依靠 ProGua ...

  4. Android混淆心得

    最近在做Android应用的混淆,踩了一些坑,这里记录分享下个人的心得. 混淆介绍 首先先简单说一下什么是混淆和混淆的作用,其实这个搜索下可以找到一堆官方的说法等等,这里简单口语叙述一下,混淆就是把代 ...

  5. Android混淆大法

    Android混淆大法 本文涉及内容: 1.混淆的基本介绍,混淆的基本配置及示例 2.如何进行多模块的混淆 3.实际项目中混淆时会遇到的问题 4.混淆后如何进行debug和日志查看 文章目录 Andr ...

  6. android 混淆后的机制,Android 代码混淆机制

    Android 代码混淆机制 由于Android项目是基于java语言的,而java属于高层抽象语言,易于反编译,其编译后的程序包包含了大量的源代码变量.函数名.数据结构等信息,根据其编译打包后的AP ...

  7. android 混淆规则作用,Android混淆规则

    简介 Java代码是非常容易反编译的.为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理. ProGuard是一个混淆代码的开源项目.它的主要作用就是混淆,当然它还能对字节码 ...

  8. 【我的Android进阶之旅】Android 混淆文件资源分类整理之二:将混淆文件拆分成更小粒度的混淆文件

    在我2017年的文章[我的Android进阶之旅]Android 混淆文件资源分类整理中,我已经提及过. 之前将所有的混淆都配置在一个 proguard-rules.pro 这个Android Stu ...

  9. Android混淆总结

    Proguard 混淆工具来帮助我们快速地对代码进行混淆.根据 Java 官方介绍,Proguard 对应的具体中文定义如下: 1.它是一个包含代码文件压缩.优化.混淆和校验等功能的工具 2.它能够检 ...

  10. Android 混淆那些事儿

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/WmJyiA3fDNriw5qXuoA9MA 作者:l ...

最新文章

  1. LeetCode 122. Best Time to Buy and Sell Stock II--贪心--Java,C++,Python解法
  2. python获取今年第一天_利用python获取某年中每个月的第一天和最后一天
  3. 向Lucene增加中文分词功能
  4. 华为手机拍照后图库里无照片_EMUI的相册不这么用,还用什么智能手机?
  5. Microsoft SQL Server 自定义函数整理大全--转【叶子】的文章
  6. LeetCode 735. 行星碰撞(栈)
  7. linux内核模块是什么,Linux内核模块介绍,使用Linux模块的优点
  8. 改善深层神经网络:超参数调整、正则化以及优化——2.5 指数加权平均的偏差修正
  9. shell 脚本学习及troubleshooting
  10. Qt4_创建菜单和工具栏
  11. Hibernate(六):映射一对多关联关系、双向一对多映射
  12. HDOJ-2602 Bone Collector [DP-01背包问题]
  13. error LNK2005 原理及解决办法
  14. CCFCSP历年认证考试真题解答汇总(已解决20道,持续更新ing)
  15. KNN——简单手写体识别
  16. 显ip图片签名php,简单几步,教你制作自己的显IP签名档
  17. vue-pdf vue中导入文件 并预览
  18. 哪些机型适配了android11,coloros11适配机型_coloros11支持机型有哪些
  19. 网络流24题(部分)
  20. Make Product Equal One(思维)

热门文章

  1. 如何在HTML中更改文本颜色?
  2. 注册机无法运行,显示系统资源不足,无法完成请求的服务
  3. linux中sendto函数路径,Linux下send、sendto、sendmsg函数分析
  4. X509证书结构解析
  5. MathType编辑手写体
  6. 【编程开发】之国家代号与电话区号
  7. 泛函分析 06.01 线性算子的谱理论 - 谱集和正则点集
  8. labview温度采集系统(数据保存到excel)
  9. 15个常用excel函数公式_(干货)EXCEL常用函数公式大全及举例
  10. OA系统如何助力企业行政管理?