每天记录学习的新知识 : Android 混淆规则
程序员文章站
2022-07-01 16:31:09
混淆为什么需要混淆?Java代码是非常容易反编译的。为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理为什么使用proguard进行混淆?因为proguard是一个很优秀的开源混淆代码项目,而且是google的android studio默认支持的混淆插件。什么是混淆?混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序 的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和...
混淆
为什么需要混淆?
Java代码是非常容易反编译的。为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理
为什么使用proguard进行混淆?
因为proguard是一个很优秀的开源混淆代码项目,而且是google的android studio默认支持的混淆插件。
什么是混淆?
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序 的真正语义。
被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英 文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。
同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢 失,这些信息的丢失使程序变得更加难以理解。
混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。
使用混淆
1. 混淆的使用方法
1.1 开启混淆
buildTypes {
debug {
//是否进行混淆
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
//开启混淆只需要设置为true即可
minifyEnabled true
//添加混淆规则的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
1.2 在混淆文件(proguard-rules.pro)内设置混淆规则
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# 代码混淆压缩比,在0~7之间
-optimizationpasses 5
# 混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames
# 不去混淆第三方jar
-dontskipnonpubliclibraryclasses
# 混淆时不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
-dontpreverify
# 混淆时是否记录日志
-verbose
# 避免混淆泛型
-keepattributes Signature
# 避免混淆Annotation
-keepattributes *Annotation*
# 避免混淆内部类
-keepattributes InnerClasses
# 避免混淆匿名类
-keepattributes EnclosingMethod
# 混淆时所采用的算法:google推荐算法
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
# 重命名抛出异常时的文件名称
-renamesourcefileattribute SourceFile
# 保护给定的可选属性,抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
# 处理support包
-dontnote android.support.**
-dontwarn 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$* {*;}
# 保留四大组件,自定义的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.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
# 保留在Activity中的方法参数是view的方法,
# 这样以来我们在layout中写的onClick就不会被影响
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# 保留枚举类不被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留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;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#assume no side effects:删除android.util.Log输出的日志
-assumenosideeffects class android.util.Log {
public static *** v(...);
public static *** d(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
}
# 保留Keep注解的类名和方法
-keep,allowobfuscation @interface android.support.annotation.Keep
-keep @android.support.annotation.Keep class *
-keepclassmembers class * {
@android.support.annotation.Keep *;
}
# 忽略用于构建工具的注释
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# 忽略用于嵌入空性信息的JSR 305注释。
-dontwarn javax.annotation.**
# JSR 305注释用于嵌入可空性信息
-dontwarn javax.annotation.**
# 资源是用相对路径加载的,因此必须保留该类的包
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java
# 忽略 Animal Sniffer 依赖,以确保api与旧版本的Java兼容
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt dependency is available.
# OkHttp平台只在JVM上使用,并且Conscrypt依赖关系可用时使用
-dontwarn okhttp3.internal.platform.ConscryptPlatform
# retrofit2混淆
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
#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);
}
# 对于带有回调函数onXXEvent的,不能混淆
-keepclassmembers class * {
void *(**On*Event);
}
# 依赖的混淆
# 高德地图混淆
#3D 地图 V5.0.0之前:
-dontwarn com.amap.api.**
-dontwarn com.autonavi.**
-keep class com.amap.api.**{*;}
-keep class com.autonavi.**{*;}
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.amap.mapcore.*{*;}
-keep class com.amap.api.trace.**{*;}
#3D 地图 V5.0.0之后:
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.**{*;}
-dontnote com.autonavi.**
-keep class com.amap.api.trace.**{*;}
#定位
-keep class com.amap.api.location.**{*;}
-keep class com.amap.api.fence.**{*;}
-keep class com.autonavi.aps.amapapi.model.**{*;}
#搜索
-keep class com.amap.api.services.**{*;}
#2D地图
-keep class com.amap.api.maps2d.**{*;}
-keep class com.amap.api.mapcore2d.**{*;}
#导航
-keep class com.amap.api.navi.**{*;}
-keep class com.autonavi.**{*;}
# 关于APP本身的混淆
# 避免自定义View的混淆
-keep class com.****.widget.**{*;}
# 避免Bean的混淆
-keep class com.****.entity.**{*;}
# sharesdk 的混淆
-keep class cn.sharesdk.**{*;}
-keep class com.sina.**{*;}
-keep class **.R$* {*;}
-keep class **.R{*;}
-keep class com.mob.**{*;}
-keep class m.framework.**{*;}
-keep class com.bytedance.**{*;}
-dontwarn cn.sharesdk.**
-dontwarn com.sina.**
-dontwarn com.mob.**
-dontwarn **.R$*
# 第三方
# ... 省略 ...
# 注:如果您的App需要上传到google play store,您需要将READ_PHONE_STATE权限屏蔽掉或者移除,否则可能会被下架。
# 避免混淆Bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
1.3 不能被混淆的包括
- android系统组件,系统组件有固定的方法被系统调用
- 被Resource文件引用到的(比如自定义的view )
- 需要使用android 序列化的
其他anroid 官方建议 不混淆的,如:
-
android.app.backup.backupagenthelper
-
android.preference.preference
-
com.android.vending.licensing.ilicensingservice
-
java序列化方法,系统序列化需要固定的方法。
-
枚举 ,系统需要处理枚举的固定方法。
-
本地方法,不能修改本地方法名
-
annotations 注释
-
数据库驱动
-
有些resource 文件
-
用到反射的地方
2. 混淆规则常用简介
2.1 警告输出控制
-verbose//指定处理期间打印更多相关信息。
-dontnote [class_filter]//指定配置中潜在错误或遗漏时不打印相关信息
-dontwarn [class_filter]//指定找不到引用或其他重要问题时不打印警告信息
-ignorewarning://是否忽略警告
-ignorewarnings://打印找不到引用或其他重要问题的警告信息,但继续处理代码
-printconfiguration [filename]//将已解析过的配置标准输出到指定的文件。该选项可用于调试配置。
-dump [filename]//标准输出类文件的内部结构到给定的文件中。例如,你可能要输出一个 jar 文件的内容而不需要进行任何处理。
2.2 保留项
-keep 防止类和成员被移除或者被重命名
-keepnames 防止类和成员被重命名
-keepclassmembers 防止成员被移除或者被重命名
-keepclassmembersname 防止成员被重命名
-keepclasseswithmembers 防止拥有该成员的类和成员被移除或者被重命名
-keepclasseswithmembernames 防止拥有该成员的类和成员被重命名
参考地址
参考地址:Android混淆规则介绍
参考地址:Android 代码混淆规则
本文地址:https://blog.csdn.net/weixin_35691921/article/details/107381126