brief introduction
Java Code is very easy to decompile. In order to protect Java source code well, we often confuse the compiled class files.
ProGuard is an open source project that obfuscates code. Its main function is confusion, of course, it can also reduce the size of bytecode, optimization, etc., but those are secondary functions for us.
Official address: http://proguard.sourceforge .NET/
principle
Java is a cross-platform, interpreted language, Java source code compiled into intermediate "bytecode" stored in the class file. Because of the need of cross-platform, Java bytecode includes a lot of source code information, such as variable name, method name, and accesses variables and methods through these names. These symbols have a lot of semantic information and can easily be decompiled into Java.
Source code. To prevent this, we can use Java obfuscator to obfuscate Java bytecode.
Obfuscation is to reorganize and process the published programs so that the processed code can perform the same functions as the pre-processed code. It is difficult to decompile the obfuscated code, even if the decompilation is successful, to get the true semantics of the program. The obfuscated program codes still follow the original file format and instruction set, and the execution results are the same as before, except that the obfuscator changes the names of all variables, functions and classes in the code into short English alphabetical codes. In the absence of corresponding function names and program annotations, even if decompiled, it will be difficult. Read . At the same time, confusion is irreversible. In the process of confusion, some information that does not affect normal operation will be lost permanently. The loss of information makes the program more difficult to understand.
The role of obfuscator is not only to protect code, but also to reduce the size of compiled programs. Due to the shortening of variables and function names and the loss of some information introduced above, the volume of jar files can be reduced by about 25% after compilation, which is meaningful for the current expensive wireless network transmission.
grammar
-
- include {filename} Read configuration parameters from a given file
-
- basedirectory {directoryname} Specifies the base directory as the file name of the future relative directory.
-
- injars {class_path} specifies the application jar,war,ear, and directory to be processed
-
- outjars {class_path} Specifies the name of the jar,war,ear and directory to be output after processing.
-
- libraryjars {classpath} specifies the library files required for the application jar,war,ear, and directory to be processed
-
- Dontskip nonpubliclibraryclasses Specifies that non-public library classes are not to be ignored.
-
- Dontskip nonpubliclibraryclass members Specifies members of library classes that do not ignore package visibility.
-
-
Reserve options
-
- keep {Modifier} {class_specification} Protects specified class files and class members
-
- Keep class members {modifier} {class_specification} protect members of specified classes, and they will protect better if such classes are protected.
-
- keep classes withmembers {class_specification} protects the members of the specified class and class, provided that all the specified class and class members exist.
-
- keepnames {class_specification} protects the names of specified classes and class members (if they do not compress steps to delete)
-
- keep class membernames {class_specification} protects the name of the member of the specified class (if they do not compress the steps to delete it)
-
- keep classes with member names {class_specification} protects the name of the specified class and class members if all the specified class members are present (after the compression step).
-
- printseeds {filename} lists the member-keep options for classes and classes, and the standard output is to a given file.
-
-
Compression
-
- dontshrink Uncompressed Input Class File
-
-printusage {filename}
-
- dontwarn If there is a warning, it will not terminate.
-
-whyareyoukeeping {class_specification}
-
-
Optimization
-
- dontoptimize Class File without Optimizing Input
-
- assumenosideeffects {class_specification} optimization assumes that the specified method has no side effects.
-
- allowaccessmodification Allows access to and modification of modifier classes and class members during optimization
-
-
Confusion
-
- dontobfuscate
-
-printmapping {filename}
-
- Apply mapping {filename} Reuse mapping increases confusion
-
- obfuscation dictionary {filename} uses keywords in a given file as the name of the method to be obfuscated.
-
- Application of intrusive overload aggressively in confusion
-
- Useuniqueclass membernames
-
- Flatten package hierarchy {package_name} repackages all renamed packages and places them in a given single package
-
- repackage class {package_name} repackage all renamed class files in a given single package
-
- Dontusemixed class names.
-
- Keep attributes {attribute_name,...} Protects given optional attributes, such as LineNumberTable, LocalVariable Table, SourceFile, Deprecated, Synthetic, Signature, and
-
-
InnerClasses.
-
- renamesourcefileattribute {string} Sets the string constants given in the source file
Android Eclipse Development Environment and ProGuard
Before Android 2.3, obfuscating Android code was very inconvenient because only Proguard was added manually to achieve obfuscation. Since 2.3, Google has added this tool to the SDK toolset. Specific path: SDK tools proguard. When creating a new Android project, under the root path of the project directory, a Proguard configuration file proguard.cfg appears. That is to say, we can use ProGuard to confuse Android project directly in our elipse project through simple configuration.
The specific steps of confusion are very simple. First, we need to add a sentence in the project.properties file to enable ProGuard. As follows:
-
# This file is automatically generated by Android Tools.
-
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-
#
-
# This file must be checked in Version Control Systems.
-
#
-
# To customize properties used by the Ant build system edit
-
# "ant.properties", and override values to adapt the script to your
-
# project structure.
-
#
-
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-
# Project target.
-
target=android-19
In this way, Proguard can be used. When we normally export the Application Package through Android Tools (or use ant to execute release packaging), Proguard will automatically be enabled to optimize and obfuscate your code.
After the export is successful, you can decompile to see the effect of confusion. Some class names, method names and variable names have become meaningless letters or numbers. Prove success in confusion!
Instance (proguard file code interpretation)
-
-optimizationpasses 7 #Specify the compression level of the code0 - 7
-
-dontusemixedcaseclassnames #Whether to use case mixing or not?
-
-dontskipnonpubliclibraryclasses #If an application introduces a jar package and wants to confuse what's inside the jar packageclass
-
-dontpreverify #Whether to do pre-checking when confusing (can be removed to speed up confusion)
-
-verbose #Whether to log when confusing (mapping file map class name - > mapping of transformed class name after confusing)
-
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #Obfuscation of the algorithm used
-
-
-keep public class * extends android.app.Activity #Don't confuse all the subclasses of 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 com.android.vending.licensing.ILicensingService #Specify specific classes without confusion.
-
-
-keepclasseswithmembernames class * {
-
native <methods>; #Keepnative The method is not to be confused.
-
}
-
-
-keepclasseswithmembers class * {
-
public <init>(android.content.Context, android.util.AttributeSet); #Keep custom control classes unambiguous, and specify format constructs unambiguous.
-
}
-
-
-keepclasseswithmembers class * {
-
public <init>(android.content.Context, android.util.AttributeSet, int);
-
}
-
-
-keepclassmembers class * extends android.app.Activity {
-
public void *(android.view.View); #Keep the specified rules unambiguous (the onClick method configured for controls in the Android layout file is unambiguous)
-
}
-
-
-keep public class * extends android.view.View { #The way to keep custom controls specifying rules is not confused.
-
public <init>(android.content.Context);
-
public <init>(android.content.Context, android.util.AttributeSet);
-
public <init>(android.content.Context, android.util.AttributeSet, int);
-
public void set*(...);
-
}
-
-
-keepclassmembers enum * { #Keep enumerationenum Not to be confused
-
public static **[] values();
-
public static ** valueOf(java.lang.String);
-
}
-
-
-keep class * implements android.os.Parcelable { #Keep Parcelable unambiguous (aidl files cannot be confused)
-
public static final android.os.Parcelable$Creator *;
-
}
-
-
-keepnames class * implements java.io.Serializable #Classes that need to be serialized and deserialized cannot be confused (Note: Classes used for Java reflection can not be confused)
-
-
-keepclassmembers class * implements java.io.Serializable { #Protect the class members of the specified rules from being confused in the class that implements the Serializable interface.
-
static final long serialVersionUID;
-
private static final java.io.ObjectStreamField[] serialPersistentFields;
-
!static !transient <fields>;
-
private void writeObject(java.io.ObjectOutputStream);
-
private void readObject(java.io.ObjectInputStream);
-
java.lang.Object writeReplace();
-
java.lang.Object readResolve();
-
}
-
-
-keepattributes Signature #Filter generics (typesetting errors may occur if you don't write them, which is usually added)
-
-
-keepattributes *Annotation* #If annotations are useful in projects, this line of configuration should be added.
-
-
-keep class **.R$* { *; } #Keep the R file unambiguous, otherwise your reflection won't get the resource id.
-
-
-keep class **.Webview2JsInterface { *; } #Protect WebView's API s for HTML pages from confusion
-
-keepclassmembers class * extends android.webkit.WebViewClient { #If you use the complex operation of webview in your project, it's better to join.
-
public void *(android.webkit.WebView,java.lang.String,android.graphics.Bitmap);
-
public boolean *(android.webkit.WebView,java.lang.String);
-
}
-
-keepclassmembers class * extends android.webkit.WebChromeClient { #If you use the complex operation of webview in your project, it's better to join.
-
public void *(android.webkit.WebView,java.lang.String);
-
}
-
#Simple instructions for WebView: After the actual test, do Tencent QQ login. If you refer to the jar provided by them, without the code to prevent confusion of WebChromeClient, oauth authentication can not be callback. After decompiling the base code, you can see that they are useful to WebChromeClient. Just add this code.
-
-
-keepclassmembernames class com.cgv.cn.movie.common.bean.** { *; } #Convert JSON's JavaBean to protect class member names from confusion.
-
-
##################################################################
-
#The following are all third-party jar packages introduced into the project. The code in a third-party jar package is not our goal or object of concern, so we ignore it all without confusion.
-
##################################################################
-
-libraryjars libs/android-support-v4.jar
-
-dontwarn android.support.v4.**
-
-keep class android.support.v4.** { *; }
-
-keep interface android.support.v4.** { *; }
-
-keep public class * extends android.support.v4.**
-
-keep public class * extends android.app.Fragment
-
-
-libraryjars libs/gson-2.3.1-sources.jar
-
-libraryjars libs/gson-2.3.1.jar
-
-dontwarn com.google.gson.**
-
-keep class sun.misc.Unsafe { *; }
-
-keep class com.google.gson.** { *; }
-
-
-libraryjars libs/alipaySDK-20150602.jar
-
-dontwarn com.alipay.**
-
-dontwarn com.ta.utdid2.**
-
-dontwarn com.ut.device.**
-
-keep class com.alipay.** { *; }
-
-keep class com.ta.utdid2.** { *; }
-
-keep class com.ut.device.** { *; }
-
-
-libraryjars libs/android-async-http-1.4.6.jar
-
-dontwarn com.loopj.android.http.**
-
-keep class com.loopj.android.http.** { *; }
-
-
-libraryjars libs/baidumapapi_v2_4_1.jar
-
-dontwarn com.baidu.**
-
-keep class com.baidu.** {*; }
-
-keep class assets.** {*; }
-
-keep class vi.com.gdi.bgl.** {*; }
-
-
-libraryjars libs/libammsdk.jar
-
-dontwarn com.tencent.**
-
-keep class com.tencent.** { *; }
-
-
-libraryjars libs/locSDK_4.1.jar
-
-dontwarn com.baidu.location.**
-
-keep class com.baidu.location.** { *; }
-
-
-libraryjars libs/mframework.jar
-
-dontwarn m.framework.**
-
-keep class m.framework.** { *; }
-
-
-libraryjars libs/mta-sdk-1.6.2.jar
-
-dontwarn com.tencent.stat.**
-
-keep class com.tencent.stat.** { *; }
-
-
-libraryjars libs/nineoldandroids-library-2.4.0.jar
-
-dontwarn com.nineoldandroids.**
-
-keep class com.nineoldandroids.** { *; }
-
-
-libraryjars libs/open_sdk_r4889.jar
-
-dontwarn com.tencent.**
-
-keep class com.tencent.** { *; }
-
-
-libraryjars libs/ShareSDK-Core-2.5.9.jar
-
-dontwarn cn.sharesdk.framework.**
-
-keep class cn.sharesdk.framework.** { *; }
-
-
-libraryjars libs/ShareSDK-ShortMessage-2.5.9.jar
-
-dontwarn cn.sharesdk.system.text.**
-
-keep class cn.sharesdk.system.text.** { *; }
-
-
-libraryjars libs/ShareSDK-SinaWeibo-2.5.9.jar
-
-dontwarn cn.sharesdk.sina.weibo.**
-
-keep class cn.sharesdk.sina.weibo.** { *; }
-
-
-libraryjars libs/ShareSDK-Wechat-2.5.9.jar
-
-dontwarn cn.sharesdk.wechat.friends.**
-
-keep class cn.sharesdk.wechat.friends.** { *; }
-
-
-libraryjars libs/ShareSDK-Wechat-Core-2.5.9.jar
-
-dontwarn cn.sharesdk.wechat.utils.**
-
-keep class cn.sharesdk.wechat.utils.** { *; }
-
-
-libraryjars libs/ShareSDK-Wechat-Favorite-2.5.9.jar
-
-dontwarn cn.sharesdk.wechat.favorite.**
-
-keep class cn.sharesdk.wechat.favorite.** { *; }
-
-
-libraryjars libs/ShareSDK-Wechat-Moments-2.5.9.jar
-
-dontwarn cn.sharesdk.wechat.moments.**
-
-keep class cn.sharesdk.wechat.moments.** { *; }
-
-
-libraryjars libs/universal-image-loader-1.9.2-SNAPSHOT-with-sources.jar
-
-dontwarn com.nostra13.universalimageloader.**
-
-keep class com.nostra13.universalimageloader.** { *; }
-
-
-libraryjars libs/weibosdkcore.jar
-
-dontwarn com.sina.weibo.sdk.**
-
-keep class com.sina.weibo.sdk.** { *; }
A diagram is attached to illustrate how to configure the ignorance of third-party jar s.
Note that if there is a. so file in a third-party jar package, don't ignore it. Don't confuse the introduced third-party jar file, or you may report an exception.
file
ProGuard automatically runs when packaging an apk in release mode, where release mode refers to generating an apk through ant release command or eclipse project - > Android tools - > export signed (unsigned) application package.
In debug mode, proguard is not invoked for faster debugging.
If the ant command packages the apk, the proguard information file will be saved in the / bin/proguard folder under the engineering code.
If packaged with the eclipse export command, it will be in the / proguard folder. It contains the following files:
mapping.txt
This file is very important for representing a comparison table that obfuscates previous and subsequent codes. If your code will generate bug s after obfuscation, the log prompt is obfuscated code. If you want to locate the source code, you can reverse it according to mapping.txt.
Every release should keep it for easy checking when the version has problems. It can be saved according to the version number or release time, or put into the code version control.
dump.txt
Describes the internal structure of all class files in the apk.
seeds.txt
Lists classes and members that are not confused.
usage.txt
Lists the code deleted from the source code that does not exist in the apk.
Unobfuscated code
As the name implies, you can't obfuscate code. If you get obfuscated, you'll make mistakes.
1. Code requiring reflection
2. System Interface
3. Jni interface
4. Code requiring serial numbers and deserialization (JavaBean that implements the Serializable interface)
5. JavaBean (corresponding classes in JSON and XML) that interacts with metadata on the server side
……
Common mistakes
1) Proguard returned with error code 1. See console
> Update the proguard version
> Android-support-v4 is not confused
> Add missing Libraries
2) missing type parameter exception occurs when using gson package to parse data
> Add in proguard-project.txt
-dontobfuscate
-dontoptimize
> Add in proguard-project.txt
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
3) Type conversion errors
> Add in proguard-project.txt
-keepattributes Signature
4) null pointer exception
> Obfuscation and Filtering Relevant Classes and Methods
5) java.lang.reflect.UndeclaredThrowableException
> -keep interface com.dev.impl.**
6) Error: Unable to access jarfile ..libproguard.jar
> Path Problem
7) java.lang.NoSuchMethodError
> This is also the most common problem, because there is no relevant method, the method is confused, confusion filter out the relevant method.
----------------------
(end)