Jun 06

Code to Create a JD-GUI Error

When evaluating Android applications, I often use dex2jar to take an Android APK file and convert it to a Java JAR file.  With the APK-turned-JAR file I can examine the decompiled Java source for the application using JD-GUI or Mike Strobel’s Procyon.

Procyon is the far superior Java decompilation tool, which gracefully handles many conditions that JD-GUI cannot.  Still, Procyon requires a few additional steps to use as a command-line tool, while Procyon has a nice GUI interface for quick and easy analysis (to be fair, Procyon does have a third-party GUI interface as well, though it lacks some of the features in JD-GUI).

As part of an exercise I am writing for my SANS Institute SEC575: Mobile Device Security and Ethical Hacking course, I needed to force the student’s hand and require them to use Procyon.  I needed to reproduce a situation where my sample code was not decompiled by JD-GUI properly.  I lowered my standards enough to look at page 2 of Google search results, but I still could not find an example of Java code that could not be decompiled by JD-GUI.

Looking through some APK files I had handy, I spotted an method that JD-GUI could not handle.  Reversing the same code with Procyon gave me the method source, which I was able to narrow down to just a few lines of Java.  If you are in the position where you want to stop someone from using JD-GUI to reverse-engineer a method, insert this code:

// Add these lines to your import section
import java.io.IOException;
import java.io.OutputStreamWriter;

// Add this code to a method that you want JD-GUI to generate an error on
OutputStreamWriter request = new OutputStreamWriter(System.out);
try {
	request.close();
} catch (IOException e) {
}
finally {
	request = null;
}

The block of code opens the System.out object (the stdout reference), and then closes it. The rest is just being graceful. When decompiled with JD-GUI, the user will see this error:

JD-GUI Error

Error produced by JD-GUI when decompiling the shown code.

So, the next time you need to stop people from reversing your code, add these lines to a method, and hope that they don’t know about Procyon.

-Josh

Jul 03

Cowpatty 4.6 (with less teh suck)

As it turns out, there was a pretty significant bug in cowpatty 4.5 and earlier when built on systems with a more modern version of OpenSSL than what I was testing against:

        typedef struct {
            unsigned char k_ipad[65];
            unsigned char k_opad[65];
            unsigned char k_ipad_set;
            unsigned char k_opad_set;
        } SHA1_CACHE;

        struct SHA1_CACHE cached;
        SHA1_CTX context;

        /* ... */

        if (usecached) {
            /* Cache the context value */
            memcpy(&cached.k_ipad, &context, sizeof(context));
            cached.k_ipad_set = 1;
        }

When I looked at this I realized what the problem was right away: I was stupid when I wrote this code.

One of the ways we can accelerate WPA2-PSK cracking is to cache values that are computed each time during SHA1 rounds; namely the inner and outer pad hashes (ipad, opad). I implemented this in cowpatty and created a data structure SHA1_CACHE to store the hashed value with a field to indicate if it was currently cached or not.

At the time, OpenSSL’s SHA1_CACHE structure was 64 bytes; I created my structure members at 65 bytes (why not 64 bytes? Because I was stupid when I wrote this code). Perfect!

All worked well until I recently discovered that the SHA1_CTX structure is now 96 bytes, which did not fit so well in my 65 byte data structure.

The lesson here: don’t try to recreate the wheel. This is how I fixed the problem, and how I should have done it back in 2005:

        typedef struct {
            SHA1_CTX k_ipad;
            SHA1_CTX k_opad;
            unsigned char k_ipad_set;
            unsigned char k_opad_set;
        } SHA1_CACHE;

Instead of relying on a static byte length that once characterized the size of SHA1_CTX, I should have just used the real thing. I’ll remember this lesson in the future, and hopefully you won’t make the same mistake I did.

You can snag the latest version of cowpatty here. Special thanks to Kevin Kestinggolrer, Philipp Schroedel, Max Moser and Nathan Grennan, Jason Franks and Michal Knobel for hitting me with their various clue-sticks.

-Josh