If you are developing java application, it is important to understand that the java class files can be easily reverse engineered using java decompilers. In this article, let us explore how a java class file is reverse engineered and how to protect your source code from being reverse engineered by someone.
The java source code is compiled to a class file that contains byte code. Java Virtual Machine needs only the class file for execution. The problem is that the class file can easily be decompiled into the original source code using java decompiler tools. The best solution to prevent reverse engineering is to obfuscate the class file so that is will be very hard to reverse engineer. According to the dictionary Obfuscate means “to make obscure or unclear”. That is exactly what lot of java obfuscator tool will do as explained below.
I. Decompile Java class file.
Before understanding how to obfuscate the java code, let us first try to understand how someone can reverse engineer your java application. Following 3 steps explains how a class file is reverse engineered to the original java source code.
1. Create HelloWorld.java as shown below.
1. Create HelloWorld.java as shown below.
public class HelloWorld { public static void main (String args[]) { String userMessage = "Hello World!"; int userCount = 100; userCount = userCount + 1; System.out.println(userMessage); System.out.println(userCount); } }
2. Compile HelloWorld.java program and execute it to make sure it works properly.
$ javac HelloWorld.java $ java HelloWorld Hello World! 101
Java class file contains only byte code. If you try to view a class file, it will be non-readable as shown below.
$ vi HelloWorld.class Ãþº¾^@^@^@2^@ ^@^G^@^P^H^@^Q ^@^R^@^S ^@^T^@^V^G^@^W^G^@^X^A^@^F^A^@^C()V^A^@^DCode^A^@^OLineNumberTable ^A^@^Dmain^A^@^V([Ljava/lang/String;)V^A^@ SourceFile^A^@^OHelloWorld.java^L^@^H^@ ^A^@^LHello World!^G^@^Y^L^@^Z^@^[^G^@^\^L^@^]^@^^^L^@^]^@^_^A^@ HelloWorld^A^@^Pjava/lang/Object^A^@^Pjava/lang/System^A^@^Cout^A^@^ULjava/io/PrintStream;^A ^@^Sjava/io/PrintStream^A^@^Gprintln^A^@^U(Ljava/lang/String;)V^A^@^D(I)V^@!^@^F^@^G^@^@^@^@^@^B^@^A^@^H^@ ^@^A^@
3. Decompile HelloWorld.class file and view the original source.
For this demonstration let us use Jad decompiler which is free for non-commercial use.Download the appropriate jad for your platform. Use jad to reverse engineer the HelloWorld.class file to get the original source as shown below.
$ unzip jadls158.zip
$ ./jad HelloWorld.class
Parsing HelloWorld.class...
Generating HelloWorld.jad
$ vi HelloWorld.jad
II. Obfuscate your java application
Let us review how to obfuscate and protect your source code from reverse engineering usingProGuard a free GPL licensed software.
1. Download and Install ProGuard
$ cd /home/jsmith $ unzip proguard4.2.zip
2. Create a proguard config file
Create myconfig.pro that contains all the information about your java application.
- -injar : Specify the location of your jar file. i.e the compiled java application that contains the class files
- -outjar: This is the jar file proguard will create after obfuscation. This will contain all the mangled, obscure naming convention of the methods and variables in the class file if someone tries to reverse engineer.
- -printmapping: ProGurad outputs all the mapping information in this file for your reference.
- -keep: Indicate the class files or the methods that you don’t want ProGuard to obfuscate. For e.g. mypkg.MainAppFrame contains the entry point for the application with the main class, which will not get obfuscated in this example.
$ cat myconfig.pro -injars /home/jsmith/myapp.jar -outjars /home/jsmith/myapp-obfuscated.jar This is the obfuscated jar file -libraryjars /usr/java/jdk1.5.0_14/jre/lib/rt.jar -printmapping proguard.map -verbose -keep public class mypkg.MainAppFrame
3. Execute ProGuard.
$ cd /home/jsmith/proguard4.2/lib $ java -jar proguard.jar @myconfig.pro
This creates the following two files:
- myapp-obfuscated.jar: Contains the obfuscated class files of your application. You can distribute this without having to worry about someone reverse engineering your application easily.
- proguard.map: This file contains the mapping information for your reference.
4. Sample proguard.map file
This is a sample proguard.map file that indicates the original name of the java source objects (classfile, methods, variable etc.) and the new obfuscated name.
myapp.AppToolBar -> myapp.ae: javax.swing.JButton btnNew -> d javax.swing.JButton btnOpen -> e
5. Sample java source code (myapp.AppToolBar) before obfuscation.
btnNew = changeButtonLabel(btnNew, language.getText("new")); btnOpen = changeButtonLabel(btnOpen, language.getText("open"));
6. Sample java source code that was decompiled from the class file (myapp.ae) after obfuscation.
d = a(d, n.a("new")); e = a(e, n.a("open"));
You can see that the line “btnNew = changeButtonLabel(btnNew, language.getText(“new”));” got translated to “d = a(d, n.a(“new”));”, by the ProGuard, which will not make any sense to someone who is using java decompiler tools to reverse engineer the class file.