Guia de ofuscação de código do Android

O código ofuscado pode efetivamente aumentar a dificuldade de descompilação do projeto e, ao mesmo tempo, também pode reduzir adequadamente o tamanho do apk, o que é especialmente importante no processo de desenvolvimento real. Após um longo período de exploração, tenho uma certa compreensão de ofuscação de código. Anote minha experiência pessoal abaixo:

1. Um arquivo importante para confusão de código: proguard-rules.pro, se você excluí-lo acidentalmente, copie-o de outro local ou crie um você mesmo.

2. Ative a ofuscação:

Defina buildTypes->release->minifyEnabled em build.gradle como true para ativar a ofuscação de código

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

3. O significado de cada configuração no arquivo proguard-rules.pro

Explique alguns significados antes de configurar

  • -manter evitar que o alvo seja ofuscado
  • * Curinga, significa tudo, estendido: set* significa começar com set, *onEvent* significa contém a palavra-chave onEvent
  • <init> representa o método de construção
  • Métodos na classe <methods>
  • Atributos na classe <fields>
  • $ delimitador, identifica a classe interna
  • -keepclasseswithmembers mantém os membros das classes

(O sinal # é adicionado antes do item de configuração para indicar um comentário)

-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. Adicione a declaração do código que não precisa ser confundido em proguard-rules.pro:

a. Declare as partes que você não precisa confundir. Algumas classes falharão ao compilar se forem combinadas.

-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

O acima são os componentes básicos e dependências do android

b. A classe da camada de modelo (entidade) é recomendada para não ser confundida

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

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

c. Não é recomendado confundir pacotes de terceiros

Bibliotecas de bibliotecas de terceiros geralmente já estão confusas, então não há necessidade de confundi-las novamente

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

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

Em resumo, use -keep mais o que você deseja manter.

Aqui está outra maneira de configurar confusão rapidamente, usando a anotação @Keep


1. Precisamos importar antes de usar a anotação @Keep (a dependência do AndroidX já está incorporada, portanto não há necessidade de introduzir as seguintes dependências)

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

2. Adicione a seguinte configuração em proguard-rules.pro

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

3. Use a anotação @Keep nas coisas que queremos manter

@Keep
public class Test {

    private String name;

    public String getName() {
        return name;
    }

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

No código acima, definimos para manter a classe Test, para que não haja confusão ao empacotar

O que devemos fazer se quisermos apenas manter seus atributos ou métodos e o nome da classe estiver confuso? do seguinte modo

Modifique a seguinte configuração em proguard-rules.pro:

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

então no código

public class Test {

    @Keep
    private String name;

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

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

No código acima, o atributo name e o método getName() são evitados, e o nome da classe Test e o nome do método setName() ainda são confusos.

Bem, o resumo da ofuscação de código é quase assim, espero que seja útil a todos!

Acho que você gosta

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