for bytecode instrumentation in java, there is the asm framework and the bcel and javaassist libraries.
However I need to do instrumentation in native code, since some java classes are already loaded by the time the javaagent runs, eg java.lang.Thread, java.lang.Class, etc
is there any library for instrumenting java classes in native code?
Edit:
Seems there is a bit of confusion.
What I want is:
Create a native java agent, which uses JVMTI apis to change the bytecode of a class while its being loaded, using the OnClassLoad event hook.
I encountered this problem during my doctoral research. The answer that worked best for me was to perform the byte-code modification in a separate JVM using a java library (I used ASM).
I used the JVMTI class load hook to capture the class file and transmit it to the separate JVM using a tcp connection. Once the class had been modified within the separate JVM I returned it to the JVMTI Agent, which copies it into VM memory and returns a pointer to the modified class file to the JVM.
I found that it was too difficult to weave classes within the same JVM as was being profiled as the system class files I wanted to modify (java.lang.Object, for example) had to be loaded before any class files I needed to perform weaving. I hunted for c/c++ bytecode libraries without much success, before settling on the separate JVM approach I finally used.
You can parameterize the JVMTI agent with the hostname/port of the weaver JVM, or you could use some form of discovery, depending on your requirements.
The JIT will turn byte code into native code. If you want to produce native code, you need to let the JIT do it or write native code which is called via JNI.
Perhaps what you are trying to achieve can be done simpler another way.
Create a native java agent, which uses JVMTI apis to change the bytecode of a class while its being loaded, using the OnClassLoad event hook.
Though you don't need to do what you want. Why make the solution more complicated (and less likely to work) than it needs to be?
You cannot change the byte code of a class once it has been loaded. You can either make sure your instrumentation runs before it is loaded, or you can create a new ClassLoader, and re-load the classes inside of it by not asking the parent class. You can't use those classes with code loaded outside of the ClassLoader though, as that code will refer to the earlier loaded, non-altered class.
Related
I stuck with a problem. I use Chilkat for Java and as i understand there is no, any Maven Repo for it. As it is a two-component library - i need to inject .dll, via System.load(). This part is clear to me, but also they provides something, like wrapper, which calls methods in .dll.
So, i don't want to import their .jar to my project, but, then i call native methods by my own it fails with java.lang.UnsatisfiedLinkError. Because, then java tries to invoke a native method it adds some stuff at the beginning of it's name. For example: if i declare native method in my package, then it will be invoked, java will add all package hierarchy names to it's name.
Can i somehow call directly the native method by it's name, without any runtime "adaptations" ?
javac can generate the bindings you might be looking for ...DLL export viewer (among several others) can list exported methods. Or for SO, just use dumpbin /EXPORTS ./filename. That method names would change at runtime is not a reality, this only happens once when obfuscating them, at build time - which usually excludes all the objects, which need to stay accessible (for reflection).
Just start a new JNI project and learn how it works with vastly reduced complexity. There still is a chance, that this one JAR might pass licensing information in the native assembly - or that the native assembly performs cryptographic functionality for the JAR. An a commercial library is not to be treated alike open source - I'd read THEIR licensing terms, to begin with.
I was checking out the source code for FileOutputStream class in Java and I noticed some native methods. To my understanding of native methods there should be a call to System.loadLibrary() somewhere, but I can not find it anywhere in the JDK source. I would like to find the dynamic library which contains the implementation of the native methods and also see the actual call to System.loadLibrary(). Can anyone help?
EDIT:
To rephrase my question, I would like to find out how JDK loads native code without loadLibrary and to actually see where is that configured in the repository.
Link to source: https://github.com/openjdk-mirror/jdk7u-jdk
jdk7u repository is obsolete. It hasn't been updated for more than 8 years. The up-to-date repository is at https://hg.openjdk.java.net/jdk/jdk/file
The native implementation of FileOutputStream methods is here.
As the path suggests, this native code is a part of libjava (libjava.so or java.dll).
libjava is not the JVM, but it is still the essential part of Java Class Library, since it contains the native methods for basic classes like java.lang.Class, java.lang.ClassLoader etc. That's why JVM preloads libjava during bootstrap, see ClassLoader::initialize.
As long as libjava is unconditionally preloaded by the JVM, there is no need to call System.loadLibrary.
The implementations for the native methods in FileOutputStream are included in the JVM. System.loadLibrary() is used with external libraries that need to be loaded separately - it's not needed when the native methods are already compiled into the JVM.
You can see the source code by searching the source code for mentions of "FileOutputStream" in C language.
The implementation is platform specific: for example, for Windows you'll find FileOutputStream_md.c which calls functions in io_util_md.c.
I am looking towards some approach where by using Java agent or instrumenting classes (preferably something at lower level than user classes) to intercept all object creation in JVM (new or any alternative ways to create Object), There is a similar question which doesn't focus on Java agent or something lower than instrumenting user classes
Java Objects can be created in several different ways.
From Java code, when a Java method, either interpreted or compiled, executes one of the following bytecode instructions: new, newarray, anewarray, multianewarray.
From native code, when native methods, including those in standard class library, call one of JNI functions: NewObject, NewObjectArray, NewStringUTF, NewDirectByteBuffer, etc.
Directly from VM runtime, when a new object is created internally by JVM, for example, in response to Object.clone(), Throwable.getStackTrace(), Class.getInterfaces(), etc.
Unfortunately, there is no single point where you can collect objects from all these sources. However, there are means for intercepting all of them.
Objects instantiated from Java can be caught by an Instrumentation agent. The agent needs to define a ClassFileTransformer that will scan the bytecode of all loaded classes for object-creating instructions and modify it.
Note: there is no need to intercept all new instructions, you can instrument Object() constructor instead. But you still need to intercept array allocation instructions.
JNI functions can be intercepted by JVMTI agent. You need to define your own native hooks for NewObjectArray, NewStringUTF etc. and then replace JNI function table. See JVMTI Reference for the details.
Objects created by the VM can be caught by JVMTI Event Callback mechanism. The desired event is VMObjectAlloc.
Note: JVM will not post VMObjectAlloc event for objects allocated from Java or by JNI functions.
All other ways of object instantiation (cloning, reflection, deserialization) fall into one of the above categories.
Get JDK 8 Demos and Samples from Oracle Java SE Downloads website.
There is a sample JVMTI agent for exactly this question.
Look under
jvmti/heapTracker
jvmti/hprof
You can take a look at this opensource java agent created by devexperts team
https://github.com/Devexperts/aprof
It provides nice reports to detect where memory is allocated. But, as i know, it doesn't intercept new objects created via JNI or sun.misc.Unsafe.allocateInstance in current version
It is pure java agent which manipulates bytecode with ASM. Before each object allocation aprof inserts method call which traks allocation size and location stack (where this allocation occurs)
The method DriverManager.getCallerClassLoader() in class java.sql.DriverManager is declared as native. I understand that all the class loaders references in an application are available in the current executing JVM. Also, my basic understanding about native method is that it's used to call the method defined in native libraries and they execute outside the JVM execution environment.
My question is, what is that needed by DriverManager.getCallerClassLoader() which requires its implementation to be native?
My basic understanding about native method is that its used to call the method defined in native libraries
This is correct, native methods represent calls of the code that is part of a natively compiled library
and they execute outside the JVM execution environment
That is what native methods typically do. That is, the native methods that Java users write. However, native methods are not limited in what they can do: once you're outside of JVM, you can do what you wish. In fact, Java's built-in classes such as Class<T>, heavily rely on the ability to do so, with dozens of native method sprinkled around their Java code.
One of these methods is package-private java.lang.Class<T>.getClassLoader0 (yes, with a zero). The implementation of ClassLoader.getCallerClassLoader ultimately refer to this method, which queries the internals of JVM to fetch the class loader.
Note that DriverManager cannot forward the call to ClassLoader.getCallerClassLoader, because that would return the DriverManager's class loader (because DriverManager would be the caller of getCallerClassLoader). It is not possible for the DriverManager to repeat the "magic" of ClassLoader's getCallerClassLoader either, because it is located in a different package (i.e. not in the java.lang), so Class<T>.getClasLoader0 is not accessible. That is why it is forced to move the getCallerClassLoader into the native territory, where the native code can obtain the calling class and fetch its class loader without restrictions.
I'm trying to use JPF to verify my bytecode generated while runtime with javassist.
The code I'm trying to verify is supplied by the user while my program is running. As I can't check all OOP models and stuff like that I need a verification process before running his code.
At the moment I simply generate bytecode with javassist from his classes.
My problem now is that I get exceptions sometimes because the user did some inheritance mistakes and stuff and my application shuts down with an exception cause I tried to load and execute his classes.
Therefore I would like to verify that generated bytecode in runtime to avoid such exceptions and to know earlier if the classes supplied from the user are faulty (or contain any problem).
Is this possible with JPF while in runtime?
Any other solutions on this?
Thanks!
As JPF uses BCEL Stand-alone Bytecode Verifier might be helpful. Just programmatically invoke the Verifier class - or even dive into the details of this class.
hth
There are many points to check:
the bytecode itself according to the class file format
the runtime phases: loading, linking and initializing
From my point of view, a ClassLoader does all that steps but it generally loads one Class at a time, and only on demand.
In your context, I propose you write a ClassLoader that loads in sequence all classes from generated bytecodes and reports each failing class name with caught exceptions. The ClassLoader is instantiated with the reference to the relevant parent ClassLoader and is discarded after the test passed, the generated bytecode is then loaded by the original ClassLoader of your runtime context.
Probably this class loading check may be implemented thanks to OSGi but it will require more efforts than a standalone ClassLoader.
If you don't have an absolute requirement to use JPF, the ASM library includes CheckClassAdapter which can verify byte code. It is only a sanity check however - I don't believe it will catch problems with inheritance etc.