Coder Social home page Coder Social logo

krakatau's People

Contributors

storyyeller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

krakatau's Issues

DuplicateImport.java assertion error

This test: http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/tip/test/tools/javac/DuplicateImport.java

compiled with default settings on the JDK 1.7.0_21 javac,

Causes an assertion error in Krakatau:

% javac DuplicateImport.java                                                                                
% jar cf lol2.jar DuplicateImport.class                                                                               
% python /var/www/temp/Krakatau/decompile.py -path /usr/lib/jvm/java-7-oracle/jre/lib/rt.jar -out krakatau222 lol2.jar
Krakatau  Copyright (C) 2012-13  Robert Grosse
This program is provided as open source under the GNU General Public License. 
See LICENSE.TXT for more details.

Attempting to automatically locate the standard library...
Unable to find the standard library
processing target DuplicateImport, 1 remaining
Loading DuplicateImport
Traceback (most recent call last):
  File "/var/www/temp/Krakatau/decompile.py", line 126, in <module>
    decompileClass(path, targets, args.out)
  File "/var/www/temp/Krakatau/decompile.py", line 79, in decompileClass
    c = e.getClass(target)
  File "/var/www/temp/Krakatau/Krakatau/environment.py", line 25, in getClass
    result = self._loadClass(name, subclasses)
  File "/var/www/temp/Krakatau/Krakatau/environment.py", line 63, in _loadClass
    new.loadSupers(self, name, subclasses)
  File "/var/www/temp/Krakatau/Krakatau/classfile.py", line 94, in loadSupers
    assert(self.name == name)
AssertionError

Var UNREACHABLE

This code, compiled with javac 1.7.0_21:

// This software is subject to the terms of the IBM Jikes Test Suite
// License Agreement available at the following URL:
// http://www.ibm.com/research/jikes.
// Copyright (C) 1996, 1999, International Business Machines Corporation
// and others.  All Rights Reserved.
// You must accept the terms of that agreement to use this software.

interface order extends cost {
  int quantity();
}

interface cost {
  int price();
}

class Food implements cost {
  int costofitem;

  Food(int i) {
    costofitem = i + 2;
   }

  public int price() {
    return costofitem;
  }

}

class Cans implements order {
  int costofitem;
  int stock;

  Cans(int i, int j) {
    costofitem = i;
    stock = j;
   }

  public int price() {
    return costofitem;
  }

  public int quantity() {
    return stock;
  }

}

class megadeth {

   public static void main (String aa[]) {
     cost costarray[], costcans[];
     int result, ok;
     costarray = new cost[5];
     costcans = new cost[5];
     for (int i=0; i< 5; i++) {
       costarray[i] = new Food(i);
       costcans[i] = new Cans(i, i+2);
     }
     costarray[0] = new Cans(15, 3);

     result = 3; ok = 0;
     Cans canarray[];
     try {
       canarray = (Cans[])costcans;
       result = result + canarray[1].price();
     }
     catch (ClassCastException e) {
      ok = ok + 1;
     }

     canarray = new Cans[5];
     System.arraycopy(costcans, 0, canarray, 0, 5);
     if (canarray[2].price() == 2) ok = ok + 1;

     try {
      canarray = (Cans[])costarray;
      result = result + canarray[1].price();
     }
     catch (ClassCastException e) {
      ok = ok + 1;
     }

     try {
      System.arraycopy(costarray, 0, canarray, 0, 5);
      result = result + canarray[1].price();
     }
     catch (ArrayStoreException e) {
      if (canarray[0].price() == 15) 
        ok = ok + 1;
     }

     if (ok != 4) result = result + 5;
     System.out.println(result);
     System.exit(result);
   }
}

Produces following exception upon decompilation:

Loading megadeth
Decompiling method <init> ()V
Decompiling method main ([Ljava/lang/String;)V
Traceback (most recent call last):
  File "/var/www/temp/Krakatau/decompile.py", line 126, in <module>
    decompileClass(path, targets, args.out)
  File "/var/www/temp/Krakatau/decompile.py", line 82, in decompileClass
    source = deco.generateSource()
  File "/var/www/temp/Krakatau/Krakatau/java/javaclass.py", line 76, in generateSource
    method_defs = map(self._getMethod, self.methods)
  File "/var/www/temp/Krakatau/Krakatau/java/javaclass.py", line 54, in _getMethod
    code_ast = MethodDecompiler(method, graph, self.forbidden_identifiers).generateAST()
  File "/var/www/temp/Krakatau/Krakatau/java/javamethod.py", line 505, in generateAST
    ast_root, varinfo = astgen.createAST(method, self.graph, setree, self.namegen)
  File "/var/www/temp/Krakatau/Krakatau/java/astgen.py", line 345, in createAST
    astroot = _createASTSub(info, seroot)
  File "/var/www/temp/Krakatau/Krakatau/java/astgen.py", line 295, in _createASTSub
    new = _createASTBlock(info, current.node, gotoMap)
  File "/var/www/temp/Krakatau/Krakatau/java/astgen.py", line 189, in _createASTBlock
    expr = ast.Assignment(info.var(n2, inv), info.var(node, outv))
  File "/var/www/temp/Krakatau/Krakatau/java/astgen.py", line 64, in var
    self._vars[var, node.num] = new = self._newVar(var, node.num)
  File "/var/www/temp/Krakatau/Krakatau/java/astgen.py", line 46, in _newVar
    tt = self._tts[var]
KeyError: Var UNREACHABLE

Gracefully handle ClassNotFound errors

From Justin Turner, via email:

I was wondering if it is possible to have the decompiler skip files that it can not find instead of throwing a ClassNotFoundException. Or be able to display the package/path of the Class it is trying to find so I can include it in the path.

I am trying to decompile the TcpCatcher.jar file from http://www.tcpcatcher.org/download.php but it fails and returns:

Krakatau.error.ClassLoaderError:
ClassNotFoundException: Callback

How well tested is this?

Hi, Storyyeller. I actually just have a couple of questions, not really issues, but I couldn't find any contact information here or on your Antimony account on stackoverflow from where I was linked to here. Sorry if this isn't an appropriate place to ask, but I couldn't think of anywhere else.

I am very interested in this project, as it's the only one I've found which seems to have the potential to support decompilation of arbitrary bytecode generated from languages other than Java or from obfuscators. (The obfuscation part isn't actually important to me personally, but it would be a nice display of robustness ;).) It's also nice to see a useful looking project and to not discover it's been unmaintained for a decade!

Your approach to the problem as a 'backwards compiler' sounds exactly like what I was looking for, as 'good quality' and readable Java isn't something I care about, I just need would like something which works consistently. If you are interested in the application, I'm trying to put together a toolchain for helping convert Java applications to Objective-C.

Currently https://code.google.com/p/j2objc/ exists to help convert Java source to Objective-C, but it occurred to me that Android apps can be written in something like Scala also, since Davlik bytecode is generated from Java bytecode. This means that to leverage the power of the j2objc library we need an extra decompilation step from bytecode to Objective-C to support all possibilities.

Since I've found no decompilers which look massively dependable it has started to feel like this technique might actually be a step backwards, since it adds steps which are often unnecessary and so may fail in cases where j2objc would have been successful by itself. I suppose those extra steps could be skipped in those cases where the original source is actually Java, but that would add extra complexity to an otherwise more generally applicable toolchain.

On the other hand, j2objc doesn't appear to be fully matured, and I have a feeling that code generated by Krakatau might actually be more consistently understandable by j2objc than arbitrary Java, so it could be more reliable in every case if the decompilation step is robust enough.

So, how well tested is your code? Have you tested with different obfuscaters or with bytecode compiled from different languages etc? I will be happy to perform a whole bunch of tests myself, of course, I'm only asking you this here in case you can give me a good idea from what you have done already :).

Sorry for the long message, I ended up with more to say than I thought I did. Please feel free to delete this issue and reply by email to eliasv at hotmail.co.uk if that would be better.

Thanks for your help.

Can't do assignments before calling "this" or "super"

Original code:

class Test {
    Test() {
        this(new Object());
    }
    Test(Object i) {
    }
}

Decompiled:

class Test {
    Test()
    {
        Object a = new Object();
        this(a);
    }

    Test(Object a)
    {
        super();
    }
}

Trying to compile:

 % javac Test.java 
Test.java:5: error: call to this must be first statement in constructor
        this(a);
            ^
1 error

Register Contains Wrong Type

I don't believe this is a bug w/ Krakatau however I don't know who else to ask. I am modifying another class and putting in an extra private method. However whenever I run the program I am getting an error w/ the method saying one of the registers contains the wrong type.

http://pastebin.com/W7xjaNmS New Method Code

This is the portion of the error that should be useful

cpw.mods.fml.common.LoaderException: java.lang.VerifyError: (class: dan200/turtle/shared/BlockTurtle, method: setOwner signature: (Lyc;IIILjava/lang/String;)V) Register 5 contains wrong type

Force use shortnames

Is there a switch I can use to force the use of shortnames instead of fully qualified names when referring to non-object references? For example, I want View v instead of android.view.View v

AssertionError during decompilation

Here is the error seen during decompilation:

//Traceback (most recent call last):
//  File "c:\Python27\Krakatau\Krakatau\java\javaclass.py", line 37, in _getMethod
//    graph = cb(method) if method.code is not None else None
//  File "Krakatau\decompile.py", line 37, in makeGraph
//    s = Krakatau.ssa.ssaFromVerified(m.code, v)
//  File "c:\Python27\Krakatau\Krakatau\ssa\graph.py", line 513, in ssaFromVerified
//    data = blockmaker.BlockMaker(parent, iNodes, inputTypes, returnTypes, code.except_raw)
//  File "c:\Python27\Krakatau\Krakatau\ssa\blockmaker.py", line 545, in __init__
//    curslots = self.appendInstrToBlock(block, node, curslots, newarray_info) #arrinfo modified in place
//  File "c:\Python27\Krakatau\Krakatau\ssa\blockmaker.py", line 606, in appendInstrToBlock
//    assert(len(inslots.stack) == len(iNode.stack) and len(inslots.locals) == len(iNode.locals))
//AssertionError 

class file: https://www.sendspace.com/file/kuitnc

Exception handlers do not form forest

I often encounter this error afterwhich, the decompile process is halted and remaining classes not decompiled. Anyone knows how to fix or ignore problematic class?

Traceback (most recent call last):
File "decompile.py", line 130, in
decompileClass(path, targets, args.out, args.dis)
File "decompile.py", line 64, in decompileClass
source = deco.generateSource()
File "C:\Krakatau\Krakatau\java\javaclass.py", line 71, in generateSource
method_defs = map(self._getMethod, self.methods)
File "C:\Krakatau\Krakatau\java\javaclass.py", line 49, in _getMethod
code_ast = MethodDecompiler(method, graph).generateAST()
File "C:\Krakatau\Krakatau\java\javamethod.py", line 731, in generateAST
blocks, entryBlock, handlerInfos = preprocess.structureCFG(blocks, blocks[0])
File "C:\Krakatau\Krakatau\java\preprocess.py", line 481, in structureCFG
handlerInfos = fixTryBlocks(blocks, root)
File "C:\Krakatau\Krakatau\java\preprocess.py", line 448, in fixTryBlocks
error('Exception handlers do not form forest')
File "C:\Krakatau\Krakatau\java\preprocess.py", line 15, in error
raise DecompilationError(msg)
Krakatau.java.preprocess.DecompilationError: Exception handlers do not form forest

Add Debug Output

Would it be possible to add a debug output that shows us anything in the Constant Pool that is unused?

How to decompile single class file?

breezewish:lib breeswish$ python Krakatau/decompile.py ~/hello.class
Krakatau  Copyright (C) 2012-14  Robert Grosse
This program is provided as open source under the GNU General Public License.
See LICENSE.TXT for more details.

Attempting to automatically locate the standard library...
Found at  /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/rt.jar
processing target /Users/breeswish/hello, 1 remaining
Loading /Users/breeswish/hello
Traceback (most recent call last):
  File "Krakatau/decompile.py", line 147, in <module>
    decompileClass(path, targets, args.out, plugins, args.skip)
  File "Krakatau/decompile.py", line 88, in decompileClass
    c = e.getClass(target)
  File "/Users/breeswish/Development/java-decompiler-combination/lib/Krakatau/Krakatau/environment.py", line 26, in getClass
    result = self._loadClass(name, subclasses)
  File "/Users/breeswish/Development/java-decompiler-combination/lib/Krakatau/Krakatau/environment.py", line 60, in _loadClass
    raise ClassLoaderError('ClassNotFoundException', name)
Krakatau.error.ClassLoaderError: 
ClassNotFoundException: /Users/breeswish/hello

Jython compatibility

Hi,

I've successfully used this project with Jython 2.7b1 (you may see results in my github project).

I applied this patch - https://gist.github.com/alexkasko/6781413 , besides jython compatibility changes (packages naming and struct creation in assembler.py) it also changes some \n to in generated source code (these changes are, of course, optional).

Thanks for the great tools!

Syntax error

Hi when I ran the decompiler python script I found this error,
Traceback (most recent call last):
File "decompile.py", line 5, in
import Krakatau.ssa
File "/cygdrive/c/Users/Tanzir/Documents/My Dropbox/PhD/phd_data/tools/Krakata
u/Krakatau/ssa/init.py", line 1, in
from graph import ssaFromVerified
File "/cygdrive/c/Users/Tanzir/Documents/My Dropbox/PhD/phd_data/tools/Krakata
u/Krakatau/ssa/graph.py", line 349
tempmap = {b:b for b in new.getSuccessors()}
^
SyntaxError: invalid syntax

what is the problem here?

Test failed: BadInnerTest

Hello.

I've just checked out master and ran ./runtests.py (after adding #!/usr/bin/python to the top and setting my JAVA_HOME).

Here is a full log of my results:
https://gist.github.com/daveloyall/9919922#file-output-txt-L86

As you can see, BadInnerTest failed.

Doing test BadInnerTest...
Generating BadInnerTest.test
processing target BadInnerTest, 1 remaining
Loading BadInnerTest
Decompiling method main ([Ljava/lang/String;)V
Class written to /tmp/BadInnerTest/BadInnerTest.java
0.164745807648 seconds elapsed
Attempting to compile
Executing BadInnerTest w/ args []
Failed test BadInnerTest w/ args []:
expected stdout: ''
actual stdout : 'Bad inners, bad inners, whatcha gonna do?\n'
expected stderr: 'Exception in thread "main" java.lang.ClassFormatError: Truncated class file\n\tat java.lang.ClassLoader.defineClass1(Native Method)\n\tat java.lang.ClassLoader.defineClass(ClassLoader.java:800)\n\tat java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)\n\tat java.net.URLClassLoader.defineClass(URLClassLoader.java:449)\n\tat java.net.URLClassLoader.access$100(URLClassLoader.java:71)\n\tat java.net.URLClassLoader$1.run(URLClassLoader.java:361)\n\tat java.net.URLClassLoader$1.run(URLClassLoader.java:355)\n\tat java.security.AccessController.doPrivileged(Native Method)\n\tat java.net.URLClassLoader.findClass(URLClassLoader.java:354)\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:425)\n\tat sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:358)\n\tat sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)\n'
actual stderr : ''

I don't know what this means and I'm not even sure it isn't an expected failure.

Here is a short description of my environment:

hobbes@metalbaby:~/src-e2/Krakatau$ uname -a
Linux metalbaby 3.11-2-amd64 #1 SMP Debian 3.11.10-1 (2013-12-04) x86_64 GNU/Linux
hobbes@metalbaby:~/src-e2/Krakatau$ java -version
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.5) (7u51-2.4.5-2)
OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)

I hope this helps. Please let me know if you'd like additional information or want me to try changing anything and running the tests again. Cheers!

FYI, i made some minor modifications to improve the compilablility of decompiled java source.

hi, I should say you have created a masterpiece! I learned a lot from your wonderful open source code. this is the most powerful decompiler I ever met. the outputted code is logically correct in most cases and is compilable after doing some manual modification(major issues are caused by embedded classes).

I made following minor modifications in ast.py to improve the compilability of decompiled java source. the first one will make the code ugly, but it works. and the second one related to embedded class.

class Cast(JavaExpression):
def init(self, *params):
self.dtype = params[0].tt
self.params = params
self.fmt = '(({}){})' <<---------this one

class TypeName(JavaExpression):
def init(self, tt):
self.dtype = None
self.tt = tt
name, dim = tt
if name[0] == '.': #primative type:
name = name[1:]
else:
name = name.replace('/','.')
name = name.replace('$','.') <<----------this one
s = name + '[]'*dim

"abstract interface ... implements" not valid

Original source:

interface T1 { 
}
interface T2 extends T1 {
}

Decompiled:

abstract interface T1 {
}
abstract interface T2 implements T1 {
}

Trying to compile:

% javac T?.java                        
T2.java:1: error: '{' expected
abstract interface T2 implements T1 {
                     ^
1 error

Load external libs

Hello,

Is it possible to load external libs with the "-path" option ? I tried like this :

python Krakatau-master/decompile.py -path /usr/lib/jvm/java-1.6.0-openjdk/jre/lib/rt.jar lib/*.jar -out decompiled/ file.jar

But it doesn't work, I get the error "unrecognized arguments".

Thank you,
Kevin

dex support

It would be really nice if Krakatau supported dex bytecode. Thanks.

Duplicate methods

Sometimes your decompiler produce the same method multiple times. This happens if a class A inherits from B (directly or indirectly) and overwrites the method f but the return-type of f in A is more specific as in B.

I'm not sure if that's always happens but I have several occurrences.

For example your decompiler produce something like that:

public class SpecialACreator implements ACreator
{
    public SpecialA createA()
    {
        return new SpecialA();
    }

    public A createA()
    {
        return (A)(Object)this.createA();
    }
}

The solution would be to write only the first function (with more specific return-type or from more specific class) to the sources.

Trying to get .java from .class file but stuck with decompilarion error

$ python decompile.py hello.class
Krakatau Copyright (C) 2012-14 Robert Grosse
This program is provided as open source under the GNU General Public License.
See LICENSE.TXT for more details.

Attempting to automatically locate the standard library...
Found at /usr/lib/jvm/java-1.7.0-openjdk-i386/jre/lib/rt.jar
processing target hello, 1 remaining
Loading hello
Traceback (most recent call last):
File "decompile.py", line 139, in
decompileClass(path, targets, args.out, args.skip)
File "decompile.py", line 85, in decompileClass
c = e.getClass(target)
File "/home/praveend/javadecompilers/Krakatau/Krakatau/environment.py", line 23, in getClass
result = self._loadClass(name, subclasses)
File "/home/praveend/javadecompilers/Krakatau/Krakatau/environment.py", line 67, in _loadClass
raise ClassLoaderError('ClassNotFoundException', name)
Krakatau.error.ClassLoaderError:
ClassNotFoundException: hello

decompile.py crashes with "Unable to find the standard library"

Running python decompile.py crashes with:

Attempting to automatically locate the standard library...
Unable to find the standard library
Traceback (most recent call last):
  File "/usr/src/Krakatau/decompile.py", line 133, in <module>
    if not os.path.exists(args.out):
  File "/usr/lib/python2.7/genericpath.py", line 18, in exists
    os.stat(path)
TypeError: coercing to Unicode: need string or buffer, NoneType found

Running with -nauto just produces:

Traceback (most recent call last):
  File "/usr/src/Krakatau/decompile.py", line 133, in <module>
    if not os.path.exists(args.out):
  File "/usr/lib/python2.7/genericpath.py", line 18, in exists
    os.stat(path)
TypeError: coercing to Unicode: need string or buffer, NoneType found

Issues w/ LocalVariableTable

In the latest commit when I try to disassemble something it will add .codeattribute LocalVariableTable to the end of every method however if I try to reassemble w/ this in there and run it with Java it will throw in error along the line of "Signature index 13 in LocalVariableTable has bad constant type in class file errorTest"

https://dl.dropbox.com/u/7231478/errorTest.zip
Here is the source & class of a little demo for you to try it with, I would like to also note that if I remove the code attribute it functions perfectly fine.

stuck while decompiling a dex2jar jar file

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.

"return" in static initializer

public class Test {
    static {
        int i = 0;
        while (true) {
            if (i++ == 2) break;
            else System.out.println("lol");
        }
    }
}

compiled with javac (JDK 7), and then decompiled:

public class Test {
    public Test()
    {
        super();
    }

    static
    {
        int i = 0;
        while(true)
        {
            int i0 = i + 1;
            if(i != 2)
            {
                java.io.PrintStream a = System.out;
                a.println("lol");
                i = i0;
            }
            else
            {
                return;
            }
        }
    }
}

"return" should have been "break"

decompiler: unconditional dependency on IllegalMonitorStateException

I'm trying to decompile the Management Engine's internal Java classes, and it does not implement (nor uses) the IllegalMonitorStateException class. The following stack trace appears when decompiling almost any class:

Traceback (most recent call last):
  File "Krakatau\decompile.py", line 153, in <module>
    decompileClass(path, targets, args.out, args.skip)
  File "Krakatau\decompile.py", line 99, in decompileClass
    source = printer.visit(javaclass.generateAST(c, makeGraph, skip_errors, add_throws=add_throws))
  File "Krakatau\Krakatau\java\javaclass.py", line 67, in generateAST
    method_defs = [_getMethod(m, cb, forbidden_identifiers, skip_errors) for m in methods]
  File "Krakatau\Krakatau\java\javaclass.py", line 37, in _getMethod
    graph = cb(method) if method.code is not None else None
  File "Krakatau\decompile.py", line 60, in makeGraph
    s.abstractInterpert()
  File "Krakatau\Krakatau\ssa\graph.py", line 296, in abstractInterpert
    out = constraints.meet(*inputs)
  File "Krakatau\Krakatau\ssa\constraints\__init__.py", line 22, in meet
    return cons[0].meet(*cons[1:])
  File "Krakatau\Krakatau\ssa\constraints\obj_c.py", line 116, in meet
    types = TypeConstraint.meet(*(c.types for c in cons))
  File "Krakatau\Krakatau\ssa\constraints\obj_c.py", line 79, in meet
    return TypeConstraint.reduce(cons[0].env, supers, exact)
  File "Krakatau\Krakatau\ssa\constraints\obj_c.py", line 45, in reduce
    newexact = [x for x in exact if not isAnySubtype(env, x, newsupers)]
  File "Krakatau\Krakatau\ssa\constraints\obj_c.py", line 10, in isAnySubtype
    return any(objtypes.isSubtype(env,x,y) for y in seq)
  File "Krakatau\Krakatau\ssa\constraints\obj_c.py", line 10, in <genexpr>
    return any(objtypes.isSubtype(env,x,y) for y in seq)
  File "Krakatau\Krakatau\ssa\objtypes.py", line 55, in isSubtype
    return isBaseTClass(x) and isBaseTClass(y) and env.isSubclass(xname, yname)
  File "Krakatau\Krakatau\environment.py", line 29, in isSubclass
    return name1 == name2 or (name2 in self.getClass(name1).getSuperclassHierarchy())
  File "Krakatau\Krakatau\environment.py", line 23, in getClass
    result = self._loadClass(name, subclasses)
  File "Krakatau\Krakatau\environment.py", line 67, in _loadClass
    raise ClassLoaderError('ClassNotFoundException', name)
Krakatau.error.ClassLoaderError: 
ClassNotFoundException: java/lang/IllegalMonitorStateException

For now I've resorted to putting IllegalMonitorStateException.class from Java into the jar but it would be nice to have the decompiler handle its absence gracefully.

Licensing

Hello,

My project (Helios) is ready for release but I need to work out licensing issues first. I would like to license under Apache 2.0 and nearly all of my dependencies are Apache 2.0-compatible (including Enjarify). However, Krakatau is not.

Will you consider relicensing Krakatau under the Apache 2.0 license? Alternatively, if you could grant me an exception to include Krakatau with Helios that would also work.

Regards.

Classes with identical simple names not distinguished

Original source:

class Integer {
    Integer(boolean a) {
    }
}

class Test {
    Integer fortytwo = new Integer(false);
    java.lang.Integer fortythree = 43;
}

Test setup:

% tree
.
├── decompiled
└── Test.java

1 directory, 1 file
% javac Test.java                                                                              
% jar cf Test.jar *.class                                                                            
% cd decompiled 
% python /var/www/temp/Krakatau/decompile.py -path /usr/lib/jvm/java-7-oracle/jre/lib/rt.jar ../Test.jar
[...]
Class written to /home/janus/Skrivebord/test/decompiled/Integer.java
[...]
Class written to /home/janus/Skrivebord/test/decompiled/Test.java

Decompiled source:

class Test {
    Integer fortytwo;
    Integer fortythree;

    Test()
    {
        super();
        Integer a = new Integer(false);
        this.fortytwo = a;
        Integer a0 = Integer.valueOf(43);
        this.fortythree = a0;
    }
}

and

class Integer {
    Integer(boolean b)
    {
        super();
    }
}

Expected: Distinguished class names in Test.java.

Comment: This may look contrived, but to encounter a real world issue, simply swap "Integer" with "Polygon", make your own Polygon class and use AWT (it has a polygon too).

Krakatau crashes with Non-ascii path

[sashok724@sashok724-pc Krakatau]$ python2 disassemble.py Launcher.class
Krakatau  Copyright (C) 2012-14  Robert Grosse
This program is provided as open source under the GNU General Public License.
See LICENSE.TXT for more details.

processing target Launcher.class, 1/1 remaining
Traceback (most recent call last):
  File "disassemble.py", line 60, in <module>
    disassembleClass(readTarget, targets, args.out)
  File "disassemble.py", line 30, in disassembleClass
    filename = writeout(class_.name, source)
  File "/home/sashok724/Загрузки/Krakatau/Krakatau/script_util.py", line 96, in write
    out = makepath(cname)
  File "/home/sashok724/Загрузки/Krakatau/Krakatau/script_util.py", line 93, in <lambda>
    makepath = lambda s:os.path.join(base_path, *s.split('/')) + suffix
  File "/usr/lib/python2.7/posixpath.py", line 80, in join
    path += '/' + b
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 16: ordinal not in range(128)

Issue when disassembling

Not sure whether this is down to my own faults or what but I'm getting this when trying to disassemble a class

c:\Python33>python C:\Users\Kieran\Desktop\BYTECODE\Krakatau-master\disassemble.
py YC.j
File "C:\Users\Kieran\Desktop\BYTECODE\Krakatau-master\disassemble.py", line 2
2
print 'processing target {}, {}/{} remaining'.format(target, len(targets)-i,
len(targets))
^
SyntaxError: invalid syntax

c:\Python33>

Missing throws declaration.

Some methods throws throwables (like excaptions) or call other methods which throws throwables. This methods have to catch them or must have a "throws-declaration".

For example

public void test() {
    throw new Exception();
}

is not a valid method but the decompiler produce methods like that. I think the method should look like this:

public void test() throws Exception {
    throw new Exception();
}

Tests fail due to line ending mismatch

I'm running on a Mac, and I assume you've been developing on Windows, because your pickled test cases have \r\n line endings. This kills the test runner:

$ python Krakatau/test_decompiler.py /tmp/kkt/
Tests found: ['ArgumentTypes', 'ArrayTest', 'BadInnerTest', 'BoolizeTest', 'ControlFlow', 'DoubleEdge', 'DuplicateInit', 'floattest', 'NullInference', 'OddsAndEnds', 'OldVersionTest', 'SkipJSR', 'splitnew', 'StaticInitializer', 'Switch', 'Synchronized', 'TryCatchTest', 'UnicodeTest', 'whilesize']
Doing test ArgumentTypes
processing target ArgumentTypes, 1 remaining
Loading ArgumentTypes
Loading java/lang/Object
Decompiling method <init> ()V
Decompiling method main (Z)I
Decompiling method main (I)Z
Decompiling method main ([Ljava/lang/String;)V
Class written to /tmp/kkt/ArgumentTypes.java
0.462176084518  seconds elapsed
Attempting to compile
input ['42', 'false']
expected ('true\r\n0\r\n', '')
actual ('true\n0\n', '')
Failed!!!
... etc for the other tests ...

I see that test_decompile.py has a createTest function, but it's not called anywhere.

Functions that only differ by return type result in compilation errors

When decompiling the scala standard library to Java source files, things like this happen:

public static scala.collection.immutable.List empty()
{
    return scala.collection.immutable.List$.MODULE$.empty();
}
public static scala.collection.GenTraversable empty()
{
    return scala.collection.immutable.List$.MODULE$.empty();
}

This will not compile because the methods only differ by their return types.

From what I can tell this is supported by the bytecode because function calls contain the desired function signature, but not by the Java language.

Question: Is my interpretation of this correct?

assembler error with .const Long

I think current code is not completely ready to handle two-slot consts (long/double). See
this sample. Stack trace:

Traceback (most recent call last):
  File "Krakatau\assemble.py", line 47, in <module>
    pairs = assembleClass(log, target, args.g, args.jas, args.d)
  File "Krakatau\assemble.py", line 23, in assembleClass
    return parse_trees and [assembler.assemble(tree, makeLineNumbers, jasmode, basename) for tree in parse_trees]
  File "Krakatau\Krakatau\assembler\assembler.py", line 528, in assemble
    addLdcRefs(top_d['method'], pool)
  File "Krakatau\Krakatau\assembler\assembler.py", line 441, in addLdcRefs
    assert(not slots)
AssertionError

Syntax Error

Alright, this one I am not sure if something I did was wrong or if there is an error w/ Krakatau. I was editing the "dig" method inside of the class "TurtleTool". I had to add an extra local to be used so I switched the stack limit from 10 to 11, and switch the locals limit from 11 to 12 not sure if this was right and inserted the following right after the limits are set.

http://pastebin.com/SXrXXdPh

But when I try to assemble it I get the following error w/ Krakatau.

http://pastebin.com/DQe6KPve

Line 241 for me is the following "astore_11"

https://dl.dropbox.com/u/7231478/TurtleTool.class

assert during decompilation

I'm getting an assert(out) triggering in SSA_Graph/abstractInterpert(). The class in question is pretty short so I'll paste the assembly here:

.class super com/intel/util/PlatformIdImpl
.super com/intel/util/PlatformId


.field private m_idType I


.method  <init> : (I)V
       .limit stack 2
       .limit locals 2

;        Bytecode disassembly:
         aload_0 
         invokespecial com/intel/util/PlatformId/<init>()V
         aload_0 
         iconst_0 
         putfield PlatformIdImpl/m_idType I
         aload_0 
         iload_1 
         putfield PlatformIdImpl/m_idType I
         return 
.end method

.method public getType : ()I
       .limit stack 2
       .limit locals 1

;        Bytecode disassembly:
         iconst_0 
         aload_0 
         getfield PlatformIdImpl/m_idType I
         if_icmpne LABEL_00B1
         new com/intel/util/UtilException
         dup 
         invokespecial com/intel/util/UtilException/<init>()V
         athrow 
         LABEL_00B1:
         aload_0 
         getfield PlatformIdImpl/m_idType I
         ireturn 
.end method

.method public getValue : ()[B
       .limit stack 3
       .limit locals 2

;        Bytecode disassembly:
         iconst_0 
         aload_0 
         getfield PlatformIdImpl/m_idType I
         if_icmpne LABEL_00D3
         new com/intel/util/UtilException
         dup 
         invokespecial com/intel/util/UtilException/<init>()V
         athrow 
         LABEL_00D3:
         iconst_4 
         newarray byte
         astore_1 
         aload_0 
         getfield PlatformIdImpl/m_idType I
         aload_1 
         iconst_0 
         invokestatic com/intel/util/UtilNative/getOemId(I[BI)I
         pop 
         aload_1 
         areturn 
.end method
.end class

Any idea what's the problem and how to fix it?

prevents disassemble.py from writing out debug info

How to prevents disassemble.py from writing out debug info like:

  • L1: ...
  • .linenumbertable ... .end linenumbertable
  • .localvariabletable ... .end localvariabletable

Apktool has "--no-debug-info" option.
There is any similar option for disassemble.py?
tks

cygwin support

In order to use Krakatau within cygwin a line in script_util.ph needs to change from

    if 'win' in osname and 'darwin' not in osname:

to
if 'win' in osname and 'darwin' not in osname and 'cygwin' not in osname:

Please consider making this change. Thanks!

Lambda assembling

When i disassembled and assembled again following class:

public class Main {
private static final List ARR = Arrays.asList("1", "2", "3");

public static void main(String[] args) {
    ARR.forEach(x -> System.out.println(x));
}

}

i got an exception:

Krakatau\constant_pool.py", line 206, in bytes
t = name2Type[name]
KeyError: 'Methodtype'

and when i "iffed" that place to change key to 'MethodType' it has successfully compiled

assembler: parsing error for identifiers starting with "INF"

Simple example:
.class A
.super java/lang/Object

  .field public static final INFO_TYPE_SERIAL_NUMBER S

  .field public static final INFO_TYPE_SUBJECT S

  .field public static final INFO_TYPE_SUBJECT_ALTERNATIVE_NAME S

  .field public static final INFO_TYPE_SUBJECT_RAW S

.end class

produces:

Syntax error at line 4: unexpected token u'INF'
Expected: SYNTHETIC, OP_FIELD, OP_INT, OP_CLASS, TOP, OBJECT, OP_WIDE, OP_LOOKUPSWITCH, OP_CLASS_INT, OP_LBL, PROTECTED, STATIC, SAME, METHODTYPE, OP_NONE, SAME_EXTENDED, NULL, PARAMETER, FINAL, LOCALS, WORD, DEFAULT, INVOKEDYNAMIC, SAME_LOCALS_1_STACK_ITEM_EXTENDED, UTF8, CPINDEX, OP_METHOD_INT, PRIVATE, CHOP, TO, APPEND, INTEGER, ARRAY, STACK, FULL, STRING, OP_DYNAMIC, IS, ENUM, UNINITIALIZEDTHIS, METHOD, FIELD, OP_LDC2, OP_TABLESWITCH, OP_LDC1, METHODHANDLE, OP_METHOD, SAME_LOCALS_1_STACK_ITEM, UNINITIALIZED, FROM, STRING_LITERAL, INT, INTERFACEMETHOD, FLOAT, OP_INT_INT, OP_NEWARR, CLASS, TRANSIENT, VOLATILE, DOUBLE, USING, LONG, PUBLIC, NAMEANDTYPE
Found: DOUBLE_LITERAL
Current stack: [$end, sep, classwithends, version_opt, class_directive_lines, classdec, superdec, interfacedecs, class_directive_lines, topitems, LexToken(D_FIELD,u'.field',5,38), fflags, LexToken(FINAL,u'final',5,59)]

The following change in tokenize.py seems to fix it:

float_base = r'''(?:
    [Nn][Aa][Nn]|                                       #Nan
    [-+]?(?:                                            #Inf and normal both use sign
        [Ii][Nn][Ff]\b|                                   #Inf
        \d+\.\d*(?:[eE][+-]?\d+)?|                         #decimal float
        \d+[eE][+-]?\d+|                                   #decimal float with no fraction (exponent mandatory)
        0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+[pP][+-]?\d+        #hexidecimal float
        )
    )
'''

(added \b) in line 4

Issue with Enum

Hi,

I'm getting an issue with decompiling an enum - the decompiler creates a values method that contains a name that is not dereferenced, hence it will not recompile (example below, non-dereferenced field is '[Lstatus.Status;').

public static status.Status[] values()
{
    return (status.Status[])(([Lstatus.Status;)(Object)$VALUES).clone();
}

In each case I've come across the name starts with a [.

I've traced the code and can see that the name contains the (potentially) erroneous character on returning from get_cp_raw, but I don't know how to fix it.

I have a simple test class the produces the error, but can't work out how to attach it here :o|

I'm compiling with JAVA 1.7.

Mark.

Class not found?

Hello,

I am using the last version of Krakatau, trying to decompile a jar using the following input (i'm inside the Krakatau folder):
python decompile.py com.file.jar

However it does produce the following results:

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

Attempting to automatically locate the standard library...
Unable to find the standard library
processing target android/UnusedStub, 4096 remaining
Loading android/UnusedStub
Loading java/lang/Object
Traceback (most recent call last):
File "decompile.py", line 134, in
decompileClass(path, targets, args.out, args.skip)
File "decompile.py", line 84, in decompileClass
source = javaclass.generateAST(c, makeGraph).print_()
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/java/javaclass.py", line 69, in generateAST
method_defs = [_getMethod(m, cb, forbidden_identifiers) for m in methods]
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/java/javaclass.py", line 39, in _getMethod
graph = cb(method) if method.code is not None else None
File "decompile.py", line 36, in makeGraph
v = verifyBytecode(m.code)
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/verifier/inference_verifier.py", line 852, in verifyBytecode
iNodes = [InstructionNode(code, offsets, key) for key in offsets[:-1]]
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/verifier/inference_verifier.py", line 147, in init
self._verifyOpcodeOperands()
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/verifier/inference_verifier.py", line 234, in _verifyOpcodeOperands
self._setProtected(False)
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/verifier/inference_verifier.py", line 344, in _setProtected
cls = self.env.getClass(cname)
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/environment.py", line 26, in getClass
result = self._loadClass(name, subclasses)
File "/Users/ivopereira/Downloads/Krakatau/Krakatau/environment.py", line 60, in _loadClass
raise ClassLoaderError('ClassNotFoundException', name)
Krakatau.error.ClassLoaderError:
ClassNotFoundException: java/lang/Object"

Any ideas?

Thanks.

IndexError: pop from empty list

processing target com/actionbarsherlock/internal/nineoldandroids/animation/Value
Animator$AnimationHandler, 6861 remaining
Decompiling method <init> ()V
Decompiling method <init> (Lcom/actionbarsherlock/internal/nineoldandroids/anima
tion/ValueAnimator$1;)V
Decompiling method handleMessage (Landroid/os/Message;)V
Traceback (most recent call last):
  File "Krakatau\decompile.py", line 147, in <module>
    decompileClass(path, targets, args.out, plugins, args.skip)
  File "Krakatau\decompile.py", line 89, in decompileClass
    source = javaclass.generateAST(c, makeGraph).print_()
  File "C:\Krakatau\Krakatau\java\javaclass.py", line 69, in generateAST
    method_defs = [_getMethod(m, cb, forbidden_identifiers) for m in methods]
  File "C:\Krakatau\Krakatau\java\javaclass.py", line 41, in _getMethod
    code_ast = javamethod.generateAST(method, graph, forbidden_identifiers)
  File "C:\Krakatau\Krakatau\java\javamethod.py", line 746, in generateAST
    setree = structuring.structure(entryNode, nodes, (method.name == '<clinit>')
)
  File "C:\Krakatau\Krakatau\java\structuring.py", line 1224, in structure
    croot, ctree_children = orderConstraints(dom, constraints, nodes)
  File "C:\Krakatau\Krakatau\java\structuring.py", line 475, in orderConstraints

    cnode, svals = cscope_assigns.pop() #choose candidate arbitrarily if more th
an 1
IndexError: pop from empty list

Decompiler outputs files with weird path on OSX

Hello!
Thank you for your work on this; this has been quite an interesting learning tool, and seems to handle some of those 'monitorenter' calls a bit more than other tools.

In any case, each time I use the decompile.py program, it saves my target file in a peculiar way:

$ python Krakatau/decompile.py \
  -path android-sdk-macosx/platforms/android-19/android.jar \
  -path com.package.name_dex2jar.jar \
  com.package.name.target.Class

[snip]

Class written to \\?\/Users/morgon/Downloads\com\package\name\target\Class.java

Note the initial escaped slashes, and the change in slashes.
Running this from my 'Downloads' folder, it has created this literal structure:

$ tree \\\\\?\\/
\\\\?\\/
└── Users
    └── morgon
        └── Downloads\\com\\package\\name\\target\\Class.java

This is coming from a fresh clone of the code (02cd99c).

Using the -out flag just replaces 'Downloads' in the filename to whatever string I provide, regardless of whether it's an existing directory.

It's not a huge issue, but it does make viewing the results a bit unwieldy.
Thanks again!

Add Support For RuntimeVisibleAnnotations Attributes

I love this tool that you made and works much better then having to use JBE to edit Java Bytecode to make modifications w/o a recompile. The only issue I have is that some of the things I have to modify use Runtime Annotations either w/ @OverRide or custom interfaces.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.