storyyeller / krakatau Goto Github PK
View Code? Open in Web Editor NEWJava decompiler, assembler, and disassembler
License: GNU General Public License v3.0
Java decompiler, assembler, and disassembler
License: GNU General Public License v3.0
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
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
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
please follow this question
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.
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
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
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
Original source (compiled with javac from JDK 7):
class Test {
final public static boolean DEBUG = false;
}
Decompiled:
class Test {
final public static boolean DEBUG = 0;
Test()
{
super();
}
}
Doesn't compile because 0 is not a boolean.
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
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
Would it be possible to add a debug output that shows us anything in the Constant Pool that is unused?
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
Seriously this has infuriated me for hours. Help, please.
Please give me an example of how this works. Sometimes I get it works but it gives AssertionError.
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!
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?
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!
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
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
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
It would be really nice if Krakatau supported dex bytecode. Thanks.
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.
$ 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
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
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.
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.
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"
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.
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.
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).
[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)
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>
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();
}
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.
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?
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
I decompiled a jar of an Android application (going from apk -> dex -> jar) and the Java files show a number of compilation errors.
I uploaded the jar and the Eclipse compile log as:
https://github.com/gliptak/Krakatau/commit/4038c78e08a9aa0cfea41539f2bb08f14f0dfc27
Please let me know if I can offer additional details. Thanks
Original code:
class Test {
final static Object i = new Object();
}
Decompiled (invalid):
class Test {
final static Object i;
Test()
{
super();
}
static
{
Object a = new Object();
Test.i = a;
}
}
"Test.i" should be just "i".
See Why isn't a qualified static final variable allowed in a static initialization block? (has JLS link)
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.
But when I try to assemble it I get the following error w/ Krakatau.
Line 241 for me is the following "astore_11"
I literally changed one value from "www." to "wwwh7.", re-assembled it with no errors, tried to run it in my program and I get this error.
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?
How to prevents disassemble.py from writing out debug info like:
Apktool has "--no-debug-info" option.
There is any similar option for disassemble.py?
tks
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!
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
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
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.
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.
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
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!
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.