欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

每天记录学习的新知识 : 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 不能被混淆的包括

  1. android系统组件,系统组件有固定的方法被系统调用
  2. 被Resource文件引用到的(比如自定义的view )
  3. 需要使用android 序列化的

其他anroid 官方建议 不混淆的,如:

  1. android.app.backup.backupagenthelper

  2. android.preference.preference

  3. com.android.vending.licensing.ilicensingservice

  4. java序列化方法,系统序列化需要固定的方法。

  5. 枚举 ,系统需要处理枚举的固定方法。

  6. 本地方法,不能修改本地方法名

  7. annotations 注释

  8. 数据库驱动

  9. 有些resource 文件

  10. 用到反射的地方

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