Danny Mandel
(dmandel@cs.arizona.edu)
Anna Segurson
(segurson@cs.arizona.edu)
This algorithm replaces all the local int variables in a function with local java.lang.Integer. This is possible through byte code manipulation of the all of the instructions that depend on retrieving and storing int values.
The following is a list of changes to the byte code:
Original byte code | Replacement byte code |
istore <index> | new Ljava/lang/Integer; dup_x1 dup_x1 pop invokespecial java/lang/Integer/<init>(I)V astore <index> |
iload <index> |
aload <index> invokevirtual java/lang/Integer/intValue(V)I |
iinc <index> <num> |
new Ljava/lang/Integer; dup ldc <num> aload <index> invokevirtual java/lang/Integer/intValue(V)I iadd invokespecial java/lang/Integer/<init>(I)V astore <index> |
To apply this obfuscation we circulate through the byte code of a given method and if the instruction is one of the ones in the table above we replace that instruction with the corresponding replacement byte code. For example, this simple class:
public class VerySimp { public static void main(String[] args) { int a,b,c; a = 1; b = 22; c = a + b; for (int i = 0; i < 3; i++) { a+=2; } } }
is obfuscated to the following class:
public class VerySimp { public static void main(String[] args) { Integer integer2 = new Integer( 1 ); Integer integer3 = new Integer( 22 ); Integer integer4 = new Integer(integer2.intValue() + integer3.intValue()); Integer integer1 = null; for( integer1 = new Integer( 0 ); integer1.intValue() < 3; integer1 = new Integer( 1 + integer1.intValue() ) ) integer2 = new Integer( 2 + integer2.intValue() ); } }
There are no extra configuration parameters necessary to run this obfuscator.