I am trying to instrument a class file, but I was just wondering where annotations are stored in the class file format. I tried putting them in the interface table however, when I did that it only recognized them as an interface not as an annotation.
They are stored in the RuntimeVisibleAnnotations and RuntimeInvisibleAnnotations attributes for classes and methods class members, and the RuntimeVisibleParameterAnnotations and RuntimeInvisibleParameterAnnotations attributes for method parameters. You can find more detailed information about the classfile format in the Java VM Specification.
When trying to understand Java bytecode, a good starting point is writing in plain Java the class you would like to create using bytecode. Compile it, then use tools to retrieve generated bytecode.
Here's some tools I can think of :
ASM's Textifier (this class has a main method to make it easy to run)
Intellij IDEA Show bytecode view
Bytecode outline plugin for Eclipse
Related
I've been trying to find an answer to this for some time, but I think part of my problem is that I don't really know how to phrase my question. I understand the that JVM ultimately preforms all the system calls at run-time that the Java program needs to make, my confusion is about the underlying way that Java classes tell the JVM to do this.
Take for example, the File class in the standard Java library. As far as I know, this is considered the most fundamental API for opening/creating files in Java. But, File is just another class right? So in theory I should be able to write my own File class from scratch which doesn't utilize the pre-exisitng one, right? How would I do that? What is happening inside the File class that tells the VM to actually create the file? I looked at the source code for the File class, and it looks like it calls another class called VMFile, but I could find no explanation of what VMFile is. When I looked at the VMFile source code, it just had function declarations with no definitions.
Thank you for your help.
The Java Native Interface (JNI) is the glue between Java classes and the OS. Native methods have a 'native' attribute (look it up in the JLS).
Libraries such as ASM, BCEL, Javaassist and AspectJ are all capable of runtime bytecode manipulation but how do they achieve this?
I have done some basic bytecode manipulation using ASM before but i don't understand how it works. Is the Java Agent executed in the JVM before the remainder of the program, allowing for ASM to load the compiled classes and edit them before they are executed by the JVM?
If so, is it possible to perform java bytecode manipulation without using an external library like ASM and loading the compiled class files with an BufferedReader and writing a custom parser etc. for example?
These libraries settle on standard Java APIs which, of course, you can also use yourself without these libraries.
First of all, Java class files are just sequences of bytes in a well defined format, as specified in JVMS §4, The class File Format. The primary task of the mentioned libraries is to provide tools for processing byte sequences in this format. The second is about getting the definitions of existing or exporting modified or newly created classes.
There are two different way of dealing with the second task. One is to read compiled classes from persistent storage like file systems or jar files, etc. and writing them back to these storage while the particular code is not running, like build and deployment tools do. This should be trivial, as it just boils down to reading and writing bytes.
The other is to manipulate classes at runtime, which can be done by Java Agents via the Instrumentation API. It offers mechanisms for intercepting classes at loading/definition time before their first use, but also redefinition of classes. The latter can’t change them freely, currently, it has to retain all field and method declarations, so it can be mainly used to change the executable code of the methods.
If you want examples for class file processing without additional 3rd party libraries, there are some answers on Stackoverflow
Extract the class name from a class file
Find all class dependencies
Parse the constant pool
Iterate over all instructions of a method
Of course, these examples are only single-purpose code or sketches. If you expand them to something more general or useful, you will soon end up at basically re-implementing these libraries.
Class files are just a sequence of bytes, the format of which is specified in The Java Virtual Machine Specification. BufferedReader is for text files so you'd want BufferedInputStream, but the format is quite complicated.
You can load manipulated class files as if they were generated by javac. You can also load them dynamically with java.net.URLClassLoader.newInstance or similar. Java Agent allows modification of class files as they are loaded, either through a Java or a native interface (the latter being necessary if you want to modify classes the are loaded before classes that load classes).
Recently java development group at Oracle announced a new JEP( Java enhancement proposal) for class file manipulation. Now we will not need any additional libraries.
https://openjdk.org/jeps/8280389
I'm trying to use the Java ASM library, and after quite a bit of research, I haven't found the solutions to a problem I'm having. I'm trying to make an application that does the following:
Reads classes from an external Jar file
Remove completely certain methods from specified classes
Print to console or store the modified class' compiled bytecode or compiled class contents, like from new String(cw.toByteArray()), cw being an instance of ClassWriter (Similar to how you would see if you edited a class file with notepad)
I have been able to read bytecode and the compiled class contents, but not remove methods. I haven't been able to find any working code, only partial code with very little explanation of how to implement it.
You can implement a ClassVisitor that overrides the visitMethod method and return null from this method without invoking super.visitMethod when you discover a certain pattern.
This way, the method in question is skipped and not added to the created class file.
like:
import com.xxx.utility.*;
class MyClass{
public static void main(String[] args){
MyUtiliy ut = new MyUtiliy();
MyUtility.doAdd(5, 6);
.......
}
}
When put the "." after MyUtiliy, eclipse will tell you all the methods you can use, how does eclipse achieve this?
Does eclipse use the reflection on the fly? (like the answer of this thread? )
The architecture of the eclipse software is describe here, in the section 6.1.2. Java Development Tools (JDT) it briefly describes the incremental build system used. That system would have all the relavent information to populate the autocomplete mechanism.
For the exact mechanism, you would have to look at the eclipse source code.
Yes Eclipse (and any other Java IDEs) uses reflection.
If fact Eclipse uses a ClassLoader for each project's libraries, so it load the classes in jar files, and after that everything is easy, it can get information using reflection.
By the way java IDEs not only use reflection, but also read class debug info, to extract parameter names, and so on.
There is an explanation in this article. Basically the Eclipse Java compiler builds an Abstract Syntax Tree (AST) of your code which lets it find all the information it needs for autocompletion very quickly.
So it is not using reflection for this, rather it is compiling the code in to an internal form for quick access.
When no source code is available (you just have a .class file) it is still possible to construct the part of the AST containing the class methods and types which are needed for completion. This appears to be done by reading the .class files directly rather than using a class loader (org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader)
I have used JD decompiler for decompiling a jar file.
Affter do that I have source code.
However, I think that it is be encrypted!
I get some class with the name like "Cny3", "JmcU","Ow0w","YrRb","Jhaa","gzL9", ....
Can I decrypt or get the name of class with any software or tech.
Thanks for your help.
The code was not encrypted but obfuscated (see obfuscated code on Wikipedia). Class and method names where transformed to unique random strings to make the understanding of decompiled code difficult. Reversing this transformation is not possible.
No. The source was probably obfuscated.
(Emphasis mine):
I get some class with the name like "Cny3",
If most class have good names and there are just a few ugly names, then I wouldn't think of code obfuscation. I would think that some byte-code enhancing tool has generated some internal classes. Or perhaps some other tool which generates classes.
Tools which may be involved:
AOP tools usually can weave during compile-time.
Everything wit an APT compiler plugin (Annotation Processing Tool)
Edit Obfuscation tools usually also encrypt instance fields and method names as far as possible. How do they look like?