Basic information about using Allatori Obfuscator and usage samples can be found in the Tutorial.
Basic information about the obfuscation can be found in the FAQ.
Contents
Configuration file structure
Jars element
Classpath element
Keep-names element
Watermark element
Property element
Common settings
Configuration File Structure
Allatori Obfuscator's configuration file is a xml file with the following structure:
<config> <jars basedir="dir (optional)" single-jar="filename (optional)"> <jar in="name1.jar" out="name1-obf.jar"/> <jar in="name2.jar" out="name2-obf.jar"/> ... </jars> <classpath basedir="dir (optional)"> <jar name="lib1.jar"/> <jar name="lib2.jar"/> ... </classpath> <keep-names> <class template="class ClassName"/> <class access="protected+"/> <class template="class *.SomeClass" ignore="yes"> <field template="private+ *"/> <field access="protected+"/> <method template="private+ *(**)"/> <method access="protected+"/> </class> <method template="private set*(java.lang.String, *)"/> <field template="private long fieldName"/> </keep-names> <watermark key="secure-key" value="Information to be embedded"/> <property name="property-name" value="property-value"/> </config>
Note: all paths are resolved according to the configuration file location.
Jars Element
Jars element is used to set the jar(s) that should be obfuscated.
It should contain at least one jar element that defines a pair of jars - original jar and the jar for the obfuscated classes.
The jars element has the following attributes:
1. basedir - optional; contains a directory name.
Relative paths to the jar files will be resolved according to that directory.
2. single-jar - optional; contains a file name.
If it is set than Allatori will create a single jar file with all obfuscated classes.
The nested jar elements have the following attributes:
1. in - required; contains the name of the jar file that should be obfuscated;
2. out - required; contains the name of the resulting obfuscated jar file.
Can have the same value as in, in such case the specified jar will be overwritten with its obfuscated version.
Example:
<jars basedir="my-jars" single-jar="application.jar"> <jar in="first.jar" out="first-obf.jar"/> <jar in="another-dir/second.jar" out="another-dir/second-obf.jar"/> </jars>
In this example Allatori will take two jars for obfuscation (my-jars/first.jar and my-jars/another-dir/second.jar)
and will produce the following files:
my-jars/first-obf.jar - obfuscated vesrion of the my-jars/first.jar;
my-jars/another-dir/second-obf.jar - obfuscated version of the my-jars/another-dir/second.jar;
my-jars/application.jar - the jar that contains all classes of the both my-jars/first-obf.jar and my-jars/another-dir/second-obf.jar jars.
Classpath Element
Classpath element is used to set the obfuscated application's classpath.
It should contain at least one jar element with the name of the jar file.
Note that it is not necessary to reference all jars that are needed by your application in the classpath section, but you should understand that missing classpath elements can result in a weaker obfuscation.
Allatori will warn you about missing classes during the obfuscation process.
The classpath element has the following attributes:
1. basedir - optional; contains a directory name.
Relative paths to the jar files will be resolved according to that directory.
The nested jar elements have the following attributes:
1. name - required; contains the name of the jar file that should be added to the classpath.
The attribute can use wildcard syntax - '*' symbol matches any characters in the file name.
Example:
<classpath> <!-- Add library.jar to the classpath --> <jar name="library.jar"/> <!-- Add all jars in the lib directory to the classpath --> <jar name="lib/*.jar"/> </classpath>
Keep-names Element
Keep-names element is the most important in the configuring Allatori Obfuscator.
It defines the names of the classes, methods and fields that should not be renamed during the obfuscation process.
If the obfuscated application is a library you should generally keep all publicly available API.
For stand-alone alone applications you should keep at least the main class's name.
You should also keep names of the classes that are used via reflection.
The keep-names element contains the following elements:
field element specifies the fields which names should be unchanged;
method element specifies the methods which names should be unchanged;
class element specifies the classes which names should be unchanged, can in turn contain nested field and method elements.
These elements define rules for matching the names of the classes, fields and methods.
Matched names will be kept unchanged.
All elements can have either access or template attribute.
The access attribute matches access type and can have the following values:
Value | Description |
private | matches classes, fields or methods with private access |
private+ | matches classes, fields or methods with private or wider access |
package | matches classes, fields or methods with package access |
package+ | matches classes, fields or methods with package or wider access |
protected | matches classes, fields or methods with protected access |
protected+ | matches classes, fields or methods with protected or wider access |
public | matches classes, fields or methods with public access |
Value | Description |
class * | Matches all classes |
interface * | Matches all interfaces |
class *abc* | Matches all classes which contain "abc" in the full qualified name |
class * extends java.util.Enumeration | Matches all classes extending java.util.Enumeration |
class * extends *.Enumeration | Matches all classes that extend Enumeration |
class * instanceof java.io.Serializable | Matches all classes that are instances of java.io.Serializable |
class * implements *.MouseListener | Matches all classes that implement MouseListener |
Value | Description |
private * | Matches all private fields |
private+ * | Matches all fields |
protected+ * | Matches all protected and public fields |
static * | Matches all static fields |
public static * | Matches all public static fields |
public int * | Matches all public integer fields |
java.lang.String * | Matches all String fields |
java.lang.* * | Matches all fields with type is in the java.lang package |
my* | Matches all fields which names start with "my" |
Value | Description |
private *(**) | Matches all private methods |
private+ *(**) | Matches all methods |
private+ *(*) | Matches all methods with exactly one argument |
private+ *(*,*) | Matches all methods with exactly two arguments |
private+ *(java.lang.String) | Matches all methods with String argument |
private+ *(java.lang.String,**) | Matches all methods with the first String argument |
private+ *(java.lang.*) | Matches all methods with the argument which type is in java.lang package |
public get*(**) | Matches all public methods which names start with "get" |
public *abc*(**) | Matches all public methods which names contain "abc" |
private+ int *(**) | Matches all public methods which return type is int |
<keep-names> <!-- Matches classes with the name "Main" in any packages --> <class template="class *.Main"/> <!-- Matches classes with the name that ends with "Bean" --> <class template="class *Bean"> <!-- Matches all fields --> <field access="private+"/> <!-- Matches public integer fields --> <field template="public int *"/> <!-- Matches all static fields --> <field template="static *"/> <!-- Matches protected and public String fields --> <field template="protected+ java.lang.String *"/> <!-- Matches all methods --> <method template="private+ *(**)"/> <!-- Matches all getter methods --> <method template="private+ get*(**)"/> <!-- Matches all methods with String argument --> <method template="private+ *(java.lang.String)"/> </class> <!-- Matches serialVersionUID field in all classes --> <field template="static final long serialVersionUID"/> <!-- Matches writeObject methods in all classes --> <method template="writeObject(java.io.ObjectOutputStream)"/> <!-- Matches readObject methods in all classes --> <method template="readObject(java.io.ObjectInputStream)"/> </keep-names>
Watermark Element
Watermark element is used to set the key and value for the watermarking process.
The element has the following attributes:
1. key - required; the key that is used to embed a watermark into the application using steganography techniques;
2. value - required; any string that will be embedded into the application jars.
It can be such information as copyright, customer name, company name or any other information that uniquely identifies the build.
A watermark can be used to identify owners of the software or track the origin of a pirated copy.
Example:
<watermark key="secure-key-to-extract-watermark" value="Customer: John Smith; Date: xx.yy.zzzz"/>
Other examples of adding and extracting watermarks can be found in the tutorial: Step 5, Step 6, Step 7.
Property Element
Property element is used to set different obfuscation properties.
The element has the following attributes:
1. name - required; the name of the property;
2. value - required; the value for the property.
Allatori Obfuscator supports the following properties:
Property Name | Property Value |
|
The name of the file. Allatori will write obfuscation log to the specified file. If the property is not set no log file will be written. |
|
The name of the package. If all classes in the package are renamed than Allatori will move that classes to the default package. The usage of "" as default package can reduce the size of the resulting jar. |
|
Defines what should be done with the line number table (debug information).
Can have the following values: 1. obfuscate - the default and recommended value. Line number table's elements will be obfuscated and the original stack trace can be restored only with the log file and Allatori Stack Trace Utility. 2. remove - the line number table will be removed. It can reduce the size of the resulting jar. 3. keep - the line number will be kept unobfuscated. This option is not recommended and should be used for the debugging purposes on the development stage only. |
|
Enables/disables string encryption.
Can have the following values: 1. enable - the default value. String encryption is enabled. All string literals that can be safely changed with the encrypted version will be encrypted and Allatori will add a method to decrypt them on run-time. 2. disable - string encryption is disabled. |
|
Enables/disables member reordering.
Can have the following values: 1. enable - the default value. Member reordering is enabled. Usually developers place interconnected methods and fields one after another in the source file, and this sequence will be kept after the compilation process. Allatori will shuffle fields and methods order in the classfile. 2. disable - member reordering is disabled. |
|
Enables/disables control flow obfuscation.
Can have the following values: 1. enable - the default value. Control flow obfuscation is enabled. Allatori will slightly alter the control flow of the methods so that it will not change what the application performs at run-time but will make the automatic decompilation process much harder. 2. disable - control flow obfuscation is disabled. |
|
Defines the local variables naming scheme.
Can have the following values: 1. single-name - the default value. Almost all local variables will have one name. It is allowed by the Java virtual machine but can confuse a lot of decompilers. 2. abc - local variables will have unique names 'a', 'b', 'c', 'd', etc. 3. remove - the original local variable names information will be removed. It can reduce the size of the resulting jar. 4. keep - the local variables' names will be kept unchanged. This option is not recommended. |
<property name="log-file" value="log.xml"/> <property name="default-package" value=""/> <property name="line-numbers" value="obfuscate"/> <property name="string-encryption" value="enable"/> <property name="member-reorder" value="enable"/> <property name="control-flow-obfuscation" value="enable"/> <property name="local-variables-naming" value="abc"/>
Common settings
1. Preserving serialization members.
<keep-names> <class template="class * instanceof java.io.Serializable"> <field template="static final long serialVersionUID"/> <method template="void writeObject(java.io.ObjectOutputStream)"/> <method template="void readObject(java.io.ObjectInputStream)"/> <method template="java.lang.Object writeReplace()"/> <method template="java.lang.Object readResolve()"/> </class> </keep-names>
2. Applets.
<keep-names> <class template="class * instanceof java.applet.Applet"/> </keep-names>
3. Servlets.
<keep-names> <class template="class * instanceof javax.servlet.Servlet"/> </keep-names>
4. Midlets.
<keep-names> <class template="class * instanceof javax.microedition.midlet.MIDlet"/> </keep-names>
Additional information can be found in our
Tutorial
and FAQ.
If you have any questions feel free to contact us.
Our Support Department will answer all your questions and help you with configuring Allatori for your project.
Web: http://www.allatori.com
Mail: support@allatori.com