一、简介

代码混淆(Obfuscated code)是将程序中的代码以某种规则转换为难以阅读和理解的代码的一种行为。

1.优点

令 APK 难以被逆向工程,即很大程度上增加反编译的成本。此外,Android 当中的"混淆"还能够在打包时移除无用资源,显著减少 APK 体积。

2.建议

发布一款应用除了设minifyEnabled为ture,你也应该设置zipAlignEnabled为true,像Google Play强制要求开发者上传的应用必须是经过zipAlign的,zipAlign可以让安装包中的资源按4字节对齐,这样可以减少应用在运行时的内存消耗。

二、启动混淆

通过工程下的build.gradle文件中的开启混淆开关和配置混淆规则文件

buildTypes {release {//不显示logbuildConfigField "boolean", "LOG_DEBUG", "false"//开启混淆minifyEnabled true//开启资源压缩shrinkResources true//Zipalign优化zipAlignEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}
}
  • shrinkResources:资源压缩
  • zipAlignEnabled:Zipalign优化
  • minifyEnabled:混淆开关
  • proguard-android.txt:SDK中默认proguard的配置规则
  • proguard-rules.pro:自定义proguard的配置规则

三、混淆语法

1.类名

对类名进行keep操作只是将类名keep住,但方法和变量仍然会被混淆

# 一颗星表示keep当前本包下的类名,子包下的类名是会被混淆的
-keep class com.example.hensen.*
# 两颗星表示keep当前本包下的类名和子包下的类名
-keep class com.example.hensen.**
# 表示keep当前类名
-keep class com.example.hensen.net.NetWorkCache
# 表示keep当前类的内部类的类名
-keep class com.example.hensen.net.NetWorkCache$NetWorkBean

2.内容

对内容进行keep操作不仅可以将类名keep住,还可以对方法和变量keep住

# 一颗星表示keep当前本包下的类名、类的内容
-keep class com.example.hensen.*{*;}
# 两颗星表示keep当前本包下的类名、类的内容和子包下的类名、类的内容
-keep class com.example.hensen.**{*;}
# 表示keep当前类名、类的内容
-keep class com.example.hensen.net.NetWorkCache{*;}
# 表示keep当前类的内部类的类名、内部类的内容
-keep class com.example.hensen.net.NetWorkCache$NetWorkBean{*;}

3.特定内容

对特定的内容进行keep操作

-keep class com.example.hensen.net.NetWorkCache{<init>;# 匹配所有构造器<fields>;# 匹配所有变量<methods>;# 匹配所有方法public <methods>;# 匹配所有共有的方法private <methods>;# 匹配所有私有的方法public *;# 匹配所有共有的内容private *;# 匹配所有私有的内容public <init>(java.lang.String);# 匹配特定参数的构造函数public void getCache(...);# 匹配任意长度类型参数的方法
}

4.类成员

对类名不需要keep,只需要对类下的方法进行keep操作

# 表示keep特定类下的特定参数的方法,但类名不会被keep
-keepclassmembernames class com.example.hensen.net.NetWorkCache{public void getCache(java.lang.String);
}

5.类和类成员

作用范围 防止被移出或重命名 防止被重命名
类和类成员 -keep -keepnames
仅类成员 -keepclassmembers -keepclassmembernames
类和类成员(前提是成员都存在) -keepclasseswithmembers -keepclasseswithmembernames

四、混淆通用规则

#############################################
#
# 基本指令区域(没什么别的需求不需要动)
#
#############################################
# 代码混淆压缩比,在0~7之间,默认为5,一般不做修改
-optimizationpasses 5# 混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses# 这句话能够使我们的项目混淆后产生映射文件
# 包含有类名->混淆后类名的映射关系
-verbose# 指定不去忽略非公共库的类成员
-dontskipnonpubliclibraryclassmembers# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
-dontpreverify# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses# 避免混淆泛型
-keepattributes Signature# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*#############################################
#
# Android开发中一些需要保留的公共部分(没什么别的需求不需要动)
#
############################################## 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
# 因为这些子类都有可能被外部调用
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService# 对于AndroidX的混淆
-keep class com.google.android.material.** {*;}
-keep class androidx.** {*;}
-keep public class * extends androidx.**
-keep interface androidx.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
-dontwarn androidx.**# 保留support下的所有类及其内部类
-keep class android.support.** {*;}# 保留继承的
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**# 保留R下面的资源
-keep class **.R$* {*;}# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {native <methods>;
}# 保留在Activity中的方法参数是view的方法,
# 这样以来我们在layout中写的onClick就不会被影响
-keepclassmembers class * extends android.app.Activity{public void *(android.view.View);
}# 保留枚举类不被混淆
-keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);public static ** valueOf(int);
}# 保留我们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{*** get*();void set*(***);public <init>(android.content.Context);public <init>(android.content.Context, android.util.AttributeSet);public <init>(android.content.Context, android.util.AttributeSet, int);
}# 保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *;
}# 保留Serializable序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {static final long serialVersionUID;private static final java.io.ObjectStreamField[] serialPersistentFields;!static !transient <fields>;!private <fields>;!private <methods>;private void writeObject(java.io.ObjectOutputStream);private void readObject(java.io.ObjectInputStream);java.lang.Object writeReplace();java.lang.Object readResolve();
}# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {void *(**On*Event);void *(**On*Listener);
}# webView处理,项目中没有使用到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);
}# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
#-assumenosideeffects class android.util.Log {#    public static int v(...);
#    public static int i(...);
#    public static int w(...);
#    public static int d(...);
#    public static int e(...);
#}
#############################################
#
# 项目中特殊处理部分
#
##############################################-----------处理反射类---------------#-----------处理js交互---------------#-----------处理实体类---------------
# 在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了。#-----------处理第三方依赖库---------
# AndroidEventBus
-keep class org.simple.** { *; }
-keep interface org.simple.** { *; }
-keepclassmembers class * {@org.simple.eventbus.Subscriber <methods>;
}# ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {@butterknife.* <methods>;
}# EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }# FastJson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature
-keepattributes *Annotation*# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {**[] $VALUES;public *;
}# Gson
#-keepattributes Signature-keepattributes *Annotation*
#-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。
# 将下面替换成自己的实体类
#-keep class com.fenda.slock.data.bean.** { *; }# OkHttp3
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**# Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {long producerIndex;long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
# Bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}# Jpush
-dontoptimize
-dontpreverify-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }# Litepal
-keep class org.litepal.** {*;
}-keep class * extends org.litepal.crud.DataSupport {*;
}-keep class * extends org.litepal.crud.LitePalSupport {*;
}# 保持测试相关的代码
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**# ============忽略警告,否则打包可能会不成功=============
-ignorewarnings##记录生成的日志数据,gradle build时在本项目根目录输出##
#apk 包内所有 class 的内部结构
-dump proguard/class_files.txt
#未混淆的类和成员
-printseeds proguard/seeds.txt
#列出从 apk 中删除的代码
-printusage proguard/unused.txt
#混淆前后的映射
-printmapping proguard/mapping.txt
########记录生成的日志数据,gradle build时 在本项目根目录输出-end######

五、关于组件化混淆

1.在app module中统一配置混淆规则

我们可以直接在app module中build.gradle文件配置所有module需要混淆的规则。这样,其他module中就无需开启混淆。但是并不推荐使用这种方法,当我们取消依赖某些module的时候,这样很容易造成混淆规则冗余,我们还需要删除掉该module相关的混淆配置,很麻烦。

2.各个module单独配置混淆规则(推荐)

我们也可以单独为module配置混淆规则,比较推荐这种做法。每个module管理自己的混淆文件,当我们不依赖该module的时候,就不会发生第一种方法出现的问题了。

我们把app module称作为主模块,其依赖的其他module称作为子模块

六、遇到的问题总结

  • 对于第三方框架的混淆,一般公开的框架都会提供混淆方法,只要到框架的github下就能找到。
  • 对于反射类的混淆,只要保持反射用到的类名和方法即可,并不需要将整个被反射到的类都进行保持。

Android混淆——混淆语法及问题相关推荐

  1. android混淆语法(android代码混淆工具)

    android 代码混淆算法有哪些 根据SDK的版本不同有2中不同的代码混淆方式,以上的proguard.cfg参数详解中所涉及到的信息是在较低版本SDK下的混淆脚本,事实上在高版本的SDK下混淆的原 ...

  2. Android 代码混淆语法讲解及常用模板(转)

    转载请注明原博客地址  Android 代码混淆语法讲解及常用模板 前言 混淆对于每一个开发者来说都不陌生,对于大多数 APP 而言,在上线之前,通常会进行代码混淆,加固,防止自己的 APP 被别人轻 ...

  3. android代码混淆个人总结及踩坑

    android代码混淆个人总结及踩坑 前言 公司项目使用组件化开发的形式,需要对自己负责的模块进行一些混淆配置,关于混淆相信做android开发的都或多或少有过一些接触,通过对混淆文件的配置从而将代码 ...

  4. Android混淆——混淆代码总结

    转自http://blog.csdn.net/lovexjyong/article/details/24652085 http://blog.csdn.net/catoop/article/detai ...

  5. android代码混淆aar_android代码混淆个人总结及踩坑

    前言 公司项目使用组件化开发的形式,需要对自己负责的模块进行一些混淆配置,关于混淆相信做android开发的都或多或少有过一些接触,通过对混淆文件的配置从而将代码中的类名,方法名,成员变量等进行无意义 ...

  6. Android代码混淆配置说明

    1.为什么需要代码混淆 Proguard混淆用于保护APP不被破解和逆向分析,Proguard通过移除没有用到的代码以及通过特定规则重命名类.变量.方法来压缩.优化.混淆你的代码.这样可以让你APK更 ...

  7. Android 打包混淆

    转载地址:http://blog.sina.com.cn/s/blog_821e2bb10102vjya.html 第一步:开启混淆功能​ 取消project.properties里面关于progua ...

  8. android工程混淆和反编译

    一.工程文件的混淆 混淆文件下载:http://download.csdn.net/detail/lxq_xsyu/6328751 1.在根目录下添加progard.cfg文件 2.打开project ...

  9. [转载]关于Android ProGuard混淆学习记录

    转自:http://www.cnitblog.com/zouzheng/archive/2011/01/12/72630.aspx 前段时间把Android的工程用Ant Build搞定后,现在需要把 ...

  10. android 混淆打包教程,Android studio 混淆打包

    AndroidStudio中的项目可以用compile的形式引入github上的开源项目,可以引用module,而不一定都要用libs文件夹中添加jar包的形式. 在最终realease打包时,混淆的 ...

最新文章

  1. 移动端web,tap与click事件
  2. 以KNN为例用sklearn进行数据分析和预测
  3. 用文本指导文本:基于文本的自监督可控文本生成模型
  4. python爬取素材图片代码_基于Python爬取素材网站音频文件
  5. 使用 gperf 实现高效的 C/C++ 命令行处理
  6. oracle怎样查询某用户下的所有表的表名
  7. 电商商城系统活动设计
  8. tensorflow线性回归基础函数
  9. WPF:使用WPF应用程序中的默认网络凭据和凭据存储来管理自动登录
  10. 输出1-10之间的偶数,并统计奇数的个数
  11. 【字典树】添加和查找单词
  12. aspnet实现搜索查询_C#算法设计查找篇之01-顺序查找
  13. python最优调配问题_Python实现的基于优先等级分配糖果问题算法示例
  14. Silverlight5 RC调用Win32API
  15. CentOS7.2下python安装pip-8.0.2管理
  16. bin mysql u root_MySQL安装后续步骤(修改root密码)
  17. wxpython 操作图片_wxpython 图像编程
  18. sam卡和sim卡区别_SAM卡概述
  19. 在photoshop中,从1寸到24寸照片的大小是多少?
  20. jbb是什么梗_太阳星座是什么意思

热门文章

  1. throw语句以及throw “error“ 和 throw new Error(“error“)的区别
  2. FineBI 的多系列折线图
  3. Set集合的使用和知识点
  4. facebook 分享页面_如何建立Facebook页面
  5. 再生龙盘对盘拷贝Linux
  6. win10如何查看显卡配置
  7. diy写字机器人_自己动手做一个写字机器人
  8. nginx域名重定向 实现新旧域名过渡
  9. asp毕业设计——基于asp+access的网上选题系统设计与实现(毕业论文+程序源码)——网上选题系统
  10. php word 表格,word 表格