Storyyeller / Krakatau

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

Decompilation Errors: KeyError on Constant pool index #60

Closed crashish closed 8 years ago

crashish commented 8 years ago

I'm not sure if this would be better to report to ByteCode Viewer, or how to qualify a "valid class" (I assume it is valid, the APK that contains the class seems to run fine, for whatever that's worth), but pasted below is the error I am seeing. I'm pretty new to most of these things (Android/Dalvik reversing, ByteCode Viewer, Krakatau) so please let me know what additional information would help diagnose the problem or where might be better to seek help.

processing target com/google/gson/DefaultTypeAdapters$EnumTypeAdapter, 5267 remaining
Loading com/google/gson/DefaultTypeAdapters$EnumTypeAdapter
Decompiling method <init> ()V
Decompiling method <init> (Lcom/google/gson/DefaultTypeAdapters$1;)V
Decompiling method deserialize (Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializatio
nContext;)Ljava/lang/Enum;
Traceback (most recent call last):
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\decompile.py", line 144, in <module>
    decompileClass(path, targets, args.out, args.skip)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\decompile.py", line 91, in decompileClass
    source = printer.visit(javaclass.generateAST(c, makeGraph, skip_errors, add_throws=add_throws))
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\javaclass.py", line 67, in generateAST

    method_defs = [_getMethod(m, cb, forbidden_identifiers, skip_errors) for m in methods]
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\javaclass.py", line 39, in _getMethod
    code_ast = javamethod.generateAST(method, graph, forbidden_identifiers)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\javamethod.py", line 864, in generateA
ST
    _preorder(ast_root, partial(_addCastsAndParens, env=env))
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\javamethod.py", line 138, in _preorder

    val = func(scope, item)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\javamethod.py", line 723, in _addCasts
AndParens
    item.addCastsAndParens(env)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\ast.py", line 70, in addCastsAndParens

    self.expr.addCasts(env)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\ast.py", line 341, in addCasts
    param.addCasts(env)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\ast.py", line 342, in addCasts
    self.addCasts_sub(env)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\ast.py", line 457, in addCasts_sub
    def addCasts_sub(self, env): self.fix(env)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\ast.py", line 451, in fix
    if not isJavaAssignable(env, tt, expr.dtype):
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\java\ast.py", line 277, in isJavaAssignable

    return objtypes.isSubtype(env, fromt, to)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\ssa\objtypes.py", line 55, in isSubtype
    return isBaseTClass(x) and isBaseTClass(y) and env.isSubclass(xname, yname)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\environment.py", line 29, in isSubclass
    return name1 == name2 or (name2 in self.getClass(name1).getSuperclassHierarchy())
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\environment.py", line 25, in getClass
    result.loadElements()
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\classfile.py", line 124, in loadElements
    self.methods = [method.Method(m, self, keepRaw) for m in self.methods_raw]
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\method.py", line 95, in __init__
    self.code = self._loadCode(keepRaw)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\method.py", line 111, in _loadCode
    return Code(self, bytestream, keepRaw)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\method.py", line 32, in __init__
    self.bytecode = bytecode.parseInstructions(codestream, self.isIdConstructor)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\bytecode.py", line 14, in parseInstructions

    if inst[0] == opnames.INVOKESPECIAL and isConstructor(inst[1]):
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\method.py", line 44, in isIdConstructor
    args = self.class_.cpool.getArgsCheck('Method', methId)
  File "C:\Users\user\.Bytecode-Viewer\krakatau_8\Krakatau-master\Krakatau\constant_pool.py", line 178, in getArgsChec
k
    raise KeyError('Constant pool index {} has incorrect type {}'.format(index, typen))
KeyError: 'Constant pool index 1158 has incorrect type Method'
Storyyeller commented 8 years ago

Can you upload or link the apk anywhere?

crashish commented 8 years ago

Sure, would you mind if I shared the link privately though?

Storyyeller commented 8 years ago

Ok. Also what did you use to convert it to a jar? Enjarify?

2016-02-02 14:13 GMT-08:00 Ed Miles notifications@github.com:

Sure, would you mind if I shared the link privately though?

— Reply to this email directly or view it on GitHub https://github.com/Storyyeller/Krakatau/issues/60#issuecomment-178854739 .

crashish commented 8 years ago

I'm using dex2jar, via Bytecode Viewer. I went back to try Enjarify have not been able to get it working, even with a valid Python3 path specified.

How should I send you the download?

Storyyeller commented 8 years ago

You can email it to n210241048576@gmail.com.

Please include the jar as well, since I probably won't have the exact version of dex2jar you do and won't be able to reproduce that step.

2016-02-02 19:25 GMT-08:00 Ed Miles notifications@github.com:

I'm using dex2jar, via Bytecode Viewer. I went back to try Enjarify have not been able to get it working, even with a valid Python3 path specified.

How should I send you the download?

— Reply to this email directly or view it on GitHub https://github.com/Storyyeller/Krakatau/issues/60#issuecomment-178980374 .

Storyyeller commented 8 years ago

I am unable to reproduce this. Sorry.

crashish commented 8 years ago

I've built a fresh dex2jar and downloaded the latest Krakatau code and am receiving the same error, only from a different package. I understand you were not able to reproduce the problem but might you have any suggestions for getting around this issue?

... [snip] ...
Loading android/support/v4/app/TaskStackBuilder
Decompiling method <clinit> ()V
Decompiling method <init> (Landroid/content/Context;)V
Decompiling method create (Landroid/content/Context;)Landroid/support/v4/app/TaskStackBuilder;
Decompiling method from (Landroid/content/Context;)Landroid/support/v4/app/TaskStackBuilder;
Decompiling method addNextIntent (Landroid/content/Intent;)Landroid/support/v4/app/TaskStackBuilder;
Decompiling method addParentStack (Landroid/app/Activity;)Landroid/support/v4/app/TaskStackBuilder;
Traceback (most recent call last):
... [snipsnip] ...
    raise KeyError('Constant pool index {} has incorrect type {}'.format(index, typen))
KeyError: 'Constant pool index 1158 has incorrect type Method'
crashish commented 8 years ago

It seems the conflict comes from Java 1.8 rt.jar. Switching to 1.7 seems to have resolved the constant pool error, though now I am encountering ClassNotFoundExceptions. I expect those are related to not using the right Android platform jar, however...

crashish commented 8 years ago

I've gone through a variety of the android platform jars from the SDK and none of them appear to have android/content/pm/PackageParser, which is the class Krakatau is currently bailing on. Any chance you might know how to resolve that?

Storyyeller commented 8 years ago

You are using the latest version of Krakatau, right?

I'll look into it again next weekend.

2016-02-08 17:24 GMT-08:00 Ed Miles notifications@github.com:

I've gone through a variety of the android platform jars from the SDK and none of them appear to have android/content/pm/PackageParser, which is the class Krakatau is currently bailing on. Any chance you might know how to resolve that?

— Reply to this email directly or view it on GitHub https://github.com/Storyyeller/Krakatau/issues/60#issuecomment-181658926 .

crashish commented 8 years ago

I've left Bytecode Viewer behind at this point, and am using the latest (as of 2 days ago) Krakatau and dex2jar (freshly built locally). I resolved the PackageParser dependency with an "android-base" jarfile from http://www.java2s.com/Code/JarDownload/android-base/android-base-4.1.2_r1_rc-real.jar.zip, and since then have been in a cycle of encountering a new ClassNotFoundException, finding/downloading a jar that provides the class, re-running Krakatau, rinse, and repeat. I feel like I'm missing something out on something obvious that would make this easier.

samczsun commented 8 years ago

Have you tried -skip?

crashish commented 8 years ago

Hah! No I didn't, but I did just now finish a full decompilation of the target after many rounds of the new exception/jar hunt process I mentioned above. I'll be sure to keep -skip in mind for the future though, thanks.

Storyyeller commented 8 years ago

Yeah, the dependency problem is really annoying. Unfortunately, Krakatau was written assuming sound type inference (i.e. you always know the superclasses of the types involved when merging) and at this point it would be too much work to change.

In the last update, I did make some changes to reduce the amount of dependencies required though. It no longer requires interfaces of loaded types.

2016-02-10 17:10 GMT-08:00 Ed Miles notifications@github.com:

Hah! No I didn't, but I did just now finish a full decompilation of the target after many rounds of the new exception/jar hunt process I mentioned above. I'll be sure to keep -skip in mind for the future though, thanks.

— Reply to this email directly or view it on GitHub https://github.com/Storyyeller/Krakatau/issues/60#issuecomment-182665065 .

samczsun commented 8 years ago

I just ran into the same issue. It appears the issue is that in Java 8, invokespecial is used to invoke a method of type InterfaceMethod. If you disassemble java/lang/reflect/AccessibleObject you'll see that in the method isAnnotationPresent(Ljava/lang/Class;)Z there is an instruction like so:

L2:     invokespecial [141]
.const [39] = Utf8 isAnnotationPresent 
.const [49] = Utf8 java/lang/reflect/AnnotatedElement 
.const [72] = Class [49] 
.const [85] = Utf8 (Ljava/lang/Class;)Z 
.const [108] = NameAndType [39] [85] 
.const [141] = InterfaceMethod [72] [108] 
Storyyeller commented 8 years ago

Ah that makes sense. The decompiler hasn't been updated to support Java 8.

2016-02-11 13:23 GMT-08:00 Sam Sun notifications@github.com:

I just ran into the same issue. It appears the issue is that in Java 8, invokespecial is used to invoke a method of type InterfaceMethod. If you disassemble java/lang/reflect/AccessibleObject you'll see that in the method isAnnotationPresent(Ljava/lang/Class;)Z there is an instruction like so:

L2: invokespecial [141]

.const [39] = Utf8 isAnnotationPresent .const [49] = Utf8 java/lang/reflect/AnnotatedElement .const [72] = Class [49] .const [85] = Utf8 (Ljava/lang/Class;)Z .const [108] = NameAndType [39] [85] .const [141] = InterfaceMethod [72] [108]

— Reply to this email directly or view it on GitHub https://github.com/Storyyeller/Krakatau/issues/60#issuecomment-183064670 .

Storyyeller commented 8 years ago

This should be fixed now.