Android Project Confusion

Keywords: Android Java Gradle SDK

Proguard is a very efficient and convenient obfuscation tool. After using this tool to obfuscate and pack, the volume of apk decreases significantly, and the difficulty of decompilation increases.

ProGuard is a free Java class file reduction, optimization, confusion and pre-validation tool. It detects and deletes unused classes, fields, methods and attributes; optimizes bytecodes and deletes unused instructions; and renames the remaining classes, fields and methods with short meaningless names. The resulting applications and libraries are smaller, faster, and better optimized for reverse engineering.

And Proguard has been integrated into Android studio build system, you can use simple code to build apk when confusing packaging.

Official address: https://developer.android.google.cn/studio/build/shrink-code.html
II. Introduction to Use
Proguard is used. We need to configure Proguard in the build.gradle file of the project.

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

        debug {
            shrinkResources false
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
}

The getDefaultProguardFile('proguard-android.txt') method retrieves the default ProGuard settings from the Android SDK tools/proguard/folder.
Tip: For further code compression, try using the same proguard-android-optimize.txt file. It includes the same ProGuard rules, but also includes other optimizations that perform analysis at the bytecode level (within and between methods) to further reduce APK size and help improve its speed.

shrinkResources is to remove invalid resource files and compress resources.

Minify Enabled is to turn on confusion.

This is the default Proguard configuration. proguard-rules.pro is a file that needs to be created in your project. The level is the same as build.gradle file. Of course, you can change its file name at will, but you need to modify it in the configuration code. In fact, this file is Proguard's custom configuration file. There is no such file. Documents you build will be wrong.

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

If you want to use different ProGuard rules in a different channel version, add a proguardFiles attribute to the corresponding product Flavor code block. For example, the following Gradle file adds flavor2-rules.pro to flavor2 product flavors. Flar2 now uses all three ProGuard rules, because rules from release code blocks are also applied.

android {
    ...
    buildTypes {
        release {
        shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
        }
    }
    productFlavors {
        flavor1 {
        }
        flavor2 {
            proguardFile 'flavor2-rules.pro'
        }
    }
}

ProGuard outputs the following files each time it builds:

dump.txt// Describes the internal structure of all class files in APK.

Map.txt// provides the transformation between the original and confused class, method, and field names.

seeds.txt// lists unobfuscated classes and members.

usage.txt// lists the code removed from the APK.

These files are saved in / build/outputs/mapping/release /.

Proguard Basic Grammar

- keep does not confuse classes and members or is renamed

- keepnames prevents classes and members from being renamed

- keepclass members do not confuse members with being removed or renamed

Keep membernames to prevent members from being renamed

- keepclasses withmembers do not confuse or rename classes and members that own that member

- keep classes with member names to prevent classes and members that own that member from being renamed

It also supports wildcards*

for example

Don't confuse a class

-keep public class com.aoaoyi.example.abc { *; }

Don't confuse a package

-keep public class com.aoaoyi.example.* { ; }

Do not confuse subclasses of a class

-keep public class * extends com.aoaoyi.exampl.xy { *; }

The following configuration is commonly used in projects

//Foundation Confusion Configuration

//Specify the compression level of the code
-optimizationpasses 5  

//Optimizing allows access to and modification of modifiers for classes and class members
-allowaccessmodification  

 //No case mixing
-dontusemixedcaseclassnames 

//Specify classes that do not ignore non-public Libraries
-dontskipnonpubliclibraryclasses  

//Whether to log in case of confusion
-verbose    

//Ignore warnings and avoid some warnings when packaging. Without this, build an error
-ignorewarnings  

//Without prevalidation, prevalidation is one of the four steps of proguard. Android does not need prevalidation. Removing this step can speed up confusion.
-dontpreverify

//Enable this when type conversion errors occur in filtering generics
-keepattributes Signature  

//Keep line numbers for easy testing when throwing exceptions
-keepattributes SourceFile,LineNumberTable

//The algorithm used in confusion
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*  

//- Some common parts of Android development that need to be preserved

//Not confusing annotation correlation
-keepattributes *Annotation* 

//Keep the native approach unambiguous
-keepclasseswithmembernames class * {  
    native ;
}

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

//Not confusing Parcelable 
-keep class * implements android.os.Parcelable {   
public static final android.os.Parcelable$Creator *;
}

//Don't confuse Serializable
-keep class * implements java.io.Serializable {*;}
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {*;}


//- A category that cannot be confused.
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-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.view.View
-keep class org.xmlpull.v1.** { *; }

//Don't confuse our custom controls (inherited from View)
 -keep public class * extends android.view.View{
     *** get*();
     void set*(***);
     public (android.content.Context);
     public (android.content.Context, android.util.AttributeSet);
     public (android.content.Context, android.util.AttributeSet, int);
 }

//Not confusing R files
-keepclassmembers class **.R$* { 
    public static ;
}

//No confusion about android-support-v4 packages
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class * extends android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v4.widget
-keep class * extends android.support.v4.app.** {*;}
-keep class * extends android.support.v4.view.** {*;}
-keep public class * extends android.support.v4.app.Fragment


//support classes that do not confuse inheritance
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**


//Don't confuse log s 
-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}


//All methods to keep the parameter type in Activity as View
-keepclassmembers class * extends android.app.Activity {
          public void *(android.view.View);
}

 //JS call interface with WEBView is not confused
-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);
}

//For onXXEvent,** On*Listener with callback function, it should not be confused
-keepclassmembers class * {
       void *(**On*Event);
       void *(**On*Listener);
}

//No obfuscation of third-party libraries, which can go to the relevant third-party libraries to find obfuscated code, can not be used if obfuscated.


//Gson 
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.idea.fifaalarmclock.entity.***
-keep class com.google.gson.stream.** { *; }
-keep class com.Yourbean.** { *; }


//OkHttp3
-dontwarn okhttp3.logging.**
-keep class okhttp3.internal.**{*;}
-dontwarn okio.**


//Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

//RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}


//WeChat
 -keep class com.tencent.mm.** {*;}


//Glide Picture Library
 -keep class com.bumptech.glide.**{*;}


 //umeng
 -keepclassmembers class * {
         public  (org.json.JSONObject);
 }

 -keep class com.umeng.onlineconfig.OnlineConfigAgent {
         public ;
         public ;
 }

 -keep class com.umeng.onlineconfig.OnlineConfigLog {
         public ;
         public ;
 }

 -keep interface com.umeng.onlineconfig.UmengOnlineConfigureListener {
         public ;
 }


//Testin
-dontwarn com.testin.agent.**
-keep class com.testin.agent.** {*;}


# Alipay Wallet
-dontwarn com.alipay.**
-dontwarn HttpUtils.HttpFetcher
-dontwarn com.ta.utdid2.**
-dontwarn com.ut.device.**
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-keep class com.alipay.mobilesecuritysdk.*
-keep class com.ut.*

You used the above configuration file, and I believe most of the projects are OK.

Posted by andy666 on Fri, 12 Jul 2019 19:48:20 -0700