I had a .class file which I wanted to decompile. I tried JAD but it resulted in usual break, goto and return statements which resulted in compilation error in the generated source code by JAD. I had a hard time trying to resolve those compilation errors and everytime I tried to fix a goto statement with return statement, it would introduce other compilation errors.
I then had to hire a freelancer on odesk and the job was done. I wanted to know the exact procedure to be used to decompile the following .class files which can help me and others in future regarding these messy goto, return and break statements added by JAD.
https://drive.google.com/file/d/0ByGLlk1Fq3QIYzVaMGZ4MEVzcjg/edit?usp=sharing
In principle, valid class files can be generated by many more languages than just java, but only class files generated by a standard java compiler can be decompiled into valid java.
To add insult, even class files compiled from java source may not decompile properly, if the code flow is not recognized properly be the decompiler (that may be caused by the original code being very imaginative or the class has been compiled with a compiler that generates byte code not understood by the decompiler). I have experienced that my own code compiled with sun javac 6 would not decompile properly in one case with a nested while loop that had labels and breaks.
The class files may have also been obfuscated precisely to prevent decompilation.
In short, there's no guarantee a class file can be decompiled into valid java code, its not generally the decompilers fault, as one can express code flows in byte code that are impossible to express using plain java.
The generic way to (sort of) decompile such classes is to use javap (or any other tool that can display the byte code) and extract the logic by understanding the byte code yourself, then express the logic in plain java.
Related
I was inspecting the class file format since I wanted to add source code to the class file (which was possible in early Java versions) but all I found was a SourceFile attribute and the SourceDebug attribute. I was looking for the complete source code of the class to be bundled with the class file to ease the post-processing pipeline.
Does anyone know if my memories are wrong or how I can bundle the complete source code of a class within the class file so that I do not have to look up for the java-file when I want to check the source code?
Is there a compiler switch to do that?
Javac has a -g option adding additional debug information. Can someone tell me whats are the information it adds? Without the -g switch it generates lines of code index and source file information.
The main problem I have is generate a class file but only have a reference to a source file that might change. I want simply to bundle up source and class file.
In maven I can simply copy over all the source files to the target directory but would might be incompatible with Eclipse, IntelliJ and NetBeans IDE (and what not)... .
Using a decompiler will also provide a way to extract a useful representation of the source code since most decompiler will value the lines of code information and position the decompiled structures accordingly within the source code.
Since some scenarios will require access to comments and a correct representation on a char by char level, the decompiler would be a second rate solution.
One possible solution I found is defining a new class-file attribute (which is legal) that contains the source. Since the source is huge when compared to the class file, the content might be best compressed (yielding a 1:5 to 1:10 ratio).
This way the class file and the sources stay bundled.
The JVM specification guarantees that every JVM/Tool has to ignore unknown attributes.
I will invest into a wrapper of javac application, that ensures the source was not modified during compilation (and if yes, redo the compilation process) and after compilation is done adding the source code as a class-file attribute.
Since this will be incompatible to the IDE-build cycle of Eclipse (and most likely IntelliJ and NetBeans) it will also require a special post processor.
So integration will also require alternatives to the JavaBuilder.
Once the source code is attached to the class file in question it is very easy to do a lot of advanced stuff with it that helps with both maintaining and managing code. For me its important that the source code and a class stay together and the source information is a 100% percent equal to the source code it was compiled from.
I am a little bit confused...
I know that classes are loaded by the class loader only when they are needed,that is when we are trying to use static variables or when we are creating instance of that class.Thus if we have for e.g. 3 classes in our program and we are going to use only one,then only that particular class will be loaded and rest are not,but when we run the java compiler,it will create 3 .class files,I know these 3 .class files are byte code files,but then what is this byte code and what is the difference between loading a class and generating bytecode of a class?Where is the use of this byte code?If we are not going to use a particular class,then what is the need of generating a bytecode for that class?
Java is a compiled language. The purpose of compiling into bytecode is to allow the code to run on the JVM on any platform. Platform independence is a feature built into java.
Furthermore, you don't have to compile all three class files unless they have inter-dependencies. You can specify which specific files to compile in the console javac command. If you are using an IDE, check your settings or exclude the undesired class from the project.
Loading a class happens at runtime, when you're preparing to invoke whatever properties the class has.
Generating the bytecode of a class happens at compile time. This allows the code to be run on the virtual machine.
Java is a compiled language, and it runs on top of the Java Virtual Machine. Compiling bytecode translates whatever higher level code (be it Java, Scala, or Clojure) into machine-independent instructions to be read by the JVM. This is why that your (backend-specific) program will generally run without modification on Linux, Windows, and Mac OS X.
The Java language will compile any classes that have dependencies on each other within the path, so if you have a class but it is not used, chances are it will not be compiled. There may be tools that override that, so if you find yourself not using a class, then remove the class so that unnecessary bytecode is not generated.
Difference between languages like C++ and java is byte code. C++ binaries(compiled,assembled,linked) will have the machine(op) codes for the OS it got compiled for. In the case of java the byte code is the target for JVM. Byte code will have the opcodes for JVM. JVM in turn will initiate the respective os calls. So bytecode and JVM makes java programs independent of os.
Reg loading class loading,it happens when the program needs it. This is at runtime. JIT will do the second compilation of class when needed.
When we compile .java we get .class file.
The .class file is called byte code.
The Byte code in Java is nothing but a .class file which is not understandable by humans i.e (00110011). These .class files are generated only after the compilation of .java.
These .class file can be used to run on any platform.
How to look into code, that was generated after complilation?
I want to watch it and find how it was changed(because I particularly interested in type erasure).
I mean I can look into assembly code using javap -c SomeClass.class.
But how to look into generated code(with type erasure)?
got to Documents\NetBeansProjects\yourProjectName\build\classes\yourPackageName here you will see all your .class files that was generated after compilation and open them using any text editor.
Note: the .class files might contain some binary data and you will see some strange symbols
Note: an internal class will have the same name as its outer class but it will start with $ sign
After short amount of time I found Java Decompiler JD-GUI. It seems that the thing I was looking for. Sorry if did not clarify the question properly.
I have tried to decompile .class file with JD. BUt i got Strange code in it(Static call to a non static method, Classname.this.method etc.) .
Could you please tell me whether it will give 100 percent source code or not?
No, java decompilers can't give you the exact source code back. Many compiler optimizations will not be reflected back in the generated file.
Can i write bytecode inside a method of a class so that the compiler bypasses that part since it is already compiled. Something similar to writing assembly programs in C language using "asm"...
I think you mean Java. If that's the case:
Short answer: no.
Long answer:
There is nothing like asm { ... } in Java. But you could (not very clever in most situations) write a .class file (or have bytecode in textual representation and then assemble it in Java to a .class file) from Java and dynamically load and execute it.