Skip to content

Disassembling classfiles

Vladimir Masarik edited this page Jan 25, 2020 · 8 revisions

Setting up soot

First you have to get your soot installation running. An explanation can be found here.

The possibilities of soot

Soot has two fundamental uses; it can be used as a stand-alone command line tool or as a Java compiler framework. As a command line tool, Soot can:

  • disassemble classfiles
  • assemble classfiles
  • optimize classfiles

As a Java compiler framework, soot can be used as a testbed for developing new optimizations. These new optimizations can then be added to the base set of optimizations invoked by the command line soot tool. The optimizations that can be added can either be applied to single classfiles or entire applications.

Soot accomplishes these myriad tasks by being able to process classfiles in a variety of different forms. Currently soot accepts code from the following sources:

  • Java (bytecode and source code up to Java 7), including other languages that compile to Java bytecode, e.g. Scala
  • Android bytecode
  • Jimple intermediate representation
  • Jasmin, a low-level intermediate representation.

and outputs any of its intermediate representations. By invoking Soot with the -help option, you can see the output formats:

java soot.Main --help
...
Output Options:
-d DIR -output-dir DIR      Store output files in DIR
-f FORMAT -output-format FORMAT
                            Set output format for Soot
J jimple                    Produce .jimple Files
j jimp                      Produce .jimp (abbreviated Jimple) files
S shimple                   Produce .shimple files
s shimp                     Produce .shimp (abbreviated Shimple) files
B baf                       Produce .baf files
b                           Produce .b (abbreviated Baf) files
G grimple                   Produce .grimple files
g grimp                     Produce .grimp (abbreviated Grimp) files
X xml                       Produce .xml Files
dex                         Produce Dalvik Virtual Machine files
force-dex                   Produce Dalvik DEX files
n none                      Produce no output
jasmin                      Produce .jasmin files
c class (default)           Produce .class Files
d dava                      Produce dava-decompiled .java files
t template                  Produce .java files with Jimple templates. 
...

There are six intermediate representations currently being used in Soot: baf, jimple, shimple, grimp, jasmin, and classfiles. A brief explanation of each form follows:

  • baf a streamlined representation of bytecode. Used to inspect Java bytecode as stack code, but in a much nicer form. Has two textual representations (one abbreviated (.b files), one full (.baf files).)

  • jimple typed 3-address code. A very convenient representation for performing optimizations and inspecting bytecode. Has two textual representations (.jimp files, and .jimple files.)

  • shimple an SSA variation of jimple. Has two textual representations (.shimp files, and .shimple files.)

  • grimp aggregated (with respect to expression trees) jimple. The best intermediate representation for inspecting disassembled code. Has two textual representations (.grimp files, and .grimple files.)

  • jasmin a messy assembler format. Used mainly for debugging Soot. Jasmin files end with ".jasmin".

  • classfiles the original Java bytecode format. A binary (non-textual) representation. The usual .class files.

Generating a Jimple file

For this tutorial we examine a simple class

public class Hello
{
    public static void main(String[] args)
    {
        System.out.println("Hello world!");
    }
}

Simply compile the class (using javac or other compilers), and try the following command in the directory where Hello.class is located.

java soot.Main -cp CLASSPATH -f jimple Hello

with your CLASSPATH set correctly according to this tutorial.

Once your CLASSPATH is set up properly, you should get:

java soot.Main -f jimple Hello
Transforming Hello...

The file called Hello.jimple should contain:

public class Hello extends java.lang.Object
{
    public void <init>()
    {
        Hello r0;

        r0 := @this: Hello;
        specialinvoke r0.<java.lang.Object: void <init>()>();
        return;
    }

    public static void main(java.lang.String[])
    {
        java.lang.String[] r0;
        java.io.PrintStream $r1;

        r0 := @parameter0: java.lang.String[];
        $r1 = <java.lang.System: java.io.PrintStream out>;
        virtualinvoke $r1.<java.io.PrintStream: void println(java.lang.String)>("Hello world!");
        return;
    }
}

Generating jimple, baf, grimp for java.lang.String

By simple extrapolation, you should be able to now generate .b, .baf, .jimp, .jimple, .grimp, and .grimple files for any of your favorite classfiles. A particularly good test is a classfile from the JDK library. So a command like:

java soot.Main -f baf java.lang.String

should yield a file java.lang.String.baf containing text of the form:

public static java.lang.String valueOf(char[], int, int)
{
    word r0, i0, i1;

    r0 := @parameter0: char[];
    i0 := @parameter1: int;
    i1 := @parameter2: int;
    new java.lang.String;
    dup1.r;
    load.r r0;
    load.i i0;
    load.i i1;
    specialinvoke <java.lang.String: void <init>(char[],int,int)>;
    return.r;
}

Output of .jimple or .java files

Soot cannot only produce .class files, it can also produce .jimple and .java files and others. You can select the output format using the –f option. If you use –f dava to decompile to Java please make sure that the file <jre>/lib/jce.jar is on Soot’s classpath.

Clone this wiki locally