Self-mockery moment

As a Java and Android developer, you’re all familiar with confusion. There are also confusion templates provided by various gods on the Internet, which are basically straightforward to use. But I still want to get this straight, because the work was confused this guy “played” several times, have to write it down in the little book.

introduce

The basic concept

Obfuscation is literally changing package names, class names, method names, and variable names in a project to confuse people. However, obfuscation involves code compression, optimization, validation, etc. Obfuscation is more appropriately called ProGuard.

ProGuard

PS: ProGuard website stuff.mit.edu/afs/sipb/pr…

ProGuard is Java’s tool for “obfuscating” Class files. Post the picture directly:

Chain of Responsibility model

  1. Shrink: ProGuard recursively determines which classes and class members are used and which others are discarded.
  2. Optimize: ProGuard further analyzes and optimizes the method. For example, some useless parameters are discarded, and some methods are inlined.
  3. Obfuscate (obfuscate) : This process is used to rename classes, methods, etc., which originally contain annotation meaning.
  4. Preverify: This step adds preverify information to a class.

All four steps are optional. Of course, on Android we generally keep the first three steps and ignore the PreVerify process to speed up the confusion.

The Android ProGuard

ProGuard is integrated with Android by default. The ProGuard tool is in the /tools/ ProGuard directory of the SDK directory. Obfuscation open method:

android {
    ...
    // AS is automatically generated
    buildTypes {
        release {
            // Obfuscate switch
            minifyEnabled true
            // Remove useless resource files
            shrinkResources true
            // proguard-android. TXT indicates the default obfuscation rule
            // proguard-rules.pro stands for custom obfuscation rules (filename and suffix can be modified)
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
Copy the code

The default proguard-android. TXT file is in the SDK directory /tools/ proGuard. There is also a proguard-Android-optimize.txt file in this directory. Our custom proGuard-rules. pro file has some basic obtrusion rules from proguard-Android-optimize.txt.

Confusion of grammar

The syntax confusion can be found in the ProGuard website above, but here are some common syntax rules.

1. Preserve classes and class members

keep Otherwise deleted or renamed Prevents being renamed
Class and class members -keep -keepnames
Class members only -keepclassmembers -keepclassmembernames
If you own a member, keep the class and its members -keepclasseswithmembers -keepclasseswithmembernames

2. Symbols in class members

symbol role
<init> Matches all constructors
<fields> Match all domains
<methods> Match all methods
* Matches all fields and methods

3. Some common wildcards

The wildcard role
* Matches characters of any length, but without the package name delimiter (.)
** Matches characters of any length and contains the package name delimiter (.)
* * * Matches any parameter type
. Matches any type of argument of any length
% Matches any primitive type
? Matches any single character in the class name

Other grammars are basically unchanged and are used in the obfuscation rules. If necessary, you can query them in the official system.

Custom obfuscation templates

B: well… This template is pretty much the same, so here are some common obfuscation rules.

# Optimization algorithm, generally not modified, from Google-optimizations ! code/simplification/arithmetic,! code/simplification/cast,! field/*,! class/merging/*# Code obfuscation compression ratio, between 0 and 7, default is 5, generally do not change
-optimizationpasses 5
The class name should be lowercase
-dontusemixedcaseclassnames
Do not ignore classes that are not public libraries
-dontskipnonpubliclibraryclasses
Optimization allows access to and modification of modifiers and class members
-allowaccessmodification
# map files generated after project confusion
-verbose
Do not perform preverification
-dontpreverify

# leave annotations unconfused
-keepattributes *Annotation*,InnerClasses
# Avoid confusing generics
-keepattributes Signature
Keep the line number when throwing an exception
-keepattributes SourceFile,LineNumberTable

Keep four components, custom Application, etc-keep public class * extends android.app.Activity -keep public class * extends android.app.Appliction -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 public class com.google.vending.licensing.ILicensingService -keep public class com.android.vending.licensing.ILicensingService# Keep native methods
-keepclasseswithmembernames class * {
    native <methods>;
}

The method parameters retained in the Activity are the view methods,
# This will not affect the onClick we wrote in layout
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}

Keep custom views
-keepclassmembers public class * extends android.view.View {
   void set* * * * (); *** get*(); public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); }# keep enumeration
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

Keep Parcelable serialized objects
-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

Keep members in R file
-keepclassmembers class **.R$* {
    public static <fields>;
}

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

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
# webView processing, the project does not use webView can be ignored
-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);
}

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- keep JS interface -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - keep reflection type -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - keep entity class -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - a third-party library confusing rules -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Copy the code

These are some common obfuscation rules, some of which are actually declared in the Android default obfuscation file. So the specific custom obfuscation rules will vary depending on the project.

Promiscuous product

After confusion, there are usually the following files:

  1. Dump. TXT: describes the internal structure of all classes in APK files;
  2. Mapping. TXT: provides mapping tables of classes, methods, and class members before and after the confusion
  3. Seeds.txt: Lists the classes and members that have not been confused
  4. Usage.txt: Lists the removed code

When I encounter confusion, I usually analyze it by looking at the mapping.txt file. If you encounter difficulties in Crash tracing, you can use the visual tool ProGuardgui. bat in /tools/ ProGuard /bin in the SDK directory to locate faults. An example is shown below:

Xue Case Caused by confusion

Scenario 1 Problem description: The business side integrates one of our SDK, and a page of SDK displays the Banner chart, which uses the customized ViewPager component of SDK. As a result, the business side fails to display the Banner chart. Possible cause: After decomcompiling apK and comparing the mapping. TXT file, it is found that key methods in the customized Adapter of the Banner chart are deleted. The support V4 ViewPager is kept, the PagerAdapter is not kept. The SDK relies on the V4 package through compileOnly (provided), so the customized Adapter can’t find the referenced relationship during project compilation and will be confused and optimized away. Lesson of thumb: For libraries that depend on compileOnly (provided), be aware of confusion of related classes, especially for SDK developers, as confusion can cause problems that are difficult to locate.

Scenario 2 Problem description: The business side has integrated one of our SDKS (yes, “again”), which has a skin replacement function, and the business side can implement skin replacement by constructing resource files in a specific format. However, the skin change function cannot be implemented in APK compiled by the business using the company’s compilation tool. Reason: Quick-witted, I quickly came up with the confusion problem and asked the business side to add a rule to keep all R files, which failed again. So began the long log reading process, again to determine the problem is the resource name confusion. Finally, it was found that although the business side kept the resource name in the local compilation environment, it still confused the resource in the company’s compilation environment, resulting in the failure of skin changing. Lesson of thumb: For resource-related functions, be careful about r-file confusion. Don’t trust businesses because they often have operations you don’t expect (manual antics…). .

I have encountered many problems related to confusion in my work, so I will not talk about them here, as long as we are careful.

conclusion

  1. Obfuscation is not a new topic, but it is a must for Java and Android developers, and should be treated with awe. .
  2. The benefits of obfuscation are self-evident by making decompilation more difficult and optimizing the code. But just to make it harder, decompilation can be a clue for those who are interested. Therefore, it is necessary to use more secure protection measures for sensitive code and data, such as hardening (hard wide wave: 360 hardening).

The resources

  1. Android security Attack and Defense, decompilation and obfuscation technology
  2. Android Studio obfuscates templates and common third-party obfuscations
  3. A confusing manual for Android developers
  4. ProGuard

Pay attention to wechat public number, the latest technology dry goods real-time push