Adding an Obfuscator
SandMark is designed to make it easy to add a new obfuscation
algorithm. Assume that we want to add a new obfuscation
ReorderMethods
. The process would be the following:
- Create a new directory
sandmark/obfuscate/reorderMethods
.
- Create a new class
sandmark/obfuscate/reorderMethods/ReorderMethods.java
.
- The
ReorderMethods
class should extend one of
the base classes AppObfuscator
(if the algorithm works
on the entire user program), MethodObfuscator
(if the algorithm works one method at a time),
or ClassObfuscator
(if the algorithm works
on one individual class at a time). Let's assume
that our algorithm reorders methods within one
class. ReorderMethods
should therefore
extend ClassObfuscator
, which looks like
this:
package sandmark.obfuscate;
public abstract class ClassObfuscator extends GeneralObfuscator {
protected ClassObfuscator(String label) {
super(label);
}
abstract public void apply(
sandmark.util.ClassFileCollection cfc, String classname)
throws Exception;
}
public String toString() {
return "ClassObfuscator(" + getLabel() + ")";
}
}
- The
ReorderMethods
class should look something
like this:
package sandmark.obfuscate.myobfuscator;
public class MyObfuscator extends sandmark.obfuscate.ClassObfuscator {
public MyObfuscator() {}
public String getAuthor() {
return "Jane Doe";
}
public String getAuthorEmail() {
return "doe@cs.arizona.edu";
}
public String getDescription() {
return "Turn all foos into bars by first turning them into yadas.";
}
public String getShortName() {
return "BarMaker";
}
public String getLongName() {
return "Turn foos into bars.";
}
public java.lang.String getAlgHTML() {
return "...";
}
public java.lang.String getAlgURL() {
return "sandmark/obfuscate/myobfuscator/doc/help.html";
}
public void apply(sandmark.program.Class cls) throws Exception {
// Actual code goes here!
}
}
- Use
BCEL
to implement your obfuscation.
The cls
parameter represents the set of classes
to be obfuscated. Use routines in sandmark.program.*
to open a class to be edited by BCEL
.
- Create a file
sandmark/obfuscate/myobfuscator/doc/help.html
documenting your work.
- Type
make
at the top-level sandmark directory (smark
).
The new obfuscation should be loaded automagically at runtime.
Example
Here is a real example of a simple obfuscator.
package sandmark.obfuscate.setfieldspublic;
/**
* The SetFieldsPublic obfuscator changes the field access modifiers
* of all of the fields in a class.
@author Christian Collberg
@version 1.0
*/
public class SetFieldsPublic extends sandmark.obfuscate.ClassObfuscator {
static int AND_MASK = ~(org.apache.bcel.Constants.ACC_PRIVATE
| org.apache.bcel.Constants.ACC_PROTECTED);
static int OR_MASK = org.apache.bcel.Constants.ACC_PUBLIC;
/**
* Constructor.
*/
public SetFieldsPublic() {}
public String getAuthor() {
return "Christian Collberg";
}
public String getAuthorEmail() {
return "collberg@cs.arizona.edu";
}
public String getDescription() {
return "Make all the fields and methods in a class public";
}
public sandmark.config.ModificationProperty[] getMutations() {
return null;
}
public sandmark.config.RequisiteProperty[] getPostprohibited() {
return new sandmark.config.RequisiteProperty[] {
new sandmark.config.AlgorithmProperty(this)
};
}
public String getShortName() {
return "Publicize Fields";
}
public String getLongName() {
return "Make all the fields/methods in this class public";
}
public java.lang.String getAlgHTML() {
return "...";
}
public java.lang.String getAlgURL() {
return "sandmark/obfuscate/setfieldspublic/doc/help.html";
}
/*************************************************************************/
/* Embedding */
/*************************************************************************/
public void apply(sandmark.program.Class cls) throws Exception {
sandmark.program.Field[] fields = cls.getFields();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessFlags((fields[i].getAccessFlags() & AND_MASK)
| OR_MASK);
}
cls.mark();
}
}