ProGuard Configuration File Translation Tutorial
This tutorial is divided into the following sections:
The ProGuard obfuscator is an open source tool. Being open source and freely available, it is often the first obfuscator that a developer might use.
However, ProGuard has only limited features. For example, it does not provide Flow Obfuscation,
Exception Obfuscation, Reference Obfuscation, AutoReflection, String Encryption or the "hardening" provided by Method Parameter Changing.
So the situation can arise where a ProGuard user may wish to migrate to Zelix KlassMaster.
This means that they need to translate their existing ProGuard configuration files to ZKM Script.
Also, ProGuard has been built into a number of build environments which have not provided an alternative, generic obfuscator interface.
The Android Development Tool plugin (ADT) for Eclipse is an example of such a tool.
So it would be convenient if a developer wishing to use Zelix KlassMaster rather than ProGuard could do a transparent swap.
Zelix KlassMaster provides broad support for ProGuard configuration files. It does this by translating ProGuard configuration files into ZKM Script on the fly.
So you can execute a ProGuard configuration file using Zelix KlassMaster just as you would if it was a ZKM Script file.
Incidentally, you can also translate a ProGuard configuration file into ZKM Script using the ProGuard Configuration File Translation Tool.
Zelix KlassMaster's log files to do not map cleanly to ProGuard's output files. See the table directly below.
Zelix KlassMaster file |
Closest ProGuard file |
Comment |
ZKM_PG_log.txt |
none |
This special a log file which Zelix KlassMaster uses to write messages relating to the translation of a ProGuard configuration file.
It will always be named "ZKM_PG_log.txt".
It will be written to the directory specified by the ZKM_DEFAULT_DIR configuration option if it has been set or otherwise
the directory specified by the user.dir property in the System properties.
|
ZKM_log.txt |
seeds.txt |
ProGuard has no direct equivalent of Zelix KlassMaster's log file. However, a verbose "ZKM_log.txt" file does contain the details of what is matched by the various exclusion statements.
In the context of ProGuard configuration file translation, the name and location of this log file will be set by the ProGuard -printseeds option if it exists.
Otherwise, it will be named "ZKM_log.txt" and it will be written to the default directory.
|
ZKM_TrimLog.txt |
usage.txt |
Lists used classes, fields and methods that have been trimmed
In the context of ProGuard configuration file translation, the name and location of this log file will be set by the ProGuard -printusage option if it exists.
Otherwise, it will be named "ZKM_TrimLog.txt" and it will be written to the default directory.
|
ChangeLog.txt |
mapping.txt |
Lists the mapping of old class, field and method names to obfuscated names
In the context of ProGuard configuration file translation, the name and location of this log file will be set by the ProGuard -printmapping option if it exists.
Otherwise, it will be named "ChangeLog.txt" and it will be written to the default directory.
|
In the context of ProGuard configuration file translation, the default directory is determined in the following fashion. It has the value of
- The ZKM_DEFAULT_DIR configuration option if it has been set or otherwise,
- The
-basedirectory option in the ProGuard configuration if it has been set or otherwise,
- The directory specified by the first encountered
-printseeds , -printmapping or -printusage option in the ProGuard configuration if it any have been set or otherwise,
- The directory specified by the
user.dir property in the System properties.
As mentioned above, Zelix KlassMaster provides broad support for ProGuard configuration files. However, it doesn't support all ProGuard configuration options.
When Zelix KlassMaster encounters one of the following options it will simply ignore them after reporting a warning.
Similarly, if Zelix KlassMaster encounters some aspect of a supported ProGuard option which it doesn't FULLY support then it will again report a warning.
Not supported |
-adaptclassstrings |
-adaptresourcefilecontents |
-adaptresourcefilenames |
-allowaccessmodification |
-dontnote |
-dontoptimize |
-dontskipnonpubliclibraryclasses |
-skipnonpubliclibraryclassmembers |
-dump |
-forceprocessing |
-keepdirectories |
-mergeinterfacesaggressively |
-optimizationpasses |
-optimizations |
-skipnonpubliclibraryclasses |
-target |
-useuniqueclassmembernames |
Not directly supported |
-microedition |
-printconfiguration |
-renamesourcefileattribute |
-whyareyoukeeping |
Zelix KlassMaster will construct a ZKM Script based upon the ProGuard configuration options which it is given.
However, this will give you just basic trimming and obfuscation without using any of Zelix KlassMaster's special obfuscation features.
You will often want to customize certain constructed ZKM Script statements with an alternative statement or to add extra ZKM Script statements for which there is no ProGuard equivalent.
You can do this by putting the customizing or additional ZKM Script statements into a file named "ZKMScript.txt".
Note that the content of the "ZKMScript.txt" file is just a list of customizing ZKM Script statements and is not an executable script in the normal sense.
It is different in that:
- Only the first occurence of a particular ZKM Script statement will be used,
- The order of the ZKM Script statements is not significant and
- The use of
/*...*/ block comments is not supported.
Also Zelix KlassMaster will only process the following statements in the "ZKMScript.txt" file. All others will be ignored.
- classpath,
- ignoreMissingReferences,
- trimExclude,
- trimUnexclude,
- trim,
- removeMethodCallsInclude,
- removeMethodCallsExcludeStatement,
- exclude,
- unexclude,
- stringEncryptionExclude,
- stringEncryptionUnexclude,
- obfuscateFlowExclude,
- obfuscateFlowUnexclude,
- accessedByReflection,
- accessedByReflectionExclude,
- obfuscateReferencesInclude,
- obfuscateReferencesExclude,
- fixedClasses,
- methodParameterChangesInclude,
- methodParameterChangesExclude,
- obfuscate.
If a customizing classpath statement is found then all paths that it specifies will be appended to the end of the classpath specified by the ProGuard configuration.
Similarly, if a customizing exclude,
unexclude,
trimExclude,
trimUnexclude,
ignoreMissingReferences,
removeMethodCallsInclude or
removeMethodCallsExclude
statement is found
then all the parameters that they specify will be appended to the end of any corresponding specifications made by the ProGuard configuration.
In all other cases, the customizing statement will override any equivalent configuration in the ProGuard configuration.
Zelix KlassMaster will look for the "ZKMScript.txt" file in the following directories.
- In the directory specified by the ZKM_DEFAULT_DIR configuration option if it has been set,
- In the directory specified by the
-basedirectory option in the ProGuard configuration if it has been set,
- In the directory specified by the first encountered
-printseeds , -printmapping or -printusage options in the ProGuard configuration if any have been set,
- Finally, in the directory specified by the
user.dir property in the System properties.
Zelix KlassMaster adds the following three convenience properties to the System properties that you are able to use as system variables
in your customizing ZKM Script statements in addition to the System user.dir property.
PROGUARD_LOG_DIR |
The absolute directory specified by the ProGuard -printseeds , --printusage or -printmapping command if present.
Otherwise it will be the directory specified by the ProGuard -basedirectory command if present.
Otherwise it will be the directory specified by the System user.dir property.
|
ZKM_LOG_DIR |
Same as PROGUARD_LOG_DIR except that the ZKM_DEFAULT_DIR System property if it is present will take precedence over the ProGuard -basedirectory command if present. |
PROGUARD_SAVE_DIR |
The absolute directory specified by the first ProGuard -outjars command if any are present. |
The contents of a basic example ZKMScript file appears below. It contains just a ZKM Script obfuscate statement.
It specifies light flow and exception obfuscation with relatively safe settings and that Strings should be encrypted.
Note that it makes use of the PROGUARD_LOG_DIR System property mentioned above.
//Start ZKMScript.txt with customizing statements
obfuscate keepGenericsInfo=false
keepInnerClassInfo=false
methodParameters=keepVisibleIfNotObfuscated
changeLogFileOut="%PROGUARD_LOG_DIR%\ChangeLog.txt"
obfuscateFlow=light
encryptStringLiterals=flowObfuscate
exceptionObfuscation=light
autoReflectionHandling=none
obfuscateReferences=none
randomize=true
preverify=false
mixedCaseClassNames=false
keepBalancedLocks=true
;
//End ZKMScript.txt
If the environment calls ProGuard through a batch or shell script file then you could directly edit that file to point to Zelix KlassMaster instead.
That is, a reference in the file to proguard.jar could simply be replaced with a reference to ZKM.jar .
Of course, you should back up the file before editing it and you would need to ensure that ZKM.jar can be found.
For example
call java -jar proguard.jar %*
would become
call java -jar ZKM.jar %*
Another option in the same scenario would be to replace the original proguard.jar with a dummy version which simply calls Zelix KlassMaster.
For example, you could replace proguard.jar with proguardStub_6.0.3.2.jar.
Again, you should back up the original proguard.jar before replacing it and you would need to ensure that ZKM.jar is in the the same directory as proguardStub_6.0.3.2.jar.
If you need to replace ProGuard in an Apache Ant build XML then, as mentioned above, you could replace the reference to proguard.jar with proguardStub_6.0.3.2.jar.
You can also simply change the reference to proguard.ant.ProguardTask to com.zelix.ZKM_PG_Task
but note that com.zelix.ZKM_PG_Task does not support the more complicated and verbose XML configuration.
Again you would need to ensure that ZKM.jar is in the classpath so that com.zelix.ZKM_PG_Task can be found.
In either case, you should back up the original build XML before editing it,
The Eclipse ADT plugin calls ProGuard via the <SDK>\tools\proguard\bin\proguard.bat file in Windows or the <SDK>/tools/proguard/bin/proguard.sh file in Linux.
These files can be directly edited to specify ZKM.jar rather than proguard.jar .
Note that when using the Android Development Tool you do not manually translate any ProGuard configuration into ZKM Script.
Rather, when ProGuard is replaced with Zelix KlassMaster, Zelix KlassMaster will automatically translate the ProGuard configuration passed to it by the Android Development Tool.
Android Studio 3.6 no longer allows you to use ProGuard. You must use R8. So unfortunately you cannot use Zelix KlassMaster in place of ProGuard in this version.
Everything set out below assumes that you are using a version of Android Studio prior to 3.6.
Newer versions of the Android Studio (prior to 3.6) treat ProGuard as a dependency of the Android Gradle plugin and will automatically upgrade it. That is not what you want if you want to replace ProGuard.
So the recommended approach is to first configure Android Studio so that it is successfully using a local copy of ProGuard that you have downloaded and then make changes so that it uses Zelix KlassMaster instead.
Step 1 is to configure Android Studio so that it is using a local copy of ProGuard.
You do this by adding two lines to your build.gradle file as is shown below.
buildscript {
repositories {
flatDir { dirs '/proguard' }
}
dependencies {
classpath ':proguard:'
}
}
The flatDir specifies a flat directory repository in your project directory.
Download the latest version of ProGuard and place the proguard.jar file into the proguard directory that you have created in your project directory.
Also, Android Studio 3.4 or better now uses the R8 compiler rather than ProGuard. So, to use Zelix KlassMaster rather than R8, you need to set android.enableR8=false in your gradle.properties file.
Check that ProGuard is being called successfully before going on to the next step.
Step 2 is to use Zelix KlassMaster rather than ProGuard.
- Rename the local
proguard.jar JAR file just so that you have it backed up,
- Download the proguardStub_6.0.3.2.jar JAR to the local
proguard directory and rename it to proguard.jar
- Put your ZKM.jar JAR file into a location where the renamed ProGuard Stub can find it.
The renamed ProGuard Stub will look in the following places.
- The directories specified by the System
java.library.path property which would normally be based upon the PATH environmental variable,
- The directory specified by the System
user.home property,
- The directory specified by the System
user.dir property,
- The directories specified by the System
java.class.path property,
- The directories specified by the System
java.endorsed.dirs property and
- The directories specified by the System
java.ext.dirs property.
Typically it would be easiest to put your ZKM.jar file in a folder that is specified by your PATH environmental variable.
Note that when using the Android Studio you do not manually translate any ProGuard configuration into ZKM Script.
Rather, when ProGuard is replaced with Zelix KlassMaster, Zelix KlassMaster will automatically translate the ProGuard configuration passed to it by the Android Studio.
The com.zelix.ZKMProGuardTranslate class appears in the Zelix KlassMaster JAR file distribution.
It provides a command line alternative to the ProGuard Configuration Translate tool GUI tool.
It is used as follows to translate a ProGuard configuration file into ZKM Script format.
java -cp ZKM.jar com.zelix.ZKMProGuardTranslate <proguardConfigFileName> <outputFileName>
The com.zelix.ZKMChangeLogConvert class appears in the Zelix KlassMaster JAR file distribution.
It provides a command line tool to translate a Zelix KlassMaster change log into ProGuard mapping file format.
This can be useful when a third party tool supports only the ProGuard mapping file format. The usage is as follows.
java -cp ZKM.jar com.zelix.ZKMChangeLogConvert <changeLogFileName> <outputFileName> [<pathToObfuscatedClasses>]
If the optional third parameter specifying the path to the obfuscated classes (e.g. the obfuscated JAR file) is specified then Zelix KlassMaster will include line number mappings
for those methods in the obfuscated JAR that have a LineNumberTable attribute.
Note that these line number mappings will be overlapping across methods if the "lineNumbers=scramble" setting has been specifed at the time of obfuscation.
If you are replacing ProGuard with Zelix KlassMaster in some environment that uses ProGuard by default then the very first step should be to make sure that you are successfully obfuscating using ProGuard.
Obviously if ProGuard is not being successfully called by the environment then attempts to replace ProGuard with Zelix KlassMaster will be ineffective.
In the context of translating a ProGuard configuration, if you are having problems then the first place to look is in the ZKM_PG_log.txt file.
If no ZKM_PG_log.txt file is being produced then Zelix KlassMaster is not being called to translate the ProGuard configuration.
As mentioned above, ZKM_PG_log.txt file will be written to the directory specified by the ZKM_DEFAULT_DIR configuration option if it has been set or otherwise
the directory specified by the user.dir property in the System properties. The ZKM_PG_log.txt file will show
- The full ProGuard configuration that is to be translated,
- The detail of any messages and warnings,
- The default directory for subsequent processing,
- The name and the location of the Zelix KlassMaster log file.
You can then look in the Zelix KlassMaster log file named in the ZKM_PG_log.txt file to see if there are any further warning and error messages.
|