// free tools for java
T o o l s
-Old tools
  Hashjava is a java library to alter symbol names in a set of bytecode files. It includes an example application to obfuscate applets by renaming all class, method and field names to random strings. Using hashjava on your applets does not make it safe from decompilation, it just takes a little longer to make sense of it. Please use version 0.2 released on Jan 14, 1997 which contains an important bug fix.
  1. Download and extract the archive into some directory. This will create a subdirectory called hashjava
  2. Locate the file hashjavalib.zip which is under the hashjava directory.
    • If your java environment allows you to read classes from zip files, append the full path to hashjavalib.zip to the CLASSPATH environment variable. For instance, CLASSPATH=/java/lib/classes.zip:.:/hashjava/hashjavalib.zip
    • Otherwise, append the full path to the hashjava directory to the CLASSPATH environment variable. For instance, CLASSPATH=/java/classes:.:/hashjava
  3. Verify the setup. Go to some directory different from where you installed hashjava. Try running the class HashApplet. For instance,
    % java HashApplet
    If this creates a box with some license information, congratulations! Your installation was successful.
If you get something like "Can't find class HashApplet", then verify that the path in step 2 is correct. Also check if the CLASSPATH environment variable has indeed been updated.
  applet obfuscator
  Hashjava comes with an example application which obfuscates applets. You give it an html file containing applet tags, and an output directory to write out the obfuscated applets. The obfuscator loads the applets in the HTML file, renames field, method and class names in the bytecode and writes them all back into the output directory. Debugging symbols can be altered or removed. The altered symbol names are a mixture of random java keywords and numbers. This is usually sufficient to prevent casual inspection of your bytecode. However, control flow is not altered so loops and branches in your code will still be detected.
Play it safe! Back up your applets before using this application.
Start the application by running the class HashApplet
% java HashApplet
This will launch a session which you can guide to load, obfuscate and write out applets from an HTML file. If the obfuscation was successful, you will find a copy of the original HTML file and obfuscated bytecode in the output directory.
Watch out for these problems!
  • HashApplet does not detect images or other files that are explicitly loaded by the applet, so you will have to copy such files to make the obfuscated applet work again.
  • Some sequences of html can confuse HashApplet. If HashApplet incorrectly detects no applet tags in the HTML source, try using a simpler HTML file with just a set of applet tags.
  • HashApplet tries to duplicate the original directory structure of applets which use CODEBASE tags, but some combinations can defeat it. In particular, using a CODEBASE with an absolute URL will usually result in an incorrect directory structure.
  • If any classes are shared between applets which haven't been obfuscated at the same time, some applets will be incorrectly obfuscated. Obfuscate all applets at the same time -- create a single dummy html file with references to all your applets and run HashApplet on that file.
  • Stack traces will no longer be available. To preserve stack traces (but lose some obfuscation) retain source file names and line numbers.
  • If your code uses Class.forName(), HashApplet will incorrectly or incompletely obfuscate the bytecode. HashApplet will notify you when obfuscated classes use this call. You should turn off renaming class names, which correctly, but incompletely obfuscates the bytecode. To obfuscate all the bytecode, create a single dummy html file with references to all of your classes called through forName() (even if they don't subclass Applet) and run HashApplet on this file. You should still turn off renaming classes.

  HashApplet and mocha
  *Mocha is a popular freely available decompiler.
Mocha's author also provides an obfuscator *Crema, which however is not freely available if you want to obfuscate applets. The free version of Crema inserts illegal identifiers in applets which does not pass security checks in many browsers.
By default, HashApplet inserts a few confusing debugging attributes (this does not affect the applet unless it runs under a debugger) which consistently seems to crash mocha. If you change the settings to instead remove all debugging attributes, mocha appears to work again.

Here is mocha generated output on a class from one of the JDK demos before and after using HashApplet.
Atom atom =
if (atom == null)
    atom = defaultAtom;
atoms[i] = atom;
i *= 3;
vert[i] = f1;
vert[i + 1] = f2;
$1 $1 =
if ($1 == null)
    $1 = $0.Vector;
else[i] = $1;
i *= 3;
do[i] = f1;
do[i + 1] = f2;

  programming with hashjava
  Hashjava is really just a library to fix up references in a set of bytecode files as you alter symbol names in any of them. The hashjava API lets you add a set of classes and examine and alter symbols in them.
Obfuscation works in 3 steps
  1. Add all classes to be kept in sync.
  2. Alter desired symbols in each class.
  3. Write out the altered classes.
The Environment stores information about all the classes. It delegates the reading/writing of classes, and the chore of picking new symbol names to its instantiator.

So to create an Environment, you have to hand it an instance of the BytecodeFactory and the Obfuscator interfaces. You actually have to pass an instance of the Statistics interface as well, which effectively observes the state of the Environment.

The distribution includes Example.java under the hashjava/src directory. This is a small application which demonstrates how to use the library.
Once you create an Environment, obfuscation works in three stages.
  1. Add all the bytecode with the addClass() method. The Environment will automatically add any dependent classes (which are the superclasses or interfaces implemented by the class) using your BytecodeFactory interface. You can optionally ask for all dependencies to be loaded, which means any class referenced in the bytecode will be automatically added.
  2. Obfuscate the bytecode with the obfuscate() method. This calls your Obfuscator interface with every class in the environment. You can use the methods in ClassInfo to examine and alter symbols in each class.
  3. Write out the altered bytecode with the dump() method.

  Hashjava is freely distributed with source code under the GNU Library General Public License (LGPL). Code generated by hashjava does not fall under the same license, and you can obfuscate commercial or non-commercial code with no restrictions or license fees.

Under the LGPL, you can also use hashjava as a library and call its public classes or methods in commercial or non-commercial applications without disclosing your own source code, provided you supply the source code to hashjava, and enable anyone modifying hashjava (without changing its public API) to freely link with your application. The license has the final word in all cases, but feel free to contact me for any clarifications.

Yes, I know it is ironic to distribute a program which actively tries to mask source code under the LGPL. And despite the free-with-source-ware on this site, I believe in a programmers right to protect their source code when they choose to do so. The LGPL label allows everyone, especially hobbyist programmers like me, to easier and better protect their source code if they choose to do so.

T o o l s

Obfuscator | Installer | Assembler | Links | Old tools

http://www.sbktech.org/hashjava.html Revised: Tue Jan 14 08:41:24 1997
Copyright (C) 1996 KB Sriram.
Comments, bug reports: kbs@sbktech.org
Found something useful?