Learn how to download applets and decompile Java class files - Part 2

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:

  1. 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.
  2. 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>............................. 

Figure 1 (above): This is the output Mocha generated and printed to my DOS window.

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.)

 

Is there any way to do this on a mac? Obviously us mac heads don't run dos ;) so I just was wanting to find out. Thanks!

Permalink

Here's a challenge for you:

Help me get the image files (either cubic or equirectangular) from this page:

http://www.travel-to-naxos.com/360.php?viewid=108

I want it purely because I collect 360 QTVR files of ancient Greek sites. I don't want to make money from it, or publish it in any way...I just want to be able to look at it as a QTVR file whenever I want to (I can handle the image to qtvr conversion).

Thanks!

Permalink

I just tested the steps shown in Part 1 of this article using a browser, and it works for me. It's just like looking at the css files from another site, you just figure out the url to the css files, and put that in the browser, or use wget.

Really, I think most Unix users probably use 'wget' or 'lynx' to download resources like this.

I haven't done this in a long time now, but I just searched around and found these following Java decompiler resources, which seem relatively recent:

My guess is that first link will be your best shot. For a while Jad was the best decompiler around, but support for it stopped at JDK 1.3.

Also, it's important to know that if a .class file (a) wasn't created with debugging on, or (b) the byte code was obfuscated, the results you see won't be of much help. I think "debugging on" used to be the default, because I remember you could make your class files smaller by turning it off, but I don't know what the default is these days.

Finally, you can probably see some of this information in Eclipse, and you should be able to get to a point where you can see the same information you can about SDK classes (without installing the SDK source), but again, that information is limited.

Permalink

i want to decompiler java source file without any software.

OK thanks for Suggetion....

If you want to try something using just the Java SDK, you can run the javap command to disassemble the class. For instance, if you have a compiled class named JavaStringToInt.class, you can run the following command to disassemble that class:

javap JavaStringToInt

For my simple class, this results in the following output:

Compiled from "JavaStringToInt.java"
public class JavaStringToInt extends java.lang.Object{
    public JavaStringToInt();
    public static void main(java.lang.String[]);
}

That's nice in that it shows you the public signature of the class.

If you really want to dig deeper, you can add the -c option to javap, like this:

javap -c JavaStringToInt

which results in this output:

Compiled from "JavaStringToInt.java"
public class JavaStringToInt extends java.lang.Object{
public JavaStringToInt();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

public static void main(java.lang.String[]);
  Code:
   0:	ldc	#2; //String 100
   2:	astore_1
   3:	aload_1
   4:	invokevirtual	#3; //Method java/lang/String.trim:()Ljava/lang/String;
   7:	invokestatic	#4; //Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
   10:	istore_2
   11:	getstatic	#5; //Field java/lang/System.out:Ljava/io/PrintStream;
   14:	new	#6; //class java/lang/StringBuilder
   17:	dup
   18:	invokespecial	#7; //Method java/lang/StringBuilder."<init>":()V
   21:	ldc	#8; //String int i = 
   23:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   26:	iload_2
   27:	invokevirtual	#10; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   30:	invokevirtual	#11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   33:	invokevirtual	#12; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   36:	goto	68
   39:	astore_2
   40:	getstatic	#5; //Field java/lang/System.out:Ljava/io/PrintStream;
   43:	new	#6; //class java/lang/StringBuilder
   46:	dup
   47:	invokespecial	#7; //Method java/lang/StringBuilder."<init>":()V
   50:	ldc	#14; //String NumberFormatException: 
   52:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   55:	aload_2
   56:	invokevirtual	#15; //Method java/lang/NumberFormatException.getMessage:()Ljava/lang/String;
   59:	invokevirtual	#9; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   62:	invokevirtual	#11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   65:	invokevirtual	#12; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   68:	return
  Exception table:
   from   to  target type
     3    36    39   Class java/lang/NumberFormatException
}

There are other options you can use with the javap command, which you can see when you run javap -help:

$ javap -help

Usage: javap <options> <classes>...

where options include:
   -c                        Disassemble the code
   -classpath <pathlist>     Specify where to find user class files
   -extdirs <dirs>           Override location of installed extensions
   -help                     Print this usage message
   -J<flag>                  Pass <flag> directly to the runtime system
   -l                        Print line number and local variable tables
   -public                   Show only public classes and members
   -protected                Show protected/public classes and members
   -package                  Show package/protected/public classes
                             and members (default)
   -private                  Show all classes and members
   -s                        Print internal type signatures
   -bootclasspath <pathlist> Override location of class files loaded
                             by the bootstrap class loader
   -verbose                  Print stack size, number of locals and args for methods
                             If verifying, print reasons for failure

Finally, out of curiosity, I just tried to look at this same class file from within Eclipse, and the information it shows is the same as the javap -c command shown above.

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.