Storyyeller / Krakatau

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

Decompilation error: AttributeError: 'NoneType' object has no attribute 'type' #179

Closed Janmm14 closed 3 years ago

Janmm14 commented 3 years ago

Used krakatau version: latest, not the one in bytecodeviewer. But the one in bytecodeviewer throws a similar error. (slightly different lines)

class version: 55

Also tried with latest pypy2, no change.

    // Traceback (most recent call last):
    //   File "C:\Users\*\.Bytecode-Viewer\krakatau_12\Krakatau-master\Krakatau\java\javaclass.py", line 38, in _getMethod
    //     graph = cb(method) if method.code is not None else None
    //   File "C:\pypy2-v6.0.0-win32\lib_pypy\_functools.py", line 45, in __call__
    //     return self._func(*(self._args + fargs), **fkeywords)
    //   File "C:\Users\*\.Bytecode-Viewer\krakatau_12\Krakatau-master\decompile.py", line 49, in makeGraph
    //     s = Krakatau.ssa.ssaFromVerified(m.code, v, opts)
    //   File "C:\Users\*\.Bytecode-Viewer\krakatau_12\Krakatau-master\Krakatau\ssa\graph.py", line 762, in ssaFromVerified
    //     block.unaryConstraints = {var:makeConstraint(var) for var in bvars}
    //   File "C:\Users\*\.Bytecode-Viewer\krakatau_12\Krakatau-master\Krakatau\ssa\graph.py", line 762, in <dictcomp>
    //     block.unaryConstraints = {var:makeConstraint(var) for var in bvars}
    //   File "C:\Users\*\.Bytecode-Viewer\krakatau_12\Krakatau-master\Krakatau\ssa\graph.py", line 734, in makeConstraint
    //     key = var.type, var.const, var.decltype, var.uninit_orig_num is None
    // AttributeError: 'NoneType' object has no attribute 'type'
    public Boolean u() {/*error*/throw null;}

Krakatau disassembly:

.method public u : ()Ljava/lang/Boolean; 
    .code stack 8 locals 7 
L0:     ldc MethodType ()Z 
L2:     astore 6 
L4:     ldc2_w 249069195L 
L7:     l2i 
L8:     ldc 249069194 
L10:    ixor 
L11:    goto L21 

        .stack full 
            locals Object net/runelite/client/plugins/theplug/t Top Top Top Top Top Object java/lang/invoke/MethodType 
            stack 
        .end stack 
L14:    ldc2_w -2101360060L 
L17:    l2i 
L18:    ldc -2101360063 
L20:    ixor 

        .stack stack_1 Integer 
L21:    ldc2_w -1415942676L 
L24:    l2i 
L25:    ldc 1415942675 
L27:    ixor 

        .stack full 
            locals Object net/runelite/client/plugins/theplug/t Top Top Top Top Top Object java/lang/invoke/MethodType 
            stack Integer Integer 
        .end stack 
L28:    getstatic Field net/runelite/client/plugins/theplug/t 'Ꮹ' J 
L31:    ldc -293076264 
L33:    i2l 
L34:    ldc2_w -3004313391711099603L 
L37:    lxor 
L38:    goto L55 

        .stack full 
            locals Object net/runelite/client/plugins/theplug/t Top Top Top Top Top Object java/lang/invoke/MethodType 
            stack Integer Integer 
        .end stack 
L41:    ldc -1735891437 
L43:    i2l 
L44:    ldc2_w -299848505290453336L 
L47:    lxor 
L48:    ldc 1893332903 
L50:    i2l 
L51:    ldc2_w 855484530969491712L 
L54:    lxor 

        .stack full 
            locals Object net/runelite/client/plugins/theplug/t Top Top Top Top Top Object java/lang/invoke/MethodType 
            stack Integer Integer Long Long 
        .end stack 
L55:    lxor 
L56:    ldc -1601532877 
L58:    i2l 
L59:    ldc2_w -1150119973941204433L 
L62:    lxor 
L63:    lcmp 
L64:    ifne L41 
L67:    aload 6 
L69:    ifnull L78 
L72:    aconst_null 
L73:    astore 6 
L75:    goto L28 

        .stack full 
            locals Object net/runelite/client/plugins/theplug/t Top Top Top Top Top Object java/lang/invoke/MethodType 
            stack Integer Integer 
        .end stack 
L78:    if_icmple L14 
L81:    aload_0 
L82:    invokedynamic [id136] 
L87:    invokedynamic [id140] 
L92:    aload_0 
L93:    invokedynamic InvokeDynamic invokeStatic Method net/runelite/client/plugins/theplug/t llIlIIll (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : '3' (Lnet/runelite/client/plugins/theplug/t;)Lnet/runelite/client/plugins/theplug/K; 
L98:    invokedynamic InvokeDynamic invokeStatic Method net/runelite/client/plugins/theplug/t llIlIIll (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : '4' (Lnet/runelite/client/plugins/theplug/p;Lnet/runelite/client/plugins/theplug/K;)Z 
L103:   invokedynamic InvokeDynamic invokeStatic Method net/runelite/client/plugins/theplug/t llIlIIll (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : '5' (Z)Ljava/lang/Boolean; 
L108:   areturn 
L109:   
        .localvariabletable 
            0 is lllIlllIIlIlIll Lnet/runelite/client/plugins/theplug/t; from L81 to L109 
            0 is lllIlllIIlIlIlI D from L81 to L109 
        .end localvariabletable 
    .end code 
.end method 
Storyyeller commented 3 years ago

Can you please post the complete disassembly?

issue179.j:77:23: error: Undefined symbolic reference
L82:    invokedynamic [id136]
                      ^~~~~~~ 

Also, have you verified that this code is actually valid in the first place?

Janmm14 commented 3 years ago

Complete jar download at: https://github.com/java-deobfuscator/deobfuscator/issues/748 Sample taken from t.class, error happens to more methods in that class and other classes.

.const [id136] = InvokeDynamic invokeStatic Method net/runelite/client/plugins/theplug/t llIlIIll (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : '1' (Lnet/runelite/client/plugins/theplug/t;)Lnet/runelite/client/plugins/theplug/ThePlugLoaderPlugin; 
.const [id140] = InvokeDynamic invokeStatic Method net/runelite/client/plugins/theplug/t llIlIIll (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : '2' (Lnet/runelite/client/plugins/theplug/ThePlugLoaderPlugin;)Lnet/runelite/client/plugins/theplug/p; 

Complete disassembly: https://gist.github.com/Janmm14/c8d3e6cb2606fb635577e84f4aa3ad79

As the startUp method of the main class of that plugin also crashes with the same error, I expect that the given bytecode is valid, however I cannot test this myself as I don't have all the dependencies to run it. Also the <clinit> has an invokedynamic to lIIIIlIIl which fails decompilation with the same excpetion.

Storyyeller commented 3 years ago

The issue is that the classes contained MethodType constants, which are part of the invokedynamic mechanism that Krakatau does not support. As a workaroud, I changed it to generate dummy string literals for MethodHandle and MethodType constants so that at least it will still decompile.

Janmm14 commented 3 years ago

Thanks for the fast work & fix.