Change Logs and Incremental Obfuscation
Change logs record the mapping of:
You should always let Zelix KlassMaster produce a change log when you perform your final obfuscation and then store it a safe place.
You will need it:
- old names to new names,
- original source line numbers to scrambled line numbers (if you used Line Number Scrambling),
- flow obfuscation data (if you used flow obfuscation).
This is the kind of stack trace you may get from an obfuscated application.
- to translate any stack trace you might get if your bytecode contains some bugs,
- to use as an input change log when you obfuscate future releases so that objects are consistently renamed.
This is called incremental obfuscation.
Without the change log that was produced when the application was obfuscated, the stack trace will be close to indecipherable.
Note that if you have a change log, you can use the Stack Trace Translate tool to help you decipher stack traces.
You can specify that a change log should be used as a guide when assigning new names to packages, classes, fields and methods.
When a change log is used in this way it is refered to as an input change log.
Input change logs are the basis of Zelix KlassMaster's incremental obfuscation.
When you are using the ZKM Script obfuscate statement, you can specify more than one input change log.
If more than one input change log is specified then the change logs are effectively merged.
Change logs appearing first in the list have precedence over those appearing later in the list.
By default, Zelix KlassMaster will honour the mappings in an input change log and it will give those mappings precedence over
any name obfuscation exclusion settings that may be in place. So input change log mappings overrule your exclusion settings.
This strictness is essential for incremental obfuscation.
However, the obfuscate statement also allows you to specify "loose" input change logs.
An input change log is specified as "loose" if the
looseChangeLogFileIn rather than the
is used with the obfuscate statement. Loose input change logs are different in that your exclusion settings
take precedence over the change log mappings. They are typically only usefull when you need to produce a slightly different for some special purpose.
They are not suitable for incremental obfuscation because the slight changes that can result
could break compatability with previous releases.
Incremental Obfuscation is the ability to consistently obfuscate subsequent versions of your bytecode such that:
This consistency is necessary:
- the same new names are assigned to each particular package, class, field and method in all releases,
- flow obfuscation is consistent across releases.
Zelix KlassMaster supports incremental obfuscation through its input change log functionality.
The change log generated when the previous version was obfuscated is specified as the input change log when the next release
is obfuscated. However, note that it is recommended that:
- for Java Serialization support,
- if you wish to release just a subset of your application's classes in the form of a patch.
Having said the above, Zelix KlassMaster does provide a limited ability to open only part of an application and successfully obfuscate it.
To do this, you would need to
- you always open and obfuscate all of the classes of your application even if you intend to release just the changed subset,
- your output and input change logs have different names so that one does not overwrite the other.
You don't want to accidentally loose your only copy of a change log.
Zelix KlassMaster will automatically update references in opened classes to the names of objects that have not been opened using the input change log as a guide.
However, this automatic processing applies to name obfuscation and not to the Trim function.
If you are using the Trim function and opening just a subset of your application then you must explicitly set your trim exclusions to reflect this.
Zelix KlassMaster will not trace for accesses to opened classes from classes which have not been opened.
Finally, it is recommended that if you are not opening the application as a whole then you should at least open archive files as complete units.
So, if your application consists of three archive files
allClassesOpened=false on your obfuscate statement,
- set the classpath so that the unobfuscated versions of all the unopened classes of the application can been located,
- specify an input change log which contains mappings for all the unopened classes of the application.
then it is recommended that you open or not open each of the three archives as a whole and not open just a subset of the classes in any of the archives.