Guía de ofuscación de código de Android

El código ofuscado puede aumentar efectivamente la dificultad de la descompilación del proyecto y, al mismo tiempo, también puede reducir adecuadamente el tamaño del apk, lo cual es especialmente importante en el proceso de desarrollo real. Después de un largo período de exploración, tengo una cierta comprensión de ofuscación de código Escriba mi experiencia personal a continuación:

1. Un archivo importante para la confusión de códigos: proguard-rules.pro, si lo elimina accidentalmente, cópielo de otro lugar o cree uno usted mismo.

2. Activa la ofuscación:

Establezca buildTypes->release->minifyEnabled en build.gradle en verdadero para habilitar la ofuscación del código

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

3. El significado de cada configuración en el archivo proguard-rules.pro

Explicar algunos significados antes de configurar

  • -mantener evitar que el objetivo sea ofuscado
  • * Comodín, significa todo, extendido: set* significa comenzar con set, *onEvent* significa que contiene la palabra clave onEvent
  • <init> representa el método de construcción
  • Métodos en la clase <methods>
  • Atributos en la clase <fields>
  • $ delimitador, identifica la clase interna
  • -mantener clases con miembros mantener miembros de clases

(El signo # se agrega antes del elemento de configuración para indicar un comentario)

-optimizationpasses 5                                                           # 指定代码的压缩级别
-dontusemixedcaseclassnames                                                     # 是否使用大小写混合
-dontskipnonpubliclibraryclasses                                                # 是否混淆第三方jar(建议注释掉)
-dontpreverify                                                                  # 混淆时是否做预校验
-verbose                                                                        # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*        # 混淆时所采用的算法

-keep public class * extends ****                                               # 保持哪些类不被混淆

-keepclasseswithmembernames class * {                                           # 保持 native 方法不被混淆
    native <methods>;
}

-keepclasseswithmembers class * {                                               # 保持自定义控件类不被混淆
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);     # 保持自定义控件类不被混淆
}

-keepclassmembers class * extends android.app.Activity {                        # 保持自定义控件类不被混淆
   public void *(android.view.View);
}

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

-keep class * implements android.os.Parcelable {                                # 保持 Parcelable 不被混淆
  public static final android.os.Parcelable$Creator *;
}

#使用WebView时JavascriptInterface不被混淆,同时需要保证自定义的JS与原生交互的接口对象不被混淆
-keepattributes *JavascriptInterface*

#保证R文件不混淆
-keep public class [你的应用包名].R$*{ public static final int *;}

-keep class MyClass;                                                            # 保持自己定义的类不被混淆

4. Agregue la declaración del código que no necesita confundirse en proguard-rules.pro:

a. Declare las partes que no necesita confundir.Algunas clases no se compilarán si se combinan.

-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.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.**
-keep public class com.android.vending.licensing.ILicensingService

Los anteriores son los componentes básicos y las dependencias de Android.

b. Se recomienda no confundir la clase de la capa Modelo (entidad)

-keep class  com.test.model.** { *; }

-keep class  com.test.domain.** { *; }  # 具体看实际项目包名和类

c. No se recomienda confundir paquetes de terceros

Las bibliotecas de bibliotecas de terceros generalmente ya están confundidas, por lo que no es necesario volver a confundirlas

#示例:百度地图SDK
-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.**{*;} 

#其他第三方lib混淆规则请参照它们的官方文档

En resumen, use -keep más lo que quiera conservar.

Aquí hay otra forma de configurar rápidamente la confusión, usando la anotación @Keep


1. Necesitamos importar antes de usar la anotación @Keep (la dependencia de AndroidX ya está integrada, por lo que no es necesario introducir las siguientes dependencias)

compile 'com.android.support:support-annotations:{version}'

2. Agregue la siguiente configuración en proguard-rules.pro

-dontwarn android.support.annotation.Keep
#保留注解
-keepattributes *Annotation*
-keep @android.support.annotation.Keep class **  #保留@Keep注解的类以及它的属性方法不被混淆

3. Usa la anotación @Keep en las cosas que queremos conservar

@Keep
public class Test {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

En el código anterior, configuramos para mantener la clase Prueba, por lo que no se confundirá al empaquetar

¿Qué debemos hacer si solo queremos mantener sus atributos o métodos, y el nombre de la clase se confunde? como sigue

Modifique la siguiente configuración en proguard-rules.pro:

-keep @android.support.annotation.Keep class **{
    @android.support.annotation.Keep <fields>;   #保留类里面被@Keep注解的属性
    @android.support.annotation.Keep <methods>;  #保留类里面被@Keep注解的方法
}

entonces en el codigo

public class Test {

    @Keep
    private String name;

    @Keep
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

En el código anterior, el atributo de nombre y el método getName() no se confunden, y el nombre de la clase Test y el nombre del método setName() aún se confunden.

Bueno, el resumen de ofuscación de código es casi así, ¡espero que sea útil para todos!

Supongo que te gusta

Origin blog.csdn.net/gs12software/article/details/48803823
Recomendado
Clasificación