Software developers invest a great deal of time, effort and money to bring a product to market. Whether it's a complete Java application, an applet for a Web site or a JavaBean component that performs some cool new function, you as a developer have a right to protect the inner workings of your Java classes from prying eyes. After all, you don't want someone looking at your super-secret algorithm or trying to analyze your classes to find potential security holes. Many developers feel confident that when they compile Java source code to bytecode, their classes will be safe. After all, who can read bytecode like a third-generation language?
Unfortunately, other developers don't have to. Decompilers allow unscrupulous developers to reverse-engineer your product and to extract source code from it. They allow others to access your or your company's intellectual property, the code that is at the heart of your application. It's a sad fact of life, but reverse engineering does occur. While there are laws to protect against intellectual property theft, the best defense is not to allow it to happen in the first place, by protecting your code from such tools. That's where SourceGuard comes in!
How Does SourceGuard Work?
SourceGuard takes existing Java class files and modifies them to protect against decompilation. You create a project, define the level of protection on a class, method and field level, and then allow SourceGuard to modify your classes. SourceGuard is capable of renaming classes, methods and fields, as well as removing extra debugging information and modifying the control flow of bytecode.
When SourceGuard is run, either manually or from the command line, it produces new copies of your classes that can then be redistributed. SourceGuard doesn't modify your original source code, only the compiled classes. This means that you as a developer don't need to be concerned with writing cryptic code or changing your variable names. SourceGuard does it all for you, and then produces protected classes.
SourceGuard is easy to install, and requires a JDK 1.1.5+ virtual machine with JFC. After you've downloaded the software from 4thpass's Web site, you need to run the installation application. SourceGuard uses InstallShield, which makes installation simple. You'll need to specify a password to use the trial edition, which is sent to you via e-mail when you register. There are two installation options: you can use either a Windows executable or an installation class file. If you run the Windows executable, SourceGuard will ask you to select a Java Virtual Machine from a list it detects. Then you simply specify the installation path. Otherwise you can run the installation class file with whatever Java virtual machine you like.
Using SourceGuard to protect your applications and applets is quite simple. After compiling your Java source code, you can run SourceGuard. It's a straightforward process to apply SourceGuard to Java classes, thanks to the Project Wizard that guides you through the task of creating project files. It requires you to specify a directory location for your Java classes, an output directory and your classpath. It's important to specify the correct classpath for any external libraries you use; otherwise you can run into problems. This includes the basic JDK packages as well. Figure 1 shows the Project Wizard in action, and how to set the classpath and output directory.
Once your project is complete, you can begin to assign rules to your classes. SourceGuard is extremely flexible, and allows you to assign different rule categories. Each class can have a category applied to it, or a class can be left unprotected. SourceGuard defaults to three categories, but you can add more as required. For example, if you'd like to treat the class with your main method differently from your proprietary packages, you can assign minimal protection for one and maximum protection for another. From the Class View menu, which can be seen in Figure 2, allows you to specify which methods and fields should be protected, and which should be left alone.
Once you've created and customized your project settings, protecting your Java classes is a breeze. Simply select the build menu option, or click on the build icon, and SourceGuard will create protected classes and place them in your project's output directory. This process can even be automated as part of your build process. SourceGuard provides a batch file and a Unix script, which takes as a parameter the name of a SourceGuard project. Simply run SourceGuard from your build tool and it will automatically protect your projects.
Protection from Decompilers
SourceGuard offers protection from decompilers and other reverse-engineering tools that seek to recreate the source code for Java class files. Several decompilers for Java are freely available. The two decompilers I used for testing were Mocha and DejaVu (distributed as part of the Object Engineering Workbench for Java). After creating a protected application, an applet and a JavaBean, I used the popular Mocha decompiler, and the results were reassuring. SourceGuard had taken my carefully named variables and replaced them with meaningless names. SourceGuard can also do the same with method and class names. As you can see from Table 1, decompiled code can be difficult to understand. When compiled with Mocha or DejaVu, variables have been replaced with meaningless names.
Decompilation with DejaVu
SourceGuard can also give you added protection that goes beyond renaming variables, classes and methods. It has the option to modify the control flow of Java class files, using its Bytecode Range Modification feature. When a method contains try/catch blocks, SourceGuard modifies the bytecodes to help prevent decompilation. With bytecode range modification enabled, Mocha and DejaVu were unable to correctly decompile methods that contained try/catch statements. This feature isn't enabled for all rule categories by default, however. You should make sure it is turned on if this level of protection is appropriate for your project, because it will make decompilation much more difficult.
SourceGuard offers significant protection against decompilation of Java classes by others. While not impossible, it makes the task of understanding decompiled code much less likely. The success of protection will vary from project to project; in general, however, the code produced is much more difficult to interpret than without SourceGuard's protection. If you have a small applet that has few methods and fields, it may be possible for someone to make rough assumptions about how the applet works. However, more complex examples with long methods become quite difficult to understand. Without the original source in front of me, it would be an extremely frustrating and time-consuming process. Furthermore, for methods that contained try/catch blocks and were protected by bytecode range modification, Mocha and DejaVu failed to produce valid source code.
While it doesn't prevent people from trying to interpret your applications, it does make the task extremely difficult and tips the effort-to-reward ratio in the original developer's favor.
Running your source code through a decompiler makes you aware of just how vulnerable unprotected classes can be. I'd feel much more confident that my source code is safe when it's protected against reverse engineering and decompilation by SourceGuard. Given the choice between releasing unprotected classes and classes run through SourceGuard, I'd take SourceGuard any day!
About the Author
- SourceGuard, from 4thpass;
- Mocha the Decompiler;
- DejaVu the Decompiler, distributed as part of OEW;
David Reilly has worked on network protocols and Web-related programming at Bond University, Australia. Since his conversion to Java in 1996, he has worked almost exclusively with the language, finding it both a joy to use and the most productive way to produce portable applications. David can be contacted by e-mail at [email protected]