Sun Java Solaris Communities My SDN Account Join SDN
 
FAQ

Protecting Code from Decompilers

 
 



Question

How do you protect your code from decompilers?

I have read in a few previous threads on the JDC forums, and elsewhere, about programs that can convert .class files back to their source code. I am curious about this for two reasons.

  1. I have heard of a product called "Mocha" which can do this.
  2. I am not thrilled with the idea that this can be done, and I am wondering how one would protect themselves from having their source code pulled from their distribution software.

This is definitely an issue that affects anyone deploying Java software. Does anyone know whether, in fact, this can be done? What can be done to prevent it?

Tip

A number of Java decompilers exist on and off the market (Mocha is one of the primordial utilities from which a number of subsequent, commercial and otherwise, versions have been derived). They vary widely in their effectiveness, but have gotten considerably better over the years.

The pseudo-art of bytecode protection is called obfuscation and generally relies heavily on name-mangling (rendering human-readable identifiers unintelligible in an attempt to cloak method, class, and variable names), adding empty or superfluous bytecode and/or actual bytecode modification. The last is 'safest' but breaks code (like Applet code) that must be verified. Encryption is a more general term that relates to the process of making (attempting to make) data indecipherable for transmission. Obfuscation is not quite the same, as it does not truly encipher .class data nor does it have anything to do with transmission per se. Truly encrypted .class files could be created, but they would be just as unintelligible to the VM as they are to you (until deciphering, at which case you are back to square one). Therefore, obfuscators must walk the fine line of producing bytecode that is valid (from the VM's standpoint) but also takes advantage of known decompiler weaknesses.

Regarding decompilation - yes, the code produced by decompilers is often significantly different from the code that was originally compiled, reflecting bytecode optimization on the part of the compiler and/or the decompiler (and occasionally decompiler mistakes as well). And as pointed out the code returned can often be an optimized version of the programmer's original intent.

By way of example here is an unoptimized and rather ugly .java source and the decompiled version produced by one of the many available decompilers (JAD 1.5.7 in this case). Notice in particular the introduction of the new import and an explicit rather than implicit no-arg constructor, or optimization of j = j + 1 and use of byte rather than int, and the loss of specific identifiers (replaced with a generic decompiler-enforced naming scheme):

* Decomp.java

public class Decomp {
public static void main(String[] args) {
System.out.println("hello");
int i = 3:
for (int j = 1; j < 10; j = j + 1) {
system.out.println("hiya");
}
}
}

* Decomp.jad

import java.io.PrintStream;

public class Decomp {
public Decomp() { }
public static void main(String args[]) {
System.out.println("hello");
byte0 = 3;
for (int i = 1; i <10; i++)
system.out.println("hiya");
}
}

.
. . .
. Note: The optimizer flag was not set for this compilation, thus byte0 = 3; is not read-only.

.
.
.

Acknowledgments

Thank you to member xhunterx for the solution to this question.

.
. . .
. Note: If you have a question to which you need an answer, try the Mobility Forums. You can read through the existing topics or register for your free Sun Developer Network membership and post new messages or threads. For more information, go to the Why Register page. .
.
.

Back To Top