Sunday, May 8, 2011

Learn how to download applets and decompile Java class files

Update
This article is a little old now, so I've started a new series (as of April, 2010) on Java decompilers and obfuscators. Please follow that link for much more recent information. The content below is kept here only for legacy reasons.

Introduction
In our previous article, we demonstrated a simple method that can be used to easily download the class files of Java applets. In this article we'll show you how to decompile the Java class, turning the .class file back into a .java source code file.

Why do this?
If you're just joining us in Part 2 of our series, I feel the need to explain why we're doing this series in the first place:

First, we're a Java educational center. Telling you the bad about Java as well as the good is also educational. Whether it's bad or good, it is truth. The fact is that other people can decompile your Java classes, and you need to know that, and it's helpful to know how they can do it.
Second, and even more importantly, if you know how to decompile Java classes, you can also learn how to try stop it (assuming you're interested in stopping it).

Obtaining software to decompile Java class files
To decompile a Java class file, you're going to need some software specially made for decompiling Java class files (also called reverse-engineering). In this article we're going to show you how to decompile Java class files with a software package that goes by the name of Mocha.

Mocha is probably not the best decompiling software available today, but it is one of the first packages available - if not the first - and it's also free. Mocha is written in Java, so you'll also need a copy of the Java JDK, or the JRE.

Step 1: Download Mocha
Assuming that you already have a copy of the Java JDK, the first step in the decompilation process is to download Mocha. Click here to download Mocha.

Step 2: Install Mocha
After you've downloaded Mocha, install it in a directory according to the installation instructions that came with the Mocha software. At the time of this writing, the installation process simply consists of unpacking a ZIP file into a desired directory.

Decompiling a Java class file
In this article we're going to decompile the AnimatedAd.class Java class file we downloaded in Part 1 of this article. If you're at all familiar with our web site, you might know that the original source code for this class file is also available. This is good, because it gives us a chance to compare the original source code to the decompiled version of the source code.

If you're ready, let's begin the process of decompiling the class file. If you've installed Mocha properly, there's really very little to the process other than running Mocha.

Step 1: Open a DOS or Unix window
Running Mocha is very simple. Assuming you're using a Windows system, just open a DOS window, and move to the directory where you installed Mocha.

If you're using a version of Unix, open a Unix command-line window and move to the Mocha installation directory.

Step 2: Modify your CLASSPATH variable
In this step, modify your CLASSPATH environment variable to include the Mocha.zip file you just downloaded and installed.

For instance, using Visual Cafe 2.5 on a Windows95 computer system, I modified my CLASSPATH to look like this:

set CLASSPATH=C:\Apps\Win95\Symantec\VisualCafe2.5\BIN\COMPONENTS\SYMBEANS.JAR;
C:\Apps\Win95\Symantec\VisualCafe2.5\JAVA\LIB\CLASSES.ZIP;
C:\Apps\Win95\Symantec\VisualCafe2.5\JAVA\LIB;
C:\Temp\DevDaily\Java\Decompilers\Mocha.zip

This should all be one continuous line. (Actually, because my CLASSPATH is so long, I cheated and combined this step and the command from Step 4 into a DOS batch file named runmocha.bat.)

Step 3: Copy the class file to the Mocha installation directory
If you haven't done so already, copy the AnimatedAd.class file into the Mocha installation directory.

Step 4: Run the Mocha program
Once the CLASSPATH is set, you can run Mocha like this to decompile the AnimatedAd.class file:

java -classpath %CLASSPATH% mocha.Decompiler -v AnimatedAd.class
Notice that I included the -v option (verbose) to see a little more output than normal. It's not required, but it is helpful.

When Mocha runs, you'll see some output on your screen similar to Figure 1.

Decompiling AnimatedAd.class -> AnimatedAd.mocha
 Method init....................................................................
 ................................................................................
 ................................................................................
 ................................................................................
 ................................................................................
 ........................
 Method start................
 Method stop..............
 Method run.....................................................................
 .........................................................................
 Method mouseDown...............
 Method pause........
 Method drawMyString..............
 Method paint................
 Method numStringsUsed.........................
 Method getRandomInt.................................................
 Method <init>.............................

The decompiled source code
When Mocha runs, it also creates an output file named AnimatedAd.mocha. This file contains the decompiled Java source code - the source code it created by reading the AnimatedAd.class binary file.

The AnimatedAd.mocha file is too large to list here, but you can click here to view the reverse-engineered source code.

As a point of comparison, you can click here to view the original AnimatedAd.java source code.

Summary
I hope you enjoyed this two-part series on downloading and decompiling Java applets. If you have any questions or comments, please leave them in the comments section below.

(Editor's Note: The process of decompiling Java class files belonging to other businesses or individuals may be illegal in your city, state, or country. Frankly, I don't know for sure, because, to coin a phrase from Star Trek's (TM) Doctor McCoy, "I'm an editor, not a lawyer." In any case, this series of articles is not written to encourage that practice. These articles are presented only so you can learn to protect your own Java class files from reverse engineering.)

Protect Your Java Code from Reverse Engineering

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.

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<init>^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 <This will show the reverse engineered original source code>
II. Obfuscate your java application

Let us review how to obfuscate and protect your source code from reverse engineering using ProGuard 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.