Zelix KlassMaster - Documentation
 

The obfuscateReferencesExclude Statement

The ZKM Script obfuscateReferencesExclude statement allows you to specify which field or method references (i.e. accesses or calls) you do notwant to have obfuscated. Zelix KlassMaster™ obfuscates a field or method reference by replacing it with a Java Reflection API call and then String encrypting the field or method name. It has an effect only if your ZKM Script obfuscate statement has specified obfuscateReferences=normal. Successive obfuscateReferencesExclude statements have a cumulative effect.

If a obfuscateReferencesExclude statement has an accompanying obfuscateReferencesInclude statement then the obfuscateReferencesExclude statement removes field and/or method references from the set of references matched by that obfuscateReferencesInclude statement. If there is no accompanying obfuscateReferencesInclude statement then the obfuscateReferencesExclude statement removes references from the set of all field and method references in your bytecode.

Once a specification has been set its effect can be removed entirely by a following resetObfuscateReferenceExclusions statement. If your ZKM Script obfuscate statement uses the obfuscateReferences=normal setting then you must specify which field and/or method references you want to obfuscate. Otherwise no reference obfuscation will be done.

The remainder of this page is organized into the following sections.

Examples and Explanation

obfuscateReferencesExclude statement parameters must specify a field or a method reference. Both types may optionally start with a containedIn clause.

The containedIn clause

Both the field and method reference exclude parameters below can have an initial containedIn clause. The containedIn clause specifies the methods containing the field or method reference that will obfuscated. Put another way, it specifies the methods from which the field or method is referenced. For example you could tell Zelix KlassMaster™ to obscure all references to methods of java.lang.System but only where those references are contained in methods within your class pack0.Class0.

Put informally (with mandatory components in bold), the syntax of the containedIn clause is:
containedIn{ <methodExcludeParameter> }

Or with the <methodExcludeParameter> expanded:
containedIn{ <classAnnotations> <classModifiers> "<archiveQualifier>"!<packageQualifiers>.<className> <extendsClause> <implementsClause>
    <methodAnnotations> <methodModifiers> <methodName>(<argumentTypes>) <throwsClause> }

So you have a method specification within parentheses preceded by the keyword containedIn. If a obfuscateReferencesExclude statement doesn't have a containedIn clause then it is the same as if it has a containedIn clause like the following which specifies ALL methods. Such a containedIn clause is satisfied by all references.

containedIn{*.* *(*)}

For a method containing a reference to be matched by a containedIn clause, all of the following must be true for the clause's <methodExcludeParameter>:
  • Its containing class must match any class exclude parameter component.
  • Its annotations must match any specified method or method parameter level annotations.
  • Its modifiers (e.g. public native) must match all parameter method modifiers. So if the parameters are public static !synchronized then the method must be public, static and NOT synchronized to be matched.
  • Its name must match the parameter method name.
  • Its argument types (e.g. int[], java.lang.String) must match the parameter argument types if they exist. (A single parameter argument type of "*" matches any method argument types including no arguments.) If the parameter has no argument type then the method must take no arguments.
  • Its throws clause must contain all the classes specified in the exclude parameter's throw clause. So, if the exclude parameter's throws clause is throws java.io.IOException then the method must throw java.io.IOException or one of its subclasses to be matched.

Field reference exclude parameters

Put informally (with mandatory components in bold), the syntax is:
<containedInClause> <classAnnotations> <classModifiers> "<archiveQualifier>"!<packageQualifiers>.<className> <extendsClause> <implementsClause>
    <fieldAnnotations> <fieldModifiers> <fieldType> <fieldName>;

For a field reference to be matched by the statement, all of the following must be true:
  • The reference must occur in a method which matches the <containedInClause> if it exists.
  • Its containing class must match any class exclude parameter component.
  • Its annotations must match any specified field level annotations.
  • Its modifiers (e.g. public volatile) must match all parameter field modifiers. So if the parameters are public static !transient then the field must be public, static and NOT transient to be matched.
  • Its type (e.g. int[] or java.lang.String) must match the parameter field type if it exists.
  • Its name must match the parameter field name.
obfuscateReferencesExclude *.* *                      and //Match references to all fields
                         *.Class1 !transient int f* and //Match references to all non-transient "int" fields matching "f*"
                                                        //which are in classes with the unqualified name "Class1"
                          containedIn{pack0.* *(*)} java.lang.System * and //Match references to all fields in java.lang.System
                                                        //where the reference occurs in a method within the "pack0" package
                          *.* @*.MyAnnotation0 *;  //Match references to all fields annotated with a class matching "*.MyAnnotation0".

Method reference exclude parameters

Put informally (with mandatory components in bold), the syntax is:
<containedInClause> <classAnnotations> <classModifiers> "<archiveQualifier>"!<packageQualifiers>.<className> <extendsClause> <implementsClause>
    <methodAnnotations> <methodModifiers> <methodName>(<argumentTypes>) <throwsClause> +signatureClasses;

For a method to be matched by the statement, all of the following must be true:
  • The reference must occur in a method which matches the <containedInClause> if it exists.
  • Its containing class must match any class exclude parameter component.
  • Its annotations must match any specified method or method parameter level annotations.
  • Its modifiers (e.g. public native) must match all parameter method modifiers. So if the parameters are public static !synchronized then the method must be public, static and NOT synchronized to be matched.
  • Its name must match the parameter method name.
  • Its argument types (e.g. int[], java.lang.String) must match the parameter argument types if they exist. (A single parameter argument type of "*" matches any method argument types including no arguments.) If the parameter has no argument type then the method must take no arguments.
  • Its throws clause must contain all the classes specified in the exclude parameter's throw clause. So, if the exclude parameter's throws clause is throws java.io.IOException then the method must throw java.io.IOException or one of its subclasses to be matched.
obfuscateReferencesExclude *.* *(*)           and  //Match references to all methods
                         containedIn{pack0.* *(*)} *.* !static m*() and //Match references to all non-static methods taking no parameters with names matching "m*"
						                        //where the reference occurs in a method within the "pack0" package
                         *.* !static m*()   and  //Match references to all non-static methods taking no parameters with names matching "m*"
                         //Match references to all "native" methods. Also match the containing class.
                         *.*^ native *(*)  and  
                         *.* *(*) throws java.io.IOException and  //Match references to all methods that throw "java.io.IOException". 
                         //Match references to all "abstract" methods that  take a single String.
                         *.* abstract *(java.lang.String) and 
                         //Match references to all methods in pack1.Class1 along with the matching methods' return and parameter types
                         //Match references to all the methods of any class implementing "Serializable" in a package that matches "pack1.*"
                         pack1.* implements java.io.Serializable *(*) and
                         //Match references to all classes contained in a JAR file with a name matching "MyJar*.jar"
                         "MyJar*.jar"!*.* and 
                         //Match references to all methods annotated with a class matching "*.MyAnnotation0".
                         *.* @*.MyAnnotation0 *(*) and
                         //Match references to all methods in java.lang.System which occur in a method annotated with a class matching "*.MyAnnotation0".
                         containedIn{*.* @*.MyAnnotation0 *(*)} java.lang.System *(*);

Syntax

"obfuscateReferencesExclude" excludeParameter ("and" excludeParameter)* ";"

annotationSpecifier ::= ("@" [packageExcludeParameter] nameSpecifier) | annotationSpecifierAndList

annotationSpecifierAndList ::= ["!"] "(" annotationSpecifierOrList ("&&" annotationSpecifierOrList)* ")"

annotationSpecifierOrList ::= annotationSpecifier ("||" annotationSpecifier)*

classExcludeParameter ::=
   [annotationSpecifier] [["!"] "public" | "package"]
   [["!"] "abstract"] [["!"] "final"] [["!"] "interface"] [["!"] "synthetic"] [["!"] "enum"] [["!"] "annotation"]
   ["\"" archiveQualifier "\"" "!"] [packageExcludeParameter] nameSpecifier ["+"] [containingClause]
   [extendsClause] [implementsClause]

containedInClause ::= "containedIn" "{" "methodExcludeParameter" "}"

containingClause ::= "containing" "{" "memberAndList" "}"

excludeParameter ::= [containedInClause] fieldExcludeParameter |
[containedInClause] methodExcludeParameter

extendsClause ::= "extends" [annotationSpecifier] wildcardClassName

fieldExcludeParameter ::=
   classExcludeParameter [annotationSpecifier] [["!"] "public" | "protected"| "package"| "private"]
   [["!"] "static"] [["!"] "final"] [["!"] "transient"] [["!"] "volatile"] [["!"] "synthetic"] [["!"] "enum"]
   [type] nameSpecifier

fullyQualifiedClassName ::= name ("." name)*

implementsClause ::= "implements" [annotationSpecifier] wildcardClassName ("," [annotationSpecifier] wildcardClassName)*

memberAndList ::= ["!"] "(" memberOrList ("&&" memberOrList)* ")"

memberOrList ::= memberSpecifier ("||" memberSpecifier)*

memberSpecifier ::= fieldExcludeParameter | methodExcludeParameter

nameAndList ::= ["!"] "(" nameOrList ("&&" nameOrList)* ")"

methodExcludeParameter ::=
   classExcludeParameter [annotationSpecifier] [["!"] "public" | "protected"| "package"| "private"]
   [["!"] "abstract"] [["!"] "static"] [["!"] "final"] [["!"] "native"] [["!"] "synchronized"] [["!"] "synthetic"] [["!"] "bridge"]
   nameSpecifier "(" [ "*" | (parameter ("," parameter)*)] ")" ["throws" wildcardClassName]

name ::= (["0"-"9","a"-"z","A"-"Z","$","_"])+
   i.e. a Java identifer (e.g. a package, class, field or method name) with no wildcards allowed

nameAndList ::= ["!"] "(" nameOrList ("&&" nameOrList)* ")"

nameOrList ::= nameSpecifier ("||" nameSpecifier)*

nameSpecifier ::= wildcardName | nameAndList

packageExcludeParameter ::= packageName | packageNameAndList

packageName ::= wildcardName ("." wildcardName)* "."
   NB: the final "." is part of the package name

packageNameAndList ::= ["!"] "(" packageNameOrList ("&&" packageNameOrList)* ")"

packageNameOrList ::= packageExcludeParameter ("||" packageExcludeParameter)*

parameter ::= [annotationSpecifier] ("*" | "?" | type)

type ::=
   ("byte" | "short" | "char" | "int" | "long" | "float" | "double"| "boolean" |
   fullyQualifiedClassName) ("[]")*

wildcardClassName ::= wildcardName ("." wildcardName)*

wildcardName ::= (["*","0"-"9","a"-"z","A"-"Z","$","_"])+
   i.e. a Java identifer (e.g. a package, class, field or method name) with the "*" wildcard allowed
Where archiveQualifier is a relative or absolute archive path name with the "*" wildcard allowed. E.g. "/lib/*.jar" or "myJar0.jar"
 
ZKM Script obfuscateReferencesInclude statement The ZKM Script Language ZKM Script resetObfuscateReferenceExclusions statement