Storyyeller / Krakatau

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

stuck while decompiling a dex2jar jar file #22

Closed mcirsta closed 11 years ago

mcirsta commented 11 years ago

Launched krakatau with:

python Krakatau/decompile.py -out ~/temp/krak/ -path /mnt/j/proj/Krakatau/android.jar /mnt/j/proj/whatsapp/2.11.23/com.whatsapp-1_dex2jar.jar

jar files:

http://www25.zippyshare.com/v/9749448/file.html http://www25.zippyshare.com/v/73555638/file.html

It manages to decompile some stuff but then goes into a loop and just prints this:

Warning, multiple entry point loop detected. Generated code may be extremely large (2 entry points, 2 blocks) Duplicating 2 nodes

Memory usage also incrementally goes up so it seems stuck in an infinite loop somehow.

Storyyeller commented 11 years ago

It might just be a very large method. Which class is it hanging on?

Edit: Assuming you're referring to com/actionbarsherlock/widget/ActivityChooserModel$HistoryPersister.run, it looks like it's has pathological control flow pattern which cannot be concisely represented in Java. So in the process of decompiling to Java, it has to make everything much longer, which takes a while, potentially forever.

I'll look into it to see if there's anything that can be done, but there might not be. Ultimately, it's a limitation of the Java language .

mcirsta commented 11 years ago

No, just goes on and on for as long as you let it. I'm sure you can reproduce it, happens every time.

Here's more output:

processing target com/actionbarsherlock/widget/ActivityChooserModel$HistoryPersister, 2403 remaining Loading com/actionbarsherlock/widget/ActivityChooserModel$HistoryPersister Decompiling method (Lcom/actionbarsherlock/widget/ActivityChooserModel;)V Decompiling method (Lcom/actionbarsherlock/widget/ActivityChooserModel;Lcom/actionbarsherlock/widget/ActivityChooserModel$1;)V Loading org/xmlpull/v1/XmlSerializer Decompiling method run ()V Warning, multiple entry point loop detected. Generated code may be extremely large (2 entry points, 2 blocks) Duplicating 2 nodes Warning, multiple entry point loop detected. Generated code may be extremely large (2 entry points, 2 blocks)

mcirsta commented 11 years ago

I'm a programmer too and I'll bet you it's forever stuck in some sort of loop there. Now for the interesting part. I've tried with a dare jar (http://siis.cse.psu.edu/dare/ ) obtained from the same apk and the results do seem much better but it still gives an error eventually:

processing target com/actionbarsherlock/widget/ActivityChooserModel$HistoryLoader, 2233 remaining Decompiling method (Lcom/actionbarsherlock/widget/ActivityChooserModel;)V Decompiling method (Lcom/actionbarsherlock/widget/ActivityChooserModel;Lcom/actionbarsherlock/widget/ActivityChooserModel$1;)V Traceback (most recent call last): File "Krakatau/decompile.py", line 136, in decompileClass(path, targets, args.out, plugins) File "Krakatau/decompile.py", line 87, in decompileClass source = javaclass.generateAST(c, makeGraph).print_() File "/home/marius/fwgit/Krakatau/Krakatau/java/javaclass.py", line 69, in generateAST method_defs = [_getMethod(m, cb, forbidden_identifiers) for m in methods] File "/home/marius/fwgit/Krakatau/Krakatau/java/javaclass.py", line 39, in _getMethod graph = cb(method) if method.code is not None else None File "Krakatau/decompile.py", line 36, in makeGraph v = verifyBytecode(m.code) File "/home/marius/fwgit/Krakatau/Krakatau/verifier/inference_verifier.py", line 881, in verifyBytecode node.update(iNodeLookup, exceptions) File "/home/marius/fwgit/Krakatau/Krakatau/verifier/inference_verifier.py", line 783, in update newstate, swap = self._getNewState(iNodes) File "/home/marius/fwgit/Krakatau/Krakatau/verifier/inference_verifier.py", line 674, in _getNewState self._checkLocals() File "/home/marius/fwgit/Krakatau/Krakatau/verifier/inference_verifier.py", line 375, in _checkLocals self.error("Invalid local at {}, expected {}", i, t) File "/home/marius/fwgit/Krakatau/Krakatau/verifier/inference_verifier.py", line 777, in error raise error_types.VerificationError(msg) Krakatau.error.VerificationError: Invalid local at 5, expected .obj

239: load('A', 5) Stack: Locals: com/actionbarsherlock/widget/ActivityChooserModel$HistoryLoader, java/lang/String, java/lang/String, org/xmlpull/v1/XmlPullParserException, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, .none, org/xmlpull/v1/XmlPullParserException, java/lang/String, java/lang/String, java/lang/String

Also needed to add some Android maps jar to classpath. Both that and the dare jar are added below.

http://www25.zippyshare.com/v/34367401/file.html http://www25.zippyshare.com/v/28419550/file.html

It might be that dex2jar produces invalid bytecode, not sure but still Krakatau should just skip over that part of handle it better.

Storyyeller commented 11 years ago

And I'm the designer and author of that code and I bet you it's not. An exponential blowup is for all practical purposes infinite, but it's very unlikely to actually be infinite.

As for the invalid bytecode, as you able to run it in the JVM? If not, it's invalid.

Anyway, you can have it skip invalid methods by setting IGNORE_EXCEPTIONS = 1 in java/javaclass.py

mcirsta commented 11 years ago

OK, I'll take your word for it then but it doesn't look to me like it's going to ever stop... I got 3000 lines of that before I stopped it and it was only those 2 lines over and over, nothing else, no new decompiling message. Maybe it would have eventually stopped but it was enough for me to call it infinite. I can't really run the code in JVM as it's Android code. What I can do and will try it so compile it back to Dalvik and run it on Android.

mcirsta commented 11 years ago

Actually it was 6000 line but I ment I got those 2 line 3000 times.

Storyyeller commented 11 years ago

Well the worst case is exponential in the code size, so it could be infinite for all practical purposes while technically being finite.

Edit: It looks like the CFG isn't actually that bad though, so it shouldn't be doing this. I'll see if I can figure out what's wrong.

Storyyeller commented 11 years ago

It should be working now. It turns out that it was just a stupid bug after all. What confuses me though is that it never should have worked in the first place, so I'm surprised my tests didn't catch it.