Storyyeller / Krakatau

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

ClassNotFoundException on checkcast opcode #94

Closed skochinsky closed 8 years ago

skochinsky commented 8 years ago

The error was generated during decompilation of the Intel ME internal classes. I managed to minimize it to this: https://gist.github.com/skochinsky/7da0d41706f2abcf0e2c5a7b283309dc It can likely be minimized further but I'm not very familiar with Java so I'll leave it to you. The following patch seems to fix it but not sure if that's the best approach:

--- a/Krakatau/verifier/inference_verifier.py
+++ b/Krakatau/verifier/inference_verifier.py
@@ -105,7 +105,7 @@ def _indexToCFMInfo(cpool, ind, typen):
     assert actual == typen or actual == 'InterfaceMethod' and typen == 'Method'

     cname = cpool.getArgs(ind)[0]
-    if cname[0] in ('[','L'):
+    if cname.startswith('['):
         try:
             return parseFieldDescriptor(cname)[0]
         except ValueError as e:
skochinsky commented 8 years ago

For the record, here's the traceback:

Loading Lcom/intel/crypto/CertificateStoreImpl;
Traceback (most recent call last):
  File "E:\work\git\Krakatau\decompile.py", line 155, in <module>
    decompileClass(path, targets, args.out, args.skip, magic_throw=args.xmagicthrow)
  File "E:\work\git\Krakatau\decompile.py", line 100, in decompileClass
    source = printer.visit(javaclass.generateAST(c, makeGraphCB, skip_errors, add_throws=add_throws))
  File "E:\work\git\Krakatau\Krakatau\java\javaclass.py", line 67, in generateAST
    method_defs = [_getMethod(m, cb, forbidden_identifiers, skip_errors) for m in methods]
  File "E:\work\git\Krakatau\Krakatau\java\javaclass.py", line 37, in _getMethod
    graph = cb(method) if method.code is not None else None
  File "E:\work\git\Krakatau\decompile.py", line 45, in makeGraph
    v = verifyBytecode(m.code)
  File "E:\work\git\Krakatau\Krakatau\verifier\inference_verifier.py", line 477, in verifyBytecode
    iNodes = [InstructionNode(code, offset_rmap, offsets, key) for key in offsets[:-1]]
  File "E:\work\git\Krakatau\Krakatau\verifier\inference_verifier.py", line 299, in __init__
    self._precomputeValues()
  File "E:\work\git\Krakatau\Krakatau\verifier\inference_verifier.py", line 318, in _precomputeValues
    result = self._removeInterface(result)
  File "E:\work\git\Krakatau\Krakatau\verifier\inference_verifier.py", line 302, in _removeInterface
    if vt.tag == '.obj' and vt.extra is not None and self.env.isInterface(vt.extra, forceCheck=True):
  File "E:\work\git\Krakatau\Krakatau\environment.py", line 56, in isInterface
    raise e
Krakatau.error.ClassLoaderError:
ClassNotFoundException: Lcom/intel/crypto/CertificateStoreImpl;
Storyyeller commented 8 years ago

That means that you didn't put the required libraries in path. You need to tell Krakatau about the location of every class referenced in the jar you are trying to decompile. Yes, I know it's annoying, but there's not much that can be done about it now.

skochinsky commented 8 years ago

The target class is defined in the same source file and so is present in the same jar. The issue is that the decompiler is looking for "Lcom/intel/crypto/CertificateStoreImpl;.class" and not "com/intel/crypto/CertificateStoreImpl.class"

Storyyeller commented 8 years ago

Oh ok, I'll look into it later.

P.S. Did you make sure the code actually runs?

Storyyeller commented 8 years ago

I do not see com/intel/crypto/CertificateStoreImpl defined in https://gist.github.com/skochinsky/7da0d41706f2abcf0e2c5a7b283309dc

skochinsky commented 8 years ago

Sorry about that! I was copying classes one by one until I could reproduce the error. I updated the gist, now it decompiles (with the patch).

Storyyeller commented 8 years ago

Does the code actually run? I want to make sure that the JVM actually accepts checkcast with explicit class descriptors before I go to the trouble of updating Krakatau.

skochinsky commented 8 years ago

Alas I can't run it since I don't have code execution in the ME yet ;) But I suspect something similar can be cooked up by someone who knows Java.

Storyyeller commented 8 years ago

Should be fixed now. Thanks for the report!