Example Script Entries - RetroGuard Documentation


Prev   Contents   Next

Classes

The simplest script line is to preserve a single class name. Note that the Java Virtual Machine syntax ('/' separators) is used rather than the Java Language syntax ('.' separators).

# Preserve class name 'com.myco.myClass' from obfuscation
.class com/myco/MyClass

Wildcards

Wildcard characters can be used to extend this to all classes in a single package (the '*' wildcard) or to all classes in all sub-packages (the '**' wildcard).

# Preserve all class names in package 'com.myco'
.class com/myco/*
# Preserve all class names in package 'com.myco' and in any sub-packages
.class com/myco/**

Methods and Fields

To preserve all public-access methods and fields in the specified classes, append the modifier 'public'. To limit this to just public methods or just public fields, also append the modifier 'method' or 'field'.

# Preserve all class names in package 'com.myco' and the public methods and fields in those classes
.class com/myco/* public
# Preserve all class names in package 'com.myco' and the public methods in those classes
.class com/myco/* public method
# Preserve all class names in package 'com.myco' and the public fields in those classes
.class com/myco/* public field

To preserve all public-, protected-, and package/default-access methods and fields in the specified classes, append the modifier 'protected'. To limit this to just public- and protected-access methods and fields, append the modifier 'pub_prot_only' instead.

# Preserve all class names in package 'com.myco' and the public, protected, or default-access methods and fields in those classes
.class com/myco/* protected
# Preserve all class names in package 'com.myco' and the public or protected methods in those classes
.class com/myco/* pub_prot_only method

Inheritance - extends

It is also possible to limit the '.class' script line to only those classes that extend a certain class or that implement a certain interface, using the 'extends' clause. The matching classes can extend the named class or implement the named interface at any level in the inheritance hierarchy.

# Preserve all class names in all packages where the class implements the interface 'java/io/Serializable'
.class ** extends java/io/Serializable
# Preserve all class names and their public methods in all packages where the class implements the interface 'java/io/Serializable'
.class ** public method extends java/io/Serializable

Access Flags

Finally, the '.class' line can be restricted to classes that have or lack certain access flags. These access flags are listed after '.class', separated by ';'. To specify that a class must not have a certain access flag, prepend '!' to the flag.

# In all packages, preserve all public, abstract class names that are not interfaces
.class;public;abstract;!interface **

Inner Classes

Inner classes are treated in the same way by RetroGuard as regular classes or interfaces. The naming convention for inner classes is that used in the class file format, so an inner class InnerCl within class OuterCl in package com.pk1.pk2 can be preserved from obfuscation with the script line:

.class com/pk1/pk2/OuterCl$InnerCl

Notice the use of the dollar $ sign to separate the inner class identifier from its parent class.

The impact of inner classes on the Java binary file format is described in Sun's Inner Classes Specification (End-Of-Life archived at Sun), reproduced here.


Methods

To preserve a particular method from obfuscation, use the '.method' script line. Note that the method is specified using the fully qualified method name followed by the JVM-style method descriptor.

# Preserve the method 'int countWords(String a)' in class com.myco.MyClass from obfuscation.
.method com/myco/MyClass/countWords (Ljava/lang/String;)I

Modifier: and_class

To preserve a method and the name of the class that contains it, append the 'and_class' modifier.

# Preserve the method 'int countWords(String a)' in class com.myco.MyClass from obfuscation, and also that class name.
.method com/myco/MyClass/countWords (Ljava/lang/String;)I and_class

Inheritance - extends

To preserve only those methods that are in classes extending a certain class or implementing a certain interface, append an 'extends' clause (it comes after the optional 'and_class' modifier).

# Preserve all methods named 'count*' ('countWords', 'countLetters', etc.) in all classes that implement the serializable interface, regardless of the method's descriptor
.method **/count* * extends java/io/Serializable

Access Flags

Method access flags can also be required or excluded. These access flags are listed after '.method', separated by ';'. To specify that a method must not have a certain access flag, prepend '!' to the flag.

# Preserve all private-access methods 'void writeObject(java.io.ObjectOutputStream s)' in all classes that implement the serializable interface
.method;private **/writeObject (Ljava/io/ObjectOutputStream;)V extends java/io/Serializable

Fields

Field script lines are virtually identical in syntax to method script lines. Some examples are given below.

# Preserve only non-'transient', non-'static' fields in all serializable classes
.field;!transient;!static ** * extends java/io/Serializable
# Preserve fields 'static final long serialVersionUID' in all serializable classes
.field;static;final **/serialVersionUID J extends java/io/Serializable

Comments

All text in a line that follows '#' is treated as a comment, and is ignored:

# This line is a comment and is ignored
.class com/myco/MyApp # end of line comments are also allowed

Attributes

By default, RetroGuard strips all debugging attributes from classfiles. Attribute script lines are used to preserve these attributes globally, for all processed classes.

# Preserve the 'SourceFile' debugging attribute for all classes
# (this is used in printed stack traces)
.attribute SourceFile
# Preserve the 'LineNumberTable' debugging attributes for all classes
# (used in printed stack traces)
.attribute LineNumberTable
# Preserve the 'LocalVariableTable' debugging attribute for all classes
# (used by debugging tools)
.attribute LocalVariableTable
# Preserve 'Deprecated' attributes for all classes
# (used by compilers to flag deprecated methods)
.attribute Deprecated

Options

Option lines are used to switch on certain RetroGuard behaviors or to represent several other RetroGuard script lines. RetroGuard's internal default script is equivalent to a list of these options. Other sections of the documentation describe these options in more detail: Application, Applet, Serializable, RMI, MapClassString, RuntimeAnnotations, Annotations, Enumeration.

.option Application # preserve all application classes and main methods
.option Applet # preserve all applet classes
.option MapClassString # remap Class.forName(...) automatically
.option DigestSHA # Generate MD5 and SHA-1 message digests for all classes
.option DigestMD5 # and resources adding the digests to the output jar manifest.

Negating Script Entries

Any '.class' '.method' or '.field' script line can be negated using the commands '!class' '!method' and '!field' later in the script file. This only makes sense when using wildcards. Consider the following example:

.class **
!class COM/rl/obf/**
.class COM/rl/obf/gui/*
!class COM/rl/obf/gui/Gui*

This means: preserve all class names; except those packaged anywhere under 'COM.rl.obf'; but do preserve class names in the single package 'COM.rl.obf.gui'; however, don't preserve the class names in 'COM.rl.obf.gui' that start with 'Gui'.

For all other script commands, order is irrelevant. However, for these negated commands the order they appear in the script file clearly matters.


Prev   Contents   Next
 Copyright © 1998-2007 Retrologic Systems.
 All rights reserved.