CHAPTER 3

Tools of the Trade

In the last chapter, you looked at the very heart of a Java classfile. In the next chapter, you’ll perform an in-depth study of all the different ways to protect your code using everything from encryption to obfuscation. After that, you’ll move on to build your own simple decompiler.

In this chapter, you’re going to look at some of the automated tools as well as some simple techniques that hackers could use to modify your code, or worse, to recover your underlying source code. You’ll also take a brief look at all the major obfuscators from third-party vendors, because obfuscation is by far the most popular tool for protecting source code. I’ll be covering the theory behind these obfuscators in the next chapter.

But let’s begin the chapter by looking at the how someone might crack your applet or application. That way, you can avoid some of the most obvious pitfalls when you’re attempting to protect your code. Typically, you might use a key, an applet parameter, or even hard code in the IP address of a server so that only a licensed user can use your program. You’ll now look at just some of the ways someone might disable your protection schemes.

Employing Hexadecimal Editors

For many years, hackers have been using hexadecimal editors and other more sophisticated tools such as NuMega’s SoftICE and SmartCheck to get around licensing schemes on time-bombed versions of all kinds of software. Cracking demonstration versions of games that came with almost every computer magazine in the late 1980s and 1990s was a rite of passage for many of my fellow programmers.

Typically the programmer tried to protect their game or utility by checking to see if the date was 30 days after the installation date. After 30 days, the evaluation copy would cease to run. Alternatively, if they just couldn’t afford to buy the real thing, they’d set the time of their computer so that it would permanently be a couple of days before the evaluation expired. Or, if they were a bit clever, they’d realize that the developer had to store the install date somewhere. If they were lucky, it would be somewhere simple like in the INI file or the registry, and they could permanently set it to some far-off date, such as 1999.

The rite of passage was truly complete when the programmer could just about read Assembler, could set a breakpoint to narrow in on the security functions, could find the piece of code that checked the evaluation date, and could disable it or create a serial number or key that the program would accept so that the evaluation copy became a fully functional version of the software.

There were countless more sophisticated mechanisms for protecting the more expensive programs—the dongle immediately springs to mind, which has to rate as one of the most useless inventions known to man—with varying degrees of success. Usually most protection mechanisms did little more than keep the average person from disabling or cracking them. The tool of choice for this type of attack in the Java world is the Hexadecimal editor.

Far from learning from the past, most programmers are condemned to repeat it. The vast majority of license protection examples out there rely on something as simple as a conditional jump.

if condition = true {
    continue;
} else {
print “Evaluation Copy expired”;
    System.exit();
}

Suppose you come across an applet or application that you’d like to use yourself, but for some reason or other, you decide that you just don’t want to pay for it. Let’s look at an example of how this might work.

Applets are exceptionally easy to download; these days they mostly come in handy jar files, which make one neat, compact file. However, more often than not, they won’t work the first time if you try to serve the applet up on your own web server, because the applet is protected using a copyright parameter or getDocumentBase and getHost to restrict the applet to its original web server. The code sample below will cause the applet to exit before it reaches main() if it is not being served up from the Apress web site.

import java.applet.*;

public class Test extends Applet {
        public void init() {
                String host, validDomain;
                boolean isValid = false;

                host = getDocumentBase().getHost();
                validDomain = “www.apress.com”;
                isValid = host.equals(validDomain);

                // Continue if the applet is on the licensed domain otherwise exit
                if (isValid == false) {
                        System.exit(1);
                }
        }
        public void main() {
        // real work happens here
        }

}

However, you can edit a hexadecimal version of the file (see Listing 3-1) to change the condition so that it will work on any web server other than the Apress web site.

        isValid == true

Alternatively, you can edit the string www.apress.com to whatever domain you want to use with your favorite hexadecimal editor such as WinHex.1

I’ll return to this topic in the next chapter to examine ways around this problem and strategies you might want to employ to properly protect your code.

The Problem of Insecure Code

Even though in many cases no more than a hexadecimal editor is required to disable any protection mechanisms you might employ, nothing will stop a “would be” attacker from employing some lateral thinking. If you want to protect your code, then you should start thinking laterally too because plenty of other possibilities exist that take almost as little work as editing the binary directly.

Let’s start with something a little less obvious than a Hexadecimal editor. Instead of disassembling or decompiling an applet, why not take advantage of a classfile’s object-oriented nature and just extend it. You can hide static methods or simply override nonstatic methods. Take a look at the insecure code in Listing 3-2, for example.

You can co-opt this code by writing Listing 3-3.

In Listing 3-3, you can potentially override the test method if it’s poorly protected. In a Java classfile, you have access to the public and protected members with the code. The only things you can’t modify are the private members. But coders are an inherently lazy bunch, and more often than not, the code is not marked private.

Gary McGraw and Ed Felten laid out just what to avoid in their JavaWorld article “Twelve Rules for Developing More Secure Java Code,”2 which ultimately ended up in their book Securing Java: Getting Down to Business with Mobile Code (John Wiley & Sons, 1999). Here are those 12 rules:

  1. Don’t depend on initialization.
  2. Limit access to your classes, methods, and variables.
  3. Make everything final (unless there’s a good reason not to).
  4. Don’t depend on package scope.
  5. Don’t use inner classes.
  6. Avoid signing your code.
  7. If you must sign your code, put it in one archive file.
  8. Make your classes noncloneable.
  9. Make your classes nonserializable.
  10. Make your classes nondeserializable.
  11. Don’t compare classes by name.
  12. Secrets stored in your code won’t protect you.

There is even an automated tool, JSLint, that rips through static code to determine where someone’s code is not following these 12 rules. Unfortunately JSLint—not to be confused with another JSLint, the JavaScript Verifier—is no longer publicly available.

For your purposes, Rule 2 and Rule 3 are the most important. Wherever possible, define your class, method, and variables as private and final unless you have a good reason not to.

If you’re interested in studying this subject further, check out the nasty little Java file called PublicEnemy.java from Mark LaDue, which is widely available on the Web.3 This searches for Java files on your hard drive and changes the access flags for a class; by doing this, it doesn’t change the classfile’s ability to run, but it breaks as many of the rules above as possible.

Disassemblers

If you’ve spent any time with Java bytecode, you’ve gradually noticed different patterns and language constructs. With practice and a lot of patience, you will find that bytecode becomes just another language.

So far you’ve seen two disassemblers: javap, which comes as part of the JDK and ClassfileToXML from Chapter 2, which disassembles the classfile into an XML structure (see the downloads area of the Apress web site for the source code). Let’s take a brief look at some other disassemblers to see how they improve on the examples you’ve seen to date. It’s worth noting that most of these disassemblers are now purely of historical or academic interest and are virtually impossible to find, but as you would imagine, they are relatively easy to re-create.

  • IceBreaker
  • ClassNavigator
  • JavaDump

IceBreaker is useful for cracking classfiles that don’t fully decompile, ClassNavigator is an easy-to-use interactive graphical user interface (GUI) that helps you make your way around the classfile, and JavaDump4 gives you an excellent HTML output of any classfile in case you prefer HTML to XML. No current URLs were available for IceBreaker or ClassNavigator at the time of this writing.

Other worthy mentions go to Chuck McManis’s “Dumping Java Class Files” code,5 and Jasmine,6 a Java assembler or reassembler from Jon Meyer’s and Troy Downing’s book, the Java Virtual Machine (O’Reilly, 1997). I’m sure there are many, many more out there, so I apologize to anyone I’ve left out.

IceBreaker

Disassemblers can sometimes be much more effective than decompilers, especially when the decompilation process goes wrong. You may have come across your own examples where, under certain conditions, your favorite decompiler cannot recover the source.

Let’s take the example of when a decompiled classfile won’t recompile because Mocha’s control flow analysis wasn’t strong enough for the job. The resultant Java source is a mixture of partially decompiled Java code and some of the original Java bytecode commands—typically a number of goto statements that are not part of the Java language.

If this happens, then your options are pretty limited. You could disassemble the code yourself and try and guess what the original source might have been, or you can use IceBreaker, shown in Figure3-1, to simplify the job.

9781590592656_Fig03-01.jpg

Figure 3-1 Disassembling with IceBreaker

IceBreaker’s graphical interface consists of four panes. Your attempt at the target source code is in the top section of the GUI, and its corresponding bytecode is in the bottom-left frame. You can see that the target bytecode is in the bottom-right frame. Any differences in the bytecode show up in red. The fourth section at the very bottom of the application displays the output from IceBreaker. Your mission, should you choose to accept it, is to modify your code, rebuild it, and gradually remove any red lines so that your bytecode and the target bytecode are the same. When you reach that stage, you can be pretty sure that your code and the original source are identical, except, of course, for any original programmer comments. You can also conveniently do this method by method, rather than by having to bite off the whole classfile all at once.

Note  IceBreaker was written by a friend of mine, Martin Lambert, who is now CTO of SealedMedia. He hails from Surrey, near London, in the UK and he’s the only person I’ve ever known who has an Irish passport issued by the Irish consulate in Tehran. So better ask him to go ahead if you ever meet him in Customs.

IceBreaker really shines if your decompiled source breaks when you try to run the recompiled code. Because it allows a side-by-side comparison, you’re able to see whether the decompiler did its job correctly.

When decompilers were in their infancy, IceBreaker was very useful because none of the early decompilers was 100 percent effective. Difficult problems in the class files could be smoothed out and the source code could be reverse engineered by hand. However, now that the likes of the Java Decompiler (JAD) and SourceAgain are so effective, IceBreaker is probably more useful as a benchmarking tool. IceBreaker makes it very, very easy to tell just how precise a decompiler is because it immediately pinpoints any differences between your bytecode and the target bytecode.

ClassNavigator

Jim Alateras from Comware in Australia is the author of one of my favorite disassemblers, ClassNavigator. To be honest it is my favorite disassembler. The interface is all encompassing without being difficult to use, and all the information you need is presented in one neat, intuitive GUI.

ClassNavigator, shown in Figure3-2, displays a hierarchical map of the methods with the corresponding bytecode for each method as well as context-sensitive constant pool information in the top-right frame.

9781590592656_Fig03-02.jpg

Figure 3-2 The ClassNavigator interface

JavaDump

Many disassemblers are by-products of articles, or as in this case, a book. However, not everyone writes their article while they’re in high school. Matt Yourst wrote JavaDump for a Dr. Dobb’s Journal article called “Inside Java Class Files.” This article first appeared in January 1998, the year before he made it into MIT.

JavaDump, shown in Figure3-3, uses a classfile manipulation library called JCF and is perfect if all you want to do is to get an HTML version of the structure of a classfile in a format not too dissimilar from Javadoc.

9781590592656_Fig03-03.jpg

Figure 3-3 JavaDump output

JavaDump breaks the classfile into the following sections:

  • Constant pool
  • Class descriptor
  • Interfaces
  • Fields
  • Methods
  • Attributes

Items in the HTML file are typically hotlinked so that you can bounce around the constant pool, resolving any pointers to their corresponding data very quickly.

JavaDump uses the JDK 1.1 and is invoked using the following command, make sure that jcfutils.zip is in your classpath.

java lti.java.javadump.javadump [classfile.class] [-noconstpool]

The JCF utilities also include a StripDebug program that removes any debug information, line number attributes, and so on, and rewrites and saves your classfiles.

Decompilers

In 1991, James Gosling lead a team of Sun engineers who wrote the first Java Virtual Machine (JVM), which was known as Oak at the time. They then spent the next three years working on making inroads into the cable and telecommunications market with little or no success. It was early 1995 before the rest of the world began to take a real interest in Java, when HotJava and early beta versions of the JDK hit the developer community with a massive, resounding bang.

And yet it was only a year later when the first decompilers began to appear. It looks like the first public mention of a Java decompiler comes not from Mocha, but in a paper by Daniel Ford, an IBM researcher, in a whitepaper entitled “Jive: A Java Decompiler,” which describes a working decompiler.

The first and only beta of Mocha appeared very soon afterward, in June of 1996. Its author, Hanpeter Van Vliet, named Mocha after the place where Dutch colonists stole a coffee plant from the Yemenese, marking the beginning of the Java coffee trade in what was then known as the Dutch East Indies. Nobody paid any real attention to Mocha until the following August when an article appeared in c|net.

Since then, we’ve seen at least a dozen decompilers: Jive, Mocha, WingDis, the Java Optimize and Decompile Environment (JODE), SourceAgain, DejaVu, JAD, HomeBrew, JReveal, Decafe, JReverse, and jAscii. There are also a number of programs—Jasmine and NMI are two examples—that provide a front end to JAD or Mocha for the command-line impaired. Some, like Mocha, are hopelessly out of date, and several others are no longer available.

Let’s take a look at some of my favorite decompilers:

  • Mocha
  • SourceAgain
  • JAD
  • JODE

Apologies once again if I’ve missed your favorite decompiler, but many of the early decompilers, such as DejaVu and WingDis, have all but disappeared. I’m covering Mocha because it’s the most famous decompiler, SourceAgain because it is a great example of a professional supported decompiler, JAD because it is the best of the free decompilers, and JODE because it is one of only two open source decompilers that I know about—the other is HomeBrew.

Mocha

Many of the earliest decompilers have long since disappeared; in fact, Jive never even saw the light of day. Mocha’s life, like its author, Hanpeter Van Vliet, was short-lived. The original beta from June 1996 had a sister program, Crema, which cost $39. This protected classfiles from being decompiled by Mocha using obfuscation.

Because it is one of the earliest decompilers, Mocha is a simple command-line tool with no front-end GUI. It was distributed as a zip file of classes, which were obfuscated by Crema. Mocha is primed to recognize and ignore class files obfuscated by Crema. Not surprisingly jar files are not supported by Mocha; they didn’t exist when Mocha was originally written.

Mocha uses the JDK 1.02. If you are going to decompile a file using Mocha, make sure the mocha.zip file is in your classpath, and decompile it using the following command:

java mocha.Decompiler [-v] [-o] Hello.class

The decompiler was only ever released as a beta, and as I said, its author met with an untimely demise before he could turn it into what I would call production quality. Mocha’s flow analysis is incomplete and it fails on a number of Java constructs. Typically something like IceBreaker would have to be used in conjunction with Mocha to decompile anything other than the simplest Java classfiles. Several individuals have tried to patch Mocha, but these have been largely wasted efforts. It makes much more sense to use either JAD or SourceAgain. Like all early decompilers, Mocha could not decompile inner classes, which didn’t appear until JDK 1.1

Just before Hanpeter died he sold the code for Mocha and Crema to Borland, and some of the Crema obfuscation code made it into early versions of JBuilder. Just a few weeks after Van Vliet’s death, Mark LaDue’s HoseMocha appeared; this allowed anyone to protect their files from being decompiled with Mocha without having to pay for Crema.

SourceAgain

Paul Martino, the founder of Ahpah Software, is the brains behind SourceAgain.7 The original version was released in October 1997. There are actually two versions: a command-line version, and a professional version that can be plugged into several IDEs such as Symantec’s Visual Café.

Both SourceAgain and JAD are not written in Java; I suspect either C or C++. The SourceAgain program is distributed as an executable, and its installation is straightforward. Ahpah Software claims that SourceAgain decompiles all Java’s language constructs, and as yet, I’m not going to disagree with that statement.

For our purposes, SourceAgain helps separate the early decompilers like Mocha and DejaVu from a second generation of decompilers because their capabilities are so different. First-generation decompilers can be defined as decompilers that cannot handle inner classes. SourceAgain is a very good example of a second-generation decompiler and it supports up to JDK 1.3. Not only can it handle inner classes, it also offers variable name massaging for obfuscated code that has mangled variable and method names.

The Java Decompiler (JAD)

JAD is fast, free, and very effective, and it was one of the first decompilers to handle inner classes properly. It’s probably the simplest command-line tool to use in this entire chapter. The last available version of JAD is v1.58 from November 2001, and according to the FAQ, the major known bug is that it doesn’t handle inline functions very well, which really shouldn’t be an issue because most compilers leave it to the JIT engines to perform any inlining.

JAD8 is the work of Pavel Kouznetsov, a graduate of the Faculty of Applied Mathematics at Moscow State Aviation School, who was living in Cyprus a few years ago.

For most cases, all you need to do to use JAD is type the following:

jad target.class

For a one-man show, JAD is remarkably complete. Its most interesting feature is that it can annotate source code with the relevant parts of a classfile’s bytecode so that you can see just where each part of the decompiled code came from. This is a great tool for understanding bytecode.

There are many, many GUIs that use JAD as the decompiler engine such as NMI9 (which originally used Mocha) and Front End Plus (no URL available) from the UK.

JODE

Jochen Hoenicke first wrote guavad, which according to his web page, is a Java disassembler not too dissimilar from javap, while working at the University of Oldenberg in Germany. Over the past few years, this has gradually turned into a full-scale decompiler and obfuscator package named JODE,10 which appears in Figure3-4.

9781590592656_Fig03-04.jpg

Figure 3-4 The JODE Decompiler

The best way to call JODE is to use the applet window as shown here:

java jode.decompiler.Window

An applet not too dissimilar to Figure3-4 appears. Enter the classfile you want to decompile, click start, and assuming it’s on your editable classpath, the source will appear in the main frame.

If, after you finish this book, you get the sudden urge to write your own decompiler, then another place to look is at one or the other of the open source decompilers. Jochen’s JODE decompiler is a very good place to start.

Obfuscators

Wherever there is a decompiler, you can be pretty sure that you’ll find some sort of obfuscator. Java decompilers are so successful because a classfile carries so much information around with it. Even without the programmer’s comments, the variable names and method names help anyone reading decompiled source to understand the flow and logic of the Java program.

Obfuscators cannot prevent decompilation, but they can scramble the names into unintelligible control characters or Java-like keywords to make it more difficult for humans to understand. However, and you’ll see more of this in the next chapter, it’s a pretty sad indictment of Java obfuscators that the introduction of Java inner classes in the JDK 1.1 were far more effective at stopping decompilers than most obfuscation techniques currently in use.

In a scene reminiscent of the cold war arms race during the 1960s and 1970s, obfuscators and decompilers will no doubt battle it out to see who can control the source code. But like the arms race, it is the missile or, in this case, the decompiler that almost always wins.

You’ll look at obfuscation in much greater detail in the next chapter, but for the moment, the main players in the history of obfuscation are as follows:

  • Crema
  • SourceGuard
  • DashO
  • Zelix KlassMaster

There are many others—the Java Obfuscator (JOBE), ShroudIt, JZipper, ObfuscatePro, and Mandate OneClass, to name but a few. By and large, many of the early obfuscators have simply given up the ghost and closed up shop. Crema, like Mocha, is so out of date that even if you did find a copy, you’d probably have to go back to a very early JDK to get it to work. 4thPass software, the creator of SourceGuard, has moved on from obfuscation and now operates primarily in the wireless market. DashO is still being sold by PreEmptive Solutions. In fact, they are also selling .NET versions of their products. Finally Zelix KlassMaster is notable in that it modifies the bytecode flow so that the original source code cannot be recovered from the classfile. However, this type of approach is very susceptible to the Java bytecode verifier, which can refuse to run the code and can potentially make your code much less portable.

I’ll cover all these points and more in the next chapter, which hopefully will go some way toward explaining just why Java obfuscation has not exactly been a growth market.

Conclusion

Often books show their age when they review products. It’s a form of technological carbon dating that usually makes a book out of date before it hits the presses. However, this book is different because I’m really telling a story of how different people have approached the problem of Java decompilation almost as soon as the language appeared.

If there is a point that’s worth making, it would be that you need to think outside the box because you can be sure your attackers will be using every possible way to get at your code if they really want it. Hopefully I’ve shown you the types of tools and techniques that are out there—both to protect your code and, just as importantly, to make it easier to get at your code.

_________________

1http://www.sf-soft.de/winhex/index-m.html

2http://www.javaworld.com/javaworld/jw-12-1998/jw-12-securityrules.html

3http://www.cigital.com/hostile-applets/

4http://www.ddj.com/ftp/1998/1998_01/class.txt (requires registration)

5http://www.javaworld.com/javaworld/jw-08-1997/jw-08-indepth.html

6http://mrl.nyu.edu/~meyer/jasmin/

7http://www.sourceagain.com

8http://kpdus.tripod.com/jad.html

9http://www.trinnion.com/javacodeviewer

10http://jode.sourceforge.net

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.97.202