android 混淆

前沿

很久没用过混淆功能了,因为之前的包都使用第三方加固了,而且项目开发好几年了,突然要混淆也很麻烦。换了家公司后,感觉还是得混淆代码才行,不然直接暴露源码也太不行了。

启动混淆功能

groovy 复制代码
isMinifyEnabled = true
#添加
proguardFiles(
	getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
)

getDefaultProguardFile("proguard-android-optimize.txt") 是系统默认的配置,而 proguard-rules.pro 才是我们自身的混淆配置

混淆

第三方库混淆

第三方一般都会自带混淆文件,或者是会提供混淆内容,如:

groovy 复制代码
-keep class com.iflytek.**{*;}
-keepattributes Signature

-dontwarn dalvik.**
-dontwarn com.tencent.smtt.**

-keep class com.tencent.smtt.** {
    *;
}

-keep class com.tencent.tbs.** {
    *;
}

App 自身混淆

最需要注意的是我们的数据模型的混淆。

本来以为直接 -keep class com.xx.xx.model.** { *; } 就万事大吉了,结果发现还是不行。

groovy 复制代码
-keep @kotlinx.serialization.Serializable class com.xx.android.netlib.model.** { *; }

各种 gson ,泛型类,枚举类,Parcelable ,Serializable ,serialization等相关的都需要 keep住。

特别是如果遇到了需要通过 Gson.toJson POST 数据到服务器的,注意字段名别被混淆了,需要一个个字段注解上:

groovy 复制代码
@SerializedName("id")
val id: Int? = null

不然上传的就是 a: 23 / b: 32 这样的了。

最后,发现还是死活不行。最后看到有人说要禁止全混淆模式,

在 gradle.properties 中:

groovy 复制代码
android.enableR8.fullMode=false

此时,一万匹草尼玛奔腾而过。

android.enableR8.fullMode=false 是 Android Gradle 插件中的一个配置项,作用是 关闭 R8 的完整模式。完整模式会严格应用代码优化规则和检查,关闭它可以在某些情况下避免兼容性或构建问题。

具体作用

当设置为 false 时:

禁用 R8 的一些激进优化:

关闭某些潜在可能影响运行时行为的优化。

比如,不会删除那些可能看似未使用但实际被反射调用的代码。

保留更宽松的代码压缩策略:

避免因为未正确配置 ProGuard/R8 规则而导致代码、类、或资源被误删除。

对兼容性更友好,尤其是对于依赖于动态加载(如反射或动态代理)的代码。

减少一些潜在的构建时间开销:

构建过程更快,特别是在调试模式下。

更安全的过渡到 R8:

如果项目从 ProGuard 迁移到 R8,设置 android.enableR8.fullMode=false 可以让开发者逐步调整 R8 配置文件。

注意事项

此配置在 Android Gradle Plugin 4.0 之后已经被废弃: 如果你使用的 Android Gradle Plugin 版本是 4.0 及以上,android.enableR8.fullMode 的设置将被忽略,R8 会默认启用完整模式。

完整混淆配置

网络库:

groovy 复制代码
-dontoptimize

-keepattributes Signature

-printmapping mapping.txt

-verbose

# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
 -keep,allowobfuscation,allowshrinking interface retrofit2.Call
 -keep,allowobfuscation,allowshrinking class retrofit2.Response

 # With R8 full mode generic signatures are stripped for classes that are not
 # kept. Suspend functions are wrapped in continuations where the type argument
 # is used.
 -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

# App 的 model
-keepattributes Signature
# 保留带有 @Serializable 注解的类
-keep @kotlinx.serialization.Serializable class com.xx.android.netlib.model.** { *; }

# 保留带有 @Parcelize 注解的类
-keep @kotlinx.parcelize.Parcelize class com.xx.android.netlib.model.** { *; }

# 防止字段名被混淆
-keepclassmembers class com.xx.android.netlib.model.** {
    <fields>;
}

-keepclassmembers class com.xx.android.netlib.model.InputAnswerModel {
    java.lang.String text;
    java.lang.String url;
    java.lang.String uuid;
    java.lang.String audio_text;
}

-keepclassmembers class com.xx.android.netlib.model.EvaluationAnswerModel {
    int id;
    java.lang.String single;
    java.util.List<com.xx.android.netlib.model.InputAnswerModel> input;
}



# 保留 Kotlin 元数据(支持反射和序列化)
-keep class kotlin.Metadata { *; }

# 不混淆 Kotlin 内部的序列化类
-keepnames class kotlinx.** { *; }
-dontwarn kotlinx.**

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
-keep class com.xx.android.netlib.model.** { <fields>; }

-keepattributes Annotation


-keep class * extends java.lang.Enum { *; }

#
-keep class com.xx.android.netlib.core.RetrofitClient { *; }

# Retrofit
-dontwarn retrofit2.**
-dontwarn org.codehaus.mojo.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
-keepattributes EnclosingMethod
-keepclasseswithmembers class * {
@retrofit2.* <methods>;
}
-keepclasseswithmembers interface * {
@retrofit2.* <methods>;
}

# 保护特定生成类(R8 或 Kotlin 编译器)
-keep class com.xx.android.netlib.interceptor.InterceptorUtil$$ExternalSyntheticLambda* { *; }
-keep class com.xx.android.netlib.model.*$$serializer { *; }


# 保留需要序列化/反射使用的字段
-keep class * {
    <fields>;
}

# 保留 Gson 中使用的泛型类
-keepclassmembers class * {
    @com.google.gson.annotations.SerializedName <fields>;
    public static final ** CREATOR;
}

# Gson 混淆规则
-keep class com.google.gson.** { *; }

# OkHttp
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-keep class javax.net.ssl.** { *; }

# 保留 TypeToken 信息
-keep class com.google.gson.reflect.TypeToken { *; }
-keepclassmembers class com.google.gson.reflect.TypeToken {
    <fields>;
}

# 保护所有可能被反射调用的类
-keepclassmembers class * {
    void *(...);
}
# 保留所有使用泛型的方法(安全配置)
-keepclassmembers class * {
    public *;
}

# 保留 Parcelable 的实现类
-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

# 保留 kotlinx.parcelize 注解
-keep @kotlinx.parcelize.* class *
-keepclassmembers class * {
    @kotlinx.parcelize.* <fields>;
}

# 保留反射所需的类信息
-keep class * implements java.io.Serializable { *; }

-dontwarn com.franmontiel.persistentcookiejar.**
-keep class com.franmontiel.persistentcookiejar.**

-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# 保留所有需要通过反射访问的泛型参数
-keepclassmembers class * {
    java.lang.reflect.Type *;
    java.lang.reflect.ParameterizedType *;
}

# 保留 kotlinx.serialization 注解
-keep @kotlinx.serialization.* class *
-keepclassmembers class * {
    @kotlinx.serialization.* <fields>;
}

# 保留需要序列化的类
-keep class kotlinx.serialization.** { *; }
-keepnames class kotlinx.serialization.** { *; }
# 避免警告
-dontwarn kotlinx.serialization.**

-keepclassmembers class kotlinx.serialization.** { *; }

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

-keep,allowoptimization,allowshrinking,allowobfuscation class <3>

-keepclassmembers class * {
    java.lang.reflect.Type *;
    java.lang.reflect.ParameterizedType *;
}

-keep @kotlinx.serialization.Serializable class * { *; }
-keepclassmembers class * {
    @kotlinx.serialization.Serializable <fields>;
}
-keep class kotlinx.serialization.** { *; }
-dontwarn kotlinx.serialization.**

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class kotlin.jvm.internal.* { *; }

# 保留所有带有泛型的类的类型信息(更通用的规则)
-keepclassmembers class * {
    java.lang.reflect.Type getGenericSuperclass();
    java.lang.reflect.Type[] getGenericInterfaces();
}

-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

-dontwarn java.lang.invoke.StringConcatFactory

app module :

groovy 复制代码
# 保留泛型信息,避免运行时类型擦除导致异常
-keepattributes Signature
-keepattributes Exceptions

-printmapping mapping.txt

# app 包下的model需要keep 
-keep class com.xx.xx.model.** { *; }

-dontwarn com.umeng.**
-dontwarn com.mobile.auth.**
-dontwarn com.cmic.sso.sdk.**
-dontwarn com.unicom.online.account.**
-dontwarn com.nirvana.**
-dontwarn com.ali.security.**

-keep class com.umeng.** {*;}
-keep class com.mobile.auth.** {*;}
-keep class com.cmic.sso.sdk.** {*;}
-keep class com.unicom.online.account.** {*;}
-keep class com.nirvana.** {*;}
-keep class com.ali.security.** {*;}

-keep class com.iflytek.**{*;}

-keepclassmembers enum * {                                                      # 保持枚举 enum 类不被混淆
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-dontwarn com.tencent.bugly.**

-keep class com.tencent.bugly.** {*;}

-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.preference.Preference
-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 * 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);
}
相关推荐
叶羽西3 小时前
Android Overlay Priority Rules
android
raychongzi5 小时前
The option ‘android.enableAapt2‘ is deprecated and should not be used anymore.
android
Tongsr8 小时前
Compose 仿微信朋友圈九宫格控件以及背后的原理
android·前端
海绵宝宝_8 小时前
【HarmonyOS NEXT】ArkTs数据类型解析与使用
android·前端·华为·harmonyos·鸿蒙
明天就是Friday8 小时前
Android Binder 进程间通信
android·binder
lansus9 小时前
智能座舱进阶-应用框架层-Jetpack主要组件
android·智能座舱
Zender Han9 小时前
Flutter 中的 Flexible 与 Expanded 的介绍、区别与使用
android·flutter·ios
xuexizhe7712 小时前
iPhone恢复技巧:如何从 iPhone 恢复丢失的照片
android·安全·ios·智能手机·电脑·手机·iphone
小菜琳12 小时前
应用如何借用manifestxml追加gid权限
android