Referencing ClassLoaders in another VM - java

So I'm creating a profiler application. It has a GUI class which is used to control the profiler. It consists of 2 pieces at runtime:
1) An application (GUI) for control
2) An agent to be loaded into the target application
It lists out PIDs, and then calls loadAgent() on the VM. So I want all of the logic to be done in the primary application. The idea I had was to get an instance of the Instrumentation class from my agent, then invoke a callback method via reflection. This would set a static field in the primary application to the Instrumentation instance, and notify the primary application that the agent is successfully loaded.
The issue I'm having is that I'm unable to grab the primary application's class which contains the Instrumentation field. Class.forName(String) implicitly looks in the ClassLoader for that application. The other method can look for classes in another ClassLoader...unfortunately I have been entirely unable to get the ClassLoader for the agent/target application from the primary application to pass into it!
I see no methods in the Instrumentation or VirtualMachine classes that allow me to do this. I haven't found any questions of this nature on the internet that are answered in a satisfactory method either.
I had some ideas...
A) If there is some kind of equivalent of Class.forName for ClassLoaders maybe I could serialize the ClassLoader and send the serialized string over a socket, then grab it that way. Thus far I haven't found anything remotely like this.
B) Navigate through the ClassLoaders in the agent (there is a ClassLoader.getParent() method..but that's the only means of navigation I see), and find the proper ClassLoader with a deep equals comparison. I don't even know where to begin..I was hoping I could iterate through VirtualMachines.list() and there would be something I could call. There isn't.
C) Load the agent in the primary application, and somehow pass that specific instance of the agent to the target application. Since they are different ClassLoaders I can only assume this doesn't work. For all I know there may be a way to do it though?
D) Create a custom ClassLoader in the primary application and load the target application using that. The issue here is I want full "attach" functionality which this prevents.
I really don't want to put all the logic in the agent, so I thought I would ask you guys before going that route. Googling this has been less than fruitful. Thanks in advance!

I think that you misunderstand how the attach API works in this case. The attach API allows to register an agent from a local VM process to a remote JVM process. After attachment, the remote VM executes the agent's agentmain method in a designated thread. The agent is not aware of its attachment process and cannot communicate objects from the remote heap to the attaching VM's heap.
Also, ClassLoaders are not normally serializable. You would rather need to communicate necessary information via some socket between processes. For this purpose, the local VM can for example communicate a socket address as an argument to the agent on which the local process later waits for information to arrive from the remote VM. In this cause, you should also consider what information you want to be exposed from the remote VM. You probably do not want to send serializable objects.

Related

Existing apis/libraries to compile/run java code?

I'm trying to add a java scripting option to my web application with the following requirements:
1-The user writes custom java code.
2-The user can compile/run this code.
3-The user can upload jars and use them in his code (without using a custom class loader/reflection).
By overriding the java class loader, I managed to achieve the first 2 requirements.
However, for the 3rd requirement, I am unsure how to proceed.
I was wondering if there was a way to use an existing api to handle this, or any offline java code compilers to execute this custom code:
input : java code+ dependent jars -> output : code execution
There is no way to dynamicly load additional JARs from the user without creating a new ClassLoader instance. But it doesn't necessarily need to be a custom subclass of ClassLoader.
The general idea is that you create a new instance of (say) URLClassLoader providing the URLs for (say) a local copy of the user's JARs. This new classloader would typically have your application's classloader as its parent classloader. Then you would use the new classloader to load the user's classes; i.e. the ones you wanted to user. You would need to reflection to create instances of those classes, and then you could cast them to an interface in your app's code-base and invoke methods on them as per a normal class.
Offline compilation won't help. The problem you need to solve is getting your application to >>load<< the user's code.
Warning: what you are proposing to do sounds rather dangerous. You have no real control over the code that the user is going to put into the Java source code or JAR. It could potentially do all sorts of malicious things: reading / writing your server's files, exfiltrating secrets or confidential data, mining bitcoins, causing your server to participate in a DDOS. Or just do something that is annoying and disruptive.
That potentially malicious coder is going to run within your webapp on your server.

Java: Method hooking & Finding object instances

Situation
Hi, I have 2 problems.
The situation is that I'm writing a Java API for Windows that also provides tools for injecting code into a process and then manipulate the target. I have already implemented the injection-part, for example injecting a jar into another jar. At this point my jar gets called (while the target already is at runtime) and starts in a complete static context.
Goals & problems
From here I have two goals:
I'd like to interact with the targets objects, thus I need references. For many objects this is already possible because they provide static access to their instances. For example awt.Frames#getFrames() provides access to all created Frame objects. But it would be awesome if there is a possibility to get access to arbitrary objects on the heap. Something like 'Heap#getAllObjectInstances()'.
Given an object instance, I'd like to hook up onto arbitrary functions of this object. For example whenever BufferStrategy#show() gets called, I want it to call another method first.
So I summarize the problems as follows:
How to get arbitrary object references from a static context?
How to hook up onto arbitrary functions?
Remarks
What I've done so far, remarks and ideas:
The JDI (Java Debugger Interface) provides such a method via VirtualMachine#allClasses() -> ReferenceType#instances(0). But the JDI needs the target JVM to be started with additional debug parameter which is no option for me. One could go down to low-level and analyze the heap with memory tools, but I hope someone knows a more high-level approach. Using the Windows API would be an option for me as I'm familiar with JNA/JNI, but I don't know such a tool.
The last resort would be to use IAT hooking with C-Code, a very low-level approach, I'd like to avoid this. As I can assume having a object reference at this point, maybe does the Reflection API provide a method to change an objects method? Or at least simply provide a hooking mechanism?
Be aware that changing the targeted code certainly is no option for me. And that it is already at runtime, thus ByteCode-Manipulation could also be an option.
Scenario
A scenario where this would come in handy:
The target is a game, deployed as jar. It renders with a Double-Buffer-Strategy, using the BufferStrategy class. It displays the image with BufferStrategy#show(). We inject our jar inside the game and like to draw an overlay with additional information. For this we get an reference to the used BufferStrategy and hook up onto its show-method. So that it calls our drawOverlay-method everytime it gets called, then we pass back to the original show-method.
What you need is JVMTI agent - a native library that makes use of JVM Tool Interface.
Agents can be attached dynamically to a running VM using the Attach API.
See VirtualMachine.loadAgentPath.
To get all instances of a given class use JVMTI IterateOverInstancesOfClass function.
See the related question for details.
To intercept a method of a foreign class you'll need JVMTI RetransformClasses API. The same can be also achieved by using Java-level instrumentation API, see Instrumentation.retransformClasses.
For the example of JVMTI-level method interception refer to demo/jvmti/mtrace from Oracle JDK demos and samples package.
Java-level instrumentation will be easier with bytecode manipulation libraries like Byte Buddy.

Reflections on tomcat server from the outside

As part of a challenge, I would like to use reflections to get information about the code running on a tomcat server as *.jsp. (Assuming that the server is not configured very secure and allows this).
Google shows absolutely no answer regarding tomcat and reflections from the outside.
I guess I might have to combine it with Remote Procedure Calls or sth like that. Any ideas?
You don't get free exploits just because Java has reflection.
Reflection (as in java.lang.reflect.*) works only from the inside. Code executing in a JVM process can reason about other code running in the same context, IOW, the program can reflect about itself.
You would need to be able to inject your spying code into the server's java process.
Luckily, servers generally don't allow you to do that, not even badly configured ones - unless there is a remote code execution vulnerability like CVE-2013-4444 for example.
You also can't abuse Remote Procedure Calls that easy. First of all, a remotely callable procedure must be placed there by the programmer. And there are none by default. But assuming you find something that is for some reason unprotected, you'd still only be allowed to call that procedure, not arbitrary code of your choice. If you can, you've probably found a vulnerability.

How to call remote JVM class method

My application code will run on one box. I have a tool that will be executed on a different box. Here I want to access my application code specific class method in the tool where it will executed on different box. How can I do this?
I don't want to change any existing code on the application side, I only want to add code on tool side to access the application class method. The class that I want to access is a regular java bean class.
We used to have a somehow similar issue.
We end up creating a simple library that allow us to distribute classes over several JVMs and to call methods in remote JVM.
You can have a look on https://github.com/plantuml/remotejvm to see if it can help you.
May be you need to have a look at Remote Method Invocation. Also take care of which version you are using, versions before Java 5.0 required the RMI stubs to be compiled separately.
Java RMI Tutorial
RMI online training
You would want to take a look at remote method invocation(RMI). It is not possible without adding code on the application side since you need to register the application with the RMI registry. The RMI registry is sort of a directory lookup to allow remote applications to access the application.
You could also use RMI-IIOP but it has the same constraints. You need to register the application with tnameserv
Link: https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/index.html

Java, runtime class reloading

I am looking for a way to reload a class into Java at runtime. The motivation is to make debugging more efficient. The application is a typical client/server design that synchronously processes requests. A "handler" object is instantiated for each request. This is the only class I intend to dynamically replace. Since each request deals with a fresh instance, reloading this class won't have any side-effects. In short, I do not want to restart the entire application every time there is a change to this module.
In my design, the Java process becomes aware that a .class file has been updated in the classpath in between requests. When this happens, the "handler" class is unloaded and a new one is loaded.
I know I can use the classLoader interface to load in a new class. I seem to be having trouble finding the proper way of "unloading".
Classes will be unloaded and garbage collected like any other object, if there is no remaining reference to them. That means there must be no reachable instance of the class (as loaded by that particular classloader instance) and the classloader instance itself must be eligible for garbage collection as well.
So basically, all you have to do is to create a new classloader instance to load the new version of the class, and make sure that no references to instances of the old version remain.
I believe that you actually need to have a hierarchy of classloaders, and in order to reload you actually get rid of the low level classloader (by normall GC means), and hence all the classes it loaded. So far as I know this technique is used by Java EE app servers for reloading applications, and there's all manner of fun results when framework code loaded in one classloader wants to use classes loaded somewhere else.
As of 2015 also java's class reloading is a missing feature.
Use OSGi to create a class reloading application.
Use jrebel for testing. There are a few others which does the same thing.
Use application server and externalize the parts which you want to reload into a separate web application. Then keep deploying/undeploying. You will eventually get some perm gen space overflow kind of errors due to dangling old ClassLoader instances.
Use a script runner to execute parts of changeable code. JSR-223 Java Scripting API support for the scripting language "Java".
I had written a series about class reloading. But all of those methods are not good for production.
The blog and source codes in google sources
IMHO this class reloading is messy in java and its not worth trying it. But I would very much like this to be a specification in java.

Categories