Storyyeller / Krakatau

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

Crash while disassembling semi-invalid class file #110

Closed samczsun closed 7 years ago

samczsun commented 7 years ago

By modding my copy of Krakatau, I was able to assemble this:

.version 52 0 
.class public super Test 
.super java/lang/Object 

.method public static main : ([Ljava/lang/String;)V 
    .code stack 10 locals 10 
L0:     getstatic Field java/lang/System out Ljava/io/PrintStream; 
L3:     ldc 'Nothing to see here' 
L5:     invokevirtual Method java/io/PrintStream println (Ljava/lang/String;)V 
L8:     return 
L9:     
    .end code 
.end method 
.code stack 1 locals 10 
L0: test 
L1: 
.end code 
.end class 

Java executes this file (even under -Xverify:all!), but Krakatau has a hard time disassembling it:

Krakatau  Copyright (C) 2012-16  Robert Grosse
This program is provided as open source under the GNU General Public License.
See LICENSE.TXT for more details.

processing target C:\Users\Sam\AppData\Local\Temp\krakatau-disassemble-1458670628942597591\input.zip, 1/1 remaining
---- STDERR ----
Traceback (most recent call last):
  File "disassemble.py", line 70, in <module>
    disassembleSub(readFile, out, targets, roundtrip=args.roundtrip, outputClassName=False)
  File "disassemble.py", line 39, in disassembleSub
    Disassembler(clsdata, output.write, roundtrip=roundtrip).disassemble()
  File "assembler\disassembly.py", line 327, in disassemble
    a.attribute(attr)
  File "assembler\disassembly.py", line 549, in attribute
    a.code(r)
  File "assembler\disassembly.py", line 408, in code
    a.instruction(bcreader)
  File "assembler\disassembly.py", line 470, in instruction
    op = OPNAMES[r.u8()]
IndexError: tuple index out of range

The class file has been attached (renamed to .txt)

Test.txt

Storyyeller commented 7 years ago

It looks like the issue is that you are using a reserved opcode, which violates the JVM specification.

Only instances of the instructions documented in 
§6.5
 may appear in the 
code
array. Instances of instructions using the reserved opcodes (
§6.2
) or any opcodes
not documented in this specification must not appear in the 
code
 array.

Sadly, the JVM doesn't appear to enforce this. Any ideas what I should do?

Storyyeller commented 7 years ago

Oh, I see what you did - you put a Code attribute on the class. I'm surprised that passes verification, but at least it's a separate issue.

Storyyeller commented 7 years ago

As a quick workaround, I modified it to ignore Code attributes that aren't inside a method. But this obviously doesn't solve the underlying issue. I think it will take some time to investigate which attributes are actually allowed where.