How to recognize a generated .class file programatically? - java

I am developing an application that analyzes Java applications (Windup).
I'd like to be able to recognize programatically if a .class file was generated instead of written by a programmer and compiled.
As a human, I can tell because the decompiled code doesn't make much sense. It looks a bit like some kind of java-ish mix of C.
I could somehow implement recognizing the resulting decompiled code.
However, decompilation takes time, I'd like to skip decompiling for generated classes.
For more information on what is a generated .class file, see here.
Is there a way to recognize generated .class just from headers? Or perhaps some specific bytecode sequence?

As mentioned, any legal class file starts with the magic numbers 0xCAFEBABE as it is specified by the JVMS §4.1. The simple fact that a file starts with this magic number does however not guarantee you that the file represents a compiled Java class, as anybody is able to create such a file.
Reading between the lines of your question, I assume that you want to find out if a class was generated by javac or another compiler / runtime code generator. This is not possible to determine as anybody can imitate javac as close as possible. As a matter of fact, many runtime code generators try to imitate the javac compiler as closely as possible as it can lead to performance improvements as the JIT-compiler recognizes some patterns that are typically used by javac.
If the code that you want to analyze derives a lot from "usual Java code", you can look for byte code patterns that are not representable in the Java language. This way, you can prove that a class was not generated by javac but you cannot generally proof that it was generated by it.

Java Classfiles always begin with the magic bytes CAFEBABE. If you want to recognize classfiles, that's the best way to do it.
If that's not what you want, you'll have to clarify the question.

Related

java - Compile code on client side without JDK

I have a question which I'm pretty confused from.
I am aware of the differences between Java Runtime Enviroment and Java Developement Kit.
I'm writing a program that uses the ToolProvider.getSystemJavaCompiler() method to compile java code from within the code.
Now, I've been answered that I can't compile code from client side if my client doesn't have JDK installed. My main question is, how can I do that? I don't want my clients having to install JDK on their computer just to run my program.
Thanks in advance!
You need to compile it on your system, and distribute the class file of corresponding java source file to anyone.
That class file doesn't require JDK but JRE must be installed on that system to run the class file.
If you want to compile code, you need a compiler, so if the user can't be expected to have the compiler you need, you'll simply have to bundle it.
I really can't say I know how to bundle the standard javac compiler, though it's probably possible, strictly speaking, to find the Jar file that contains it and bundle that along with your code. No idea how robust such a solution would be, though.
But depending on your needs, you may not need the standard javac. There are tons of byte-code generation libraries out there, with more or less high-level functionality. I wouldn't really want to recommend anything that I have no personal experience with, but examples include Byte Buddy or ASM. You could probably use ABCL too.
Eclipse's compiler is worth a look as well.
There is also an so question here.
So there really is no way to do what it is you are wanting to do unless you bundle the compiler itself with you application, or unless you find a library that has all of the Java compiler code in it already so it doesn't have to use the JDK compiler, you will not get what you want, and what you want is the ability to turn a String containing source code into a Java class.
I do not understand what you wish to accomplish, but the BEST option I can give you is asm. If you are up for the task, you can manually write new classes at runtime without the presence of the JDK compiler. HOWEVER, this does not involve you using a String full of source code and turning it into a Class object. This is you working at the low level with the Java bytecode for the most part.
This tutorial can get you started:
https://www.javaworld.com/article/2071777/design-patterns/add-dynamic-java-code-to-your-application.html
And here is the Java documentation for class files. You can use this to expand on what you learned from the first link:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
That is the only instance creating classes on the fly that I can give you. That being said, you could try writing your own Java compiler that can turn source code into classes without ever getting the Java compiler, but at that point you are literally recreating the Java compiler yourself, and I assure you that is no easy feat for one person.

Easiest way to edit/modify compiled class file

My main problem is that i have some class files from a game where i wan't to edit/modify parts of it
What would be the easiest way to achieve this ?
Decompiling the whole code and recompiling is not an option unless you have some decompiler that doesn't cause errors in the source code, as i do not wish to spend time fixing them.
Best regards
A solution could be the use of bytecode manipulators like ASM or BCEL. They both provide an API to load a class file, change part of it and save it. ASM has the advantage to be able to do this during runtime.
You can also use the Krakatau disassembler/assembler I wrote. The disassembler turns a class file into a human readable (well readable if you understand bytecode anyway) format, which you can then edit and reassemble. This is useful if you want to view and edit the classfiles by hand, where writing a bunch of library calls and then compiling and running a program just to use ASM or BCEL is rather unwieldy.
Krakatau also has a decompiler specifically designed to handle obfuscated classes, so it may be able to produce valid source code even when no other decompiler can. Of course if the class is obfuscated, the generated source will probably still be unreadable.

Does javac optimize object files (*.class)?

I'm trying to limit changes from a jar file. I introduced a fix on the code, a very small fix in a single file. Javac compiler generates the new .class file and I plan to replace ONLY this single file in the jar (we had problems with the build and are unsure if the current build matches the production build).
I'm a C++ pro, but java... not so much. I wouldn't dare to do this in C++ as optimizers inline a lot of stuff from object files and static libs. I'm under the impression I can do this with no great consequences in java.
Any advice?
I usually hot deploy files on server, that creates no problem in JAVA. You can do it as long as your compiler version is same as the other files. It would not be a problem.
The Java Language Specification defines binary compatibility between class files. In general, class files tend to be much more compatible than they would be in C, so you'll probably be ok. However, there are a few gotchas, such as static final fields (constants) which are inlined by the compiler.
In any case, the situation in which you are not sure what code code you have running in production, I would consider to be very dangerous, and try to fix as soon as possible.

Is there any Java Source code obfuscator working on windows 7?

I require a source code obfuscator for Java that is working on windows 7.
Because I plan to release a closed source library in GWT it really has to be an obfuscator that outputs source and does not process ready to use .class files. The result files need to be .java files.
The only obfuscator that is Java-to-Java instead of .class as a result is Java Source Code Obfuscator from Semantic Design.
But sadly it seems this one does not work on Windows 7.
What about compile it into class files with all the debugging symbols stripped and then run a decompiler on the resulting class files? Example decompiler
Despite the existence of some quality work out there, I assure you Java obfuscation will NOT stop someone who is determined to decompile your code. Understand that all you are buying is a bit of time. If they have your class files in hand and choose to decompile them, it won't take long before they have your source code.
If you don't trust your customer, don't give them the class files. Come up with a different solution. More and more companies are moving to services as a way to keep their source code in house and still make their monies.
Most Java source codes are self obfuscated, nobody can understand them.
There are no effective obfuscators, the silly things they do do not deter anyone determined to steal your code. This is a false market based on false fears. If the threats were real, there will be de-obfuscators, selling for much higher price than obfuscators.
If you really want to obfuscate your code, don't use meaningless symbols, use misleading symbols.

Understanding Java Byte Code

Often I am stuck with a java class file with no source and I am trying to understand the problem I have at hand.
Note a decompiler is useful but not sufficient in all situation...
I have two question
What tools are available to view java byte code (preferably available from the linux command line )
What are good references to get familiar with java byte code syntax
Rather than looking directly at the Java bytecode, which will require familiarity with the Java virtual machine and its operations, one could try to use a Java decompiling utility. A decompiler will attempt to create a java source file from the specified class file.
The How do I “decompile” Java class files? is a related question which would be informative for finding out how to decompile Java class files.
That said, one could use the javap command which is part of the JDK in order to disassemble Java class files. The output of javap will be the Java bytecode contained in the class files. But do be warned that the bytecode does not resemble the Java source code at all.
The definite source for learning about the Java bytecode and the Java Virtual Machine itself would be The Java Virtual Machine Specification, Second Edition. In particular, Chapter 6: The Java Virtual Machine Instruction Set has an index of all the bytecode instructions.
To view bytecode instruction of class files, use the javap -v command, the same way as if you run a java program, specifying classpath (if necessary) and the class name.
Example:
javap -v com.company.package.MainClass
About the bytecode instruction set,
Instruction Set Summary
Fernflower is an analytical decompiler, so it will decompile classes to a readable java code instead of bytecodes. It's much more usefull when you want to understand how code works.
If you have a class and no source code, but you have a bug, you can do one of two basic things:
Decompile, fix the bug and recreate the jar file. I have done this before, but sysadmins are leery about putting that into production.
Write unit tests for the class, determine what causes the bug, report the bug with the unit tests and wait for it to be fixed.
(2) is generally the one that sysadmins, in my experience, prefer.
If you go with (2) then, in the meantime, since you know what causes the bug, you can either not allow that input to go to the class, to prevent a problem, or be prepared to properly handle it when the error happens.
You can also use AspectJ to inject code into the problem class and change the behavior of the method without actually recompiling. I think this may be the preferable option, as you can change it for all code that may call the function, without worrying about teaching everyone about the problem.
If you learn to read the bytecode instructions, what will you do to solve the problem?
I have two question
1) What tools are available to view java byte code (preferably available
from the linux command line )
The javap tool (with the -c option) will disassemble a bytecode file. It runs from the command line, and is supplied as part of the Java SDK.
2) What are good references to get familiar with java byte code syntax
The javap tool uses the same syntax as is used in the JVM specification, and the JVM spec is naturally the definitive source. I also spotted "Inside the Java Virtual Machine" by Bill Venners. I've never read it, and it looks like it might be out of print.
The actual (textual) syntax is simple and self explanatory ... assuming that you have a reference that explains what the bytecodes do, and that you are moderately familiar with reading code at this level. But it is likely to be easier to read the output of a decompiler, even if the bytecodes has been fed through an obfuscator.
You might find the Eclipse Byte Code Outline plugin useful:
http://andrei.gmxhome.de/bytecode/index.html
I have not used it myself - just seen it mentioned in passing.

Categories

Resources