Obfuscation#
Principle#
Java is a cross-platform, interpreted language. Java source code is compiled into intermediate "bytecode" and stored in class files. Due to the need for cross-platform compatibility, Java bytecode contains a lot of source code information, such as variable names and method names. These symbols carry a lot of semantic information and can be easily decompiled into Java source code. To prevent this phenomenon, we can use a Java obfuscator to obfuscate Java bytecode.
Obfuscation is the process of reorganizing and processing the released program to make the processed code perform the same function as the original code. The obfuscated code is difficult to decompile, and even if decompiled successfully, it is difficult to determine the true semantics of the program. The obfuscated program code still follows the original file format and instruction set, and the execution result is the same as before obfuscation. The only difference is that the obfuscator changes the names of all variables, functions, and classes to short English letter codes. Without corresponding function names and program comments, even if decompiled, it will be difficult to read. At the same time, obfuscation is irreversible, and some information that does not affect normal operation will be permanently lost during the obfuscation process, making the program more difficult to understand.
The role of an obfuscator is not only to protect the code, but also to reduce the size of the compiled program. Due to the shortened variable and function names mentioned above, the size of the compiled jar file can be reduced by about 25%. This is meaningful for expensive wireless network transmission.
Syntax#
-include {filename} Read configuration parameters from the given file
-basedirectory {directoryname} Specify the base directory for future relative file names
-injars {class_path} Specify the application jar, war, ear, and directory to be processed
-outjars {class_path} Specify the name of the jar, war, ear, and directory to output after processing
-libraryjars {classpath} Specify the library files required by the application jar, war, ear, and directory
-dontskipnonpubliclibraryclasses Specify not to ignore non-public library classes
-dontskipnonpubliclibraryclassmembers Specify not to ignore package-visible library class members
Preservation options
-keep {Modifier} {class_specification} Protect specified class files and class members
-keepclassmembers {modifier} {class_specification} Protect specified class members, better protection if this class is protected
-keepclasseswithmembers {class_specification} Protect specified classes and class members, but all specified classes and class members must exist
-keepnames {class_specification} Protect the names of specified classes and class members (if they are not deleted in the compression step)
-keepclassmembernames {class_specification} Protect the names of specified class members (if they are not deleted in the compression step)
-keepclasseswithmembernames {class_specification} Protect the names of specified classes and class members, if all specified class members are present (after compression step)
-printseeds {filename} List the classes and class members of the -keep option, and output them to the given file
Compression
-dontshrink Do not compress input class files
-printusage {filename}
-whyareyoukeeping {class_specification}
Optimization
-dontoptimize Do not optimize input class files
-assumenosideeffects {class_specification} Assume that the specified method has no side effects during optimization
-allowaccessmodification Allow access and modification of classes and class members with modifiers during optimization
Obfuscation
-dontobfuscate Do not obfuscate input class files
-printmapping {filename}
-applymapping {filename} Reuse mapping to increase obfuscation
-obfuscationdictionary {filename} Use keywords in the given file as names for obfuscation methods
-overloadaggressively Apply intrusive overload during obfuscation
-useuniqueclassmembernames Determine unified obfuscation class member names to increase obfuscation
-flattenpackagehierarchy {package_name} Repackage all renamed packages and place them in the given single package
-repackageclass {package_name} Repackage all renamed class files and place them in the given single package
-dontusemixedcaseclassnames Do not generate various class names during obfuscation
-keepattributes {attribute_name,...} Protect the given optional attributes, such as LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses
-renamesourcefileattribute {string} Set the given string constant in the source file
Files#
mapping.txt
Comparison table of code before and after obfuscation, used for debugging, decompiling, etc.
dump.txt
Describes the internal structure of all class files in the APK.
seed.txt
Lists classes and members that have not been obfuscated.
usage.txt
Lists code that has been deleted in the source code and does not exist in the APK.
Common Issues#
- Proguard returned with error code
-
Update Proguard version
-
Do not obfuscate android-support-v4
-
Add missing libraries
- Missing type parameter exception when using Gson package for data parsing
- Add the following lines to proguard.cfg:
-dontobfuscate
-dontoptimize
- Add the following lines to proguard.cfg:
# 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.** { *; }
- Type conversion error
-keepattributes Signature
- NullPointerException
Obfuscate related classes and methods
- java.lang.NoSuchMethodError
No related method, the method has been obfuscated, obfuscate related methods to solve the issue
Bug troubleshooting: http://proguard.sourceforge.net/index.html#manual/troubleshooting.html
Note#
- Reflection should not be obfuscated
- System interfaces should not be obfuscated
- JNI interfaces should not be obfuscated
- There are also some special cases that need to be customized