Hi, not sure if this is the correct forum, but I have a few queries regarding obfuscation.
For those not aware, the aim of obfuscation is basically to prevent the user from being able to edit the provided classes (easily). This can be done with name, String, and flow obfuscation.
I'll give a quick run-down of each method.
Name Obfuscation
This is probably the harmless method out of them. The obfuscator gets each class/method/field name, and renames it to something pointless. (
e.g aaa, aab, aac).
This method only confuses the user, and does not cause any serious disruption when manipulating classes.
String Obfuscation
This method, however, does cause some problems. It gets every single String literal and encrypts it.
Here is an example:
// Original String
throw new SecurityException("Wrong Password");
// String encryption
throw new SecurityException(b(c("N\001\177\022k9#q\017\177n\034b\030")));
Funky, isn't it. I think it may be XOR encryption, but I honestly have no idea on this one.
Flow Obfuscation
Heh, this method causes
all the problems. This obfuscation method will make selection and looping constructs into some other equivalent (Like LABEL: or GOTO(LABEL) methods). This is all done in bytecode by the obfuscator, so when it comes to decompiling, the decompiler does not know what to do, and outputs complete crap, and sometimes bytecode commands (ifeq TAG_0) for example, when it cannot work out an obfuscated 'if' statement.
Here is an example of this method:
//Original
package test;
import java.util.*;
class Demo {
private Vector buffer = new Vector();
/**
* Return the position of the specified String in the
* buffer. Remove the String once if it has been found.
* Return -1 if the String isn't found. */
int getStringPos(String string) {
for(int counter=0; counter < buffer.size(); counter++) {
String curString = (String)buffer.elementAt(counter);
if (curString.equals(string)) {
buffer.remove(counter);
return counter;
}
}
return -1;
}
}
// Flow Obfuscation + Name Obfuscation
package a;
import java.util.Vector;
class a {
private Vector a;
public static int b;
a() {
a = new Vector();
}
int a(String s) {
int i;
int j;
j = b;
i = 0;
if(j == 0) goto _L2; else goto _L1
_L1:
String s1 = (String)a.elementAt(i);
s1.equals(s);
if(j != 0) goto _L4; else goto _L3
_L3:
JVM INSTR ifeq 48;
goto _L5 _L6
_L5:
break MISSING_BLOCK_LABEL_37;
_L6:
continue;
a.remove(i);
i;
_L4:
return;
_L2:
if(i >= a.size())
return -1;
if(true) goto _L1; else goto _L7
_L7:
}
}
I have looked at the bytecode, and there are noticable differences.
Upon seeing this, I went off and downloaded BCEL and Regexp from Jakarta Apache, and tried using these libraries. I have now written a few useful tools using BCEL (Refactoring and such), but so far I have failed at making a tool to remove Flow and String obfuscation.
I was wondering whether anybody with experience in this field would be interested in writing a few snippets demonstrating the removal of flow obfuscation? I am asking this free, although I do have a small amount of money in PayPal.
Thanks for your time,
~IR