Storyyeller / Krakatau

Java decompiler, assembler, and disassembler
GNU General Public License v3.0
1.95k stars 220 forks source link

JSR Confusion #65

Closed samczsun closed 8 years ago

samczsun commented 8 years ago

So if you're having a boring day and you want something to work on, here's a fun edge case to fix.

redacted

Other decompilers will decompile straight to

   public static void main(String[] var0) {
      System.out.println("Nothing to see here, Officer");
   }

However, Krakatau trips up at blockmaker.py on line 691

node = self.iNodeD[key]
KeyError: 19

The KeyError error might be an easier fix than the potential jsr confusion

Storyyeller commented 8 years ago

Should be fixed now.

As far as jsr confusion goes, Krakatau already handles this control flow correctly and always has. Unlike most decompilers, I tried to get these things right.

samczsun commented 8 years ago
.method public static main : ([Ljava/lang/String;)V 
    .code stack 10 locals 10
        jsr Ltest1
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Insert CryptoLocker code here..."
        invokevirtual java/io/PrintStream println (Ljava/lang/String;)V
        return
Ljsr2:
        iconst_0
        iconst_1
        invokestatic Method java/lang/Math min (II)I
        ifeq L1
        pop
        goto Ltest1
L1:
        swap
        astore_1
        ret 1
Ltest1:
        jsr Ljsr2
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Nothing to see here, Officer"
        invokevirtual java/io/PrintStream println (Ljava/lang/String;)V
        return
    .end code 
.end method

Thought I'd post here instead of opening a new issue (unless you prefer new issues in which case let me know).

This one causes an AssertionError at assert(block.predecessors == [(jsrblock, False)])

Storyyeller commented 8 years ago

Interesting. I think I forgot about the possibility of normal jumps to the beginning of a subprocedure when writing that code.

Ironically, most of the time spent on this was trying to figure out why I couldn't get my own test to reproduce the same behavior even after pasting in the same method code. It turns out that this only occurs when there is a local variable, which your example has due to the method parameter.

Anyway, should be fixed now.