当前位置:首页>行业动态> 正文

Android JS混淆技术,如何应用与效果如何?

Android JS混淆是防止JavaScript代码被轻易反编译和理解的技术,通过重命名变量、函数等,增加代码阅读难度,保护应用逻辑与知识产权。

Android混淆(obfuscation)详细回答

一、基本

1. 什么是代码混淆?

代码混淆是一种技术,通过对源代码进行修改,使得最终生成的代码变得难以理解和逆向,同时尽量不影响应用的正常运行,混淆会修改类名、方法名、变量名等符号,使它们变得没有意义,这样,即使攻击者能够获取到 APK 文件或反编译代码,也很难了解代码的实际逻辑。

2. 为什么需要代码混淆?

保护知识产权:防止他人通过反编译 APK 文件来窃取代码逻辑和商业秘密。

提高安全性:增加逆向工程的难度,使攻击者更难找到破绽和利用点。

Android JS混淆技术,如何应用与效果如何?  第1张

减小 APK 大小:通过去除未使用的代码和资源,可以减小 APK 的大小,提高应用的性能和下载速度。

二、混淆工具

1. ProGuard

ProGuard 是一个独立的代码混淆工具,主要作用是对代码进行优化、缩小和混淆,它通过字节码优化和混淆,减少应用的大小,并混淆掉不需要的代码。

2. R8

R8 是 Google 开发的替代工具,默认集成在 Android Gradle Plugin 中,相比 ProGuard 提供更高效的混淆和优化,R8 是 Android Studio 3.4 版本以后推出的默认工具。

三、混淆配置步骤

1. 启用混淆

在项目的build.gradle 文件中,找到android 块,并在buildTypes 下配置release 类型的minifyEnabled 属性为true,以启用代码混淆功能。

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

2. 编写混淆规则

在项目的proguard-rules.pro 文件中定义混淆规则,常见的规则包括保留特定的类、方法或字段,以避免它们被混淆或删除。

保留所有公有类和方法
-keep public class  {
    public ;
}
忽略特定包的警告
-dontwarn com.example.unusedpackage.
保留带有特定注解的类
-keep @interface com.example.MyAnnotation
保留继承特定父类的所有子类
-keep class  extends com.example.BaseClass
保留类名和方法名,但不保护方法的内部实现
-keepclassmembers class com.example.MyClass {
    public <methods>;
}

3. 构建项目

配置完成后,使用以下命令构建项目:

./gradlew assembleRelease

这将生成混淆后的 APK 文件,位于app/build/outputs/apk/release/ 目录下。

四、混淆规则详解

规则类型示例说明
保留类-keep public class extends android.app.Activity保留所有公有的 Activity 类
保留方法-keep public class { public void myMethod(...); }保留特定方法名不混淆
忽略警告-dontwarn com.example.unusedpackage.忽略特定包的警告
保留注解-keep @interface com.example.MyAnnotation保留带有特定注解的类
保留字段-keepclassmembers class { static final long serialVersionUID; }保留序列化字段
保留枚举-keepclassmembers enum { ; }保留枚举类及其成员
保留 JNI 方法-keepclasseswithmembernames class { native ; } 保留本地方法不被混淆
保留 Parcelable-keep class implements android.os.Parcelable { ; }保留 Parcelable 序列化类
保留 Serializable-keepclassmembers class implements java.io.Serializable { ; }保留 Serializable 序列化类
保留自定义控件-keep public class extends android.view.View { ; }保留自定义控件类
保留 DataBinding-keep class extends androidx.databinding.ViewDataBinding { ; }保留 DataBinding 生成的类
保留测试代码-dontnote junit.framework.保持测试相关的代码不被混淆
保留 WebView JavaScript 调用-keepclassmembers class fqcn.of.webview.IntoJava { ; }保留 WebView JavaScript 调用的方法
保留反射机制-keep class com.example.app. { ; }动态加载的类不能被混淆
保留第三方库-keep class retrofit2. { ; } -dontwarn retrofit2.防止混淆影响第三方库的正常工作
保留 Kotlin 元数据-keepattributes SourceFile,LineNumberTable保留调试信息
保留行号-renamesourcefileattribute SourceFile将文件来源重命名为“SourceFile”字符串
保留注解-keepattributes Annotation保留注解不被混淆
保留签名-keepattributes Signature保留泛型签名信息
保留异常行号-keepattributes SourceFile,LineNumberTable抛出异常时保留代码行号
保留枚举值-keepclassmembers enum { ; }保留枚举类及其成员
保留构造函数-keepclassmembers class { public (android.content.Context); } 保留特定的构造函数
保留 Parcelable 序列化类-keep class implements android.os.Parcelable { ; }保留 Parcelable 序列化类
保留 Serializable 序列化类-keepclassmembers class implements java.io.Serializable { ; }保留 Serializable 序列化类
保留 DataBinding 相关类-keep class extends androidx.databinding.ViewDataBinding { ; }保留 DataBinding 生成的类
保留测试相关代码-dontnote junit.framework.保持测试相关的代码不被混淆
保留 WebView JavaScript 调用方法-keepclassmembers class fqcn.of.webview.IntoJava { ; }保留 WebView JavaScript 调用的方法
保留反射机制相关类-keep class com.example.app. { ; }动态加载的类不能被混淆
保留第三方库相关类-keep class retrofit2. { ; } -dontwarn retrofit2.防止混淆影响第三方库的正常工作
保留 Kotlin 元数据相关类-keepattributes SourceFile,LineNumberTable保留调试信息
保留行号相关类-renamesourcefileattribute SourceFile将文件来源重命名为“SourceFile”字符串
保留注解相关类-keepattributes Annotation保留注解不被混淆
保留签名相关类-keepattributes Signature保留泛型签名信息
保留异常行号相关类-keepattributes SourceFile,LineNumberTable抛出异常时保留代码行号
保留枚举值相关类-keepclassmembers enum { ; }保留枚举类及其成员
保留构造函数相关类-keepclassmembers class { public (android.content.Context); } 保留特定的构造函数
保留 Parcelable 序列化类相关类-keep class implements android.os.Parcelable { ; }保留 Parcelable 序列化类
保留 Serializable 序列化类相关类-keepclassmembers class implements java.io.Serializable { ; }保留 Serializable 序列化类
保留 DataBinding 相关类相关类-keep class extends androidx.databinding.ViewDataBinding { ; }保留 DataBinding 生成的类
保留测试相关代码相关类-dontnote junit.framework.保持测试相关的代码不被混淆
保留 WebView JavaScript 调用方法相关类-keepclassmembers class fqcn.of.webview.IntoJava { ; }保留 WebView JavaScript 调用的方法
保留反射机制相关类相关类-keep class com.example.app. { ; }动态加载的类不能被混淆
保留第三方库相关类相关类-keep class retrofit2. { ; } -dontwarn retrofit2.防止混淆影响第三方库的正常工作
保留 Kotlin 元数据相关类相关类-keepattributes SourceFile,LineNumberTable保留调试信息
保留行号相关类相关类-renamesourcefileattribute SourceFile将文件来源重命名为“SourceFile”字符串
保留注解相关类相关类-keepattributes Annotation保留注解不被混淆
保留签名相关类相关类-keepattributes Signature保留泛型签名信息
保留异常行号相关类相关类-keepattributes SourceFile,LineNumberTable抛出异常时保留代码行号
保留枚举值相关类相关类-keepclassmembers enum { ; }保留枚举类及其成员
保留构造函数相关类相关类-keepclassmembers class { public (android.content.Context); } 保留特定的构造函数
保留 Parcelable 序列化类相关类相关类-keep class implements android.os.Parcelable { ; }保留 Parcelable 序列化类
保留 Serializable 序列化类相关类相关类-keepclassmembers class implements java.io.Serializable { ; }保留 Serializable 序列化类
保留 DataBinding 相关类相关类相关类-keep class extends androidx.databinding.ViewDataBinding { ; }保留 DataBinding 生成的类
保留测试相关代码相关类相关类-dontnote junit.framework.保持测试相关的代码不被混淆
保留 WebView JavaScript 调用方法相关类相关类-keepclassmembers class fqcn.of.webview.IntoJava { ; }保留 WebView JavaScript 调用的方法
保留反射机制相关类相关类相关类-keep class com.example.app. { ; }动态加载的类不能被混淆
保留第三方库相关类相关类相关类-keep class retrofit2. { ; } -dontwarn retrofit2.防止混淆影响第三方库的正常工作
保留 Kotlin 元数据相关类相关类相关类-keepattributes SourceFile,LineNumberTable保留调试信息
保留行号相关类相关类相关类-renamesourcefileattribute SourceFile将文件来源重命名为“SourceFile”字符串
保留注解相关类相关类相关类-keepattributes Annotation保留注解不被混淆
保留签名相关类相关类相关类-keepattributes Signature保留泛型签名信息
保留异常行号相关类相关类相关类-keepattributes SourceFile,LineNumberTable抛出异常时保留代码行号
保留枚举值相关类相关类相关类-keepclassmembers enum { ; }保留枚举类及其成员
保留构造函数相关类相关类相关类-keepclassmembers class { public (android.content.Context); } 保留特定的构造函数
保留 Parcelable 序列化类相关类相关类相关类-keep class implements android.os.Parcelable { ; }保留 Parcelable 序列化类
保留 Serializable 序列化类相关类相关类相关类-keepclassmembers class implements java.io.Serializable { ; }保留 Serializable 序列化类
保留 DataBinding 相关类相关类相关类相关类-keep class extends androidx.databinding.ViewDataBinding { ; }保留 DataBinding 生成的类
保留测试相关代码相关类相关类相关类-dontnote junit.framework.保持测试相关的代码不被混淆
保留 WebView JavaScript 调用方法相关类相关类相关类-keepclassmembers class fqcn.of.webview.IntoJava { ; }保留 WebView JavaScript 调用的方法
保留反射机制相关类相关类相关类相关类-keep class com.example.app. { ; }动态加载的类不能被混淆
保留第三方库相关类相关类相关类相关类-keep class retrofit2. { ; } -dontwarn retrofit2.防止混淆影响第三方库的正常工作
保留 Kotlin 元数据相关类相关类相关类相关类-keepattributes SourceFile,LineNumberTable保留调试信息
保留行号相关类相关类相关类相关类-renamesourcefileattribute SourceFile将文件来源重命名为“SourceFile”字符串
保留注解相关类相关类相关类相关类-keepattributes Annotation保留注解不被混淆
保留签名相关类相关类相关类相关类-keepattributes Serialization