How to find a class instance in a running JVM - java

I am trying to figure out a way to find a class instance inside a working JVM. The JVM is embedded into another process and an object is created by this process. The same process executes my Java code. I do not have a direct access to the Java object reference in my Java code, but I know the class of that object. I want to find out if there are objects of this class already instantiated in JVM, and if they are, I want to find them (get say an Object array with references to all the instances of this class). This mechanism can be either a Java API or an JNI API.
I know it is possible since debuggers let me inspect all instances. I just cannot seem to find the way.
Thanks
Nikita

In case anybody is curious, It is possible and I am doing it now using JVMTI. Not straightforward, but very doable. You can look at my other post about jvmti and you will find the answer.
Perplexed by jvmti object allocation callback behavior
Thanks

Use Java Instrumentation APIs.

This should be possible from another process using the debug interface
http://docs.oracle.com/javase/6/docs/jdk/api/jpda/jdi/
However, if I understand your requirement correctly, you would need your process to debug itself which is probably not going to work.

Related

Block instances of a class at the JVM level?

Is there a way to configure the JVM to block instances of a class being created?
I'd like to do this to ensure no service running in the JVM is allowed to create instances of a class that has been identified as a security risk in a CVE, lets call that class BadClass.
NOTE: I'm looking for a general solution, so the following is purely additional information. I would normally address this by switching the library out, or upgrading it to a version that doesn't have the exploit, but it's part of a larger library that wont be addressing the issue for some time. So I'm not even using BadClass anywhere, but want to completely block it.
I do not know a JVM parameter, but here's some alternatives that might pout you in a position that solve your requirements:
You can write a CustomClassLoader that gives you fine control on what to do. Normal use cases would be plugin loading etc. In your case this is more security governance on devops level.
If you have a CICD pipeline with integration tests you could also start the JVM with -verbose:class parameter and see which classes are loaded when running your tests. Seem a bit hacky, but maybe suits your use case. Just throwing everything into the game, it's up to you judging about the best fit.
Depending on your build system (Maven?) you could restrict building applications just on your private cached libs. So you should have full control on it and put a library - review layer in between. This would also share responsibility between devs and the repository admins.
A distinct non-answer: Do not even try!
What if that larger library that has this dependency wants to call that method? What should happen then?
In other words, what is your blocking supposed to do?
Throw some Error instance, that leads to a teardown of the JVM?
Return null, so that (maybe much later) other code runs into a NPE?
Remember: that class doesn't exist in a void. There is other code invoking it. That code isn't prepared for you coming in, and well, doing what again?!
I think there are no good answers to these questions.
So, if you really want to "manipulate" things:
Try sneaking in a different version of that specific class into your classpath instead. Either an official one, that doesn't have the security issue, or something that complies to the required interface and that does something less harmful. Or, if you dare going down that path, do as the other answer suggests and get into "my own classloader" business.
In any case, your first objective: get clean on your requirements here. What does blocking mean?!
Have you considered using Java Agent?
It can intercept class loading in any classloader, and manipulate it's content before the class is actually loaded. Then, you may either modify the class to remove/fix it's bugs, or return dummy class that would throw error in static initializer.

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.

Monodroid, Interop betwen Java and C#

We have a big Java application under Android ("big" just means it's too much work to translate the application). We must access to an engine written in .Net (this engine is also too "big" ...). This engine is only calculation.
We therefore seek a solution with monodroid. Our main problem is interop betwen monodroid and Java. At this time, we get :
call a Java function in a .jar library from a Mono application
But we can not call and start a Java activity. Is it possible ?
The second problem is that we do not know how to communicate from Java to Mono. Is it also possible?
There are several ways to call integrate Java and managed code, depending on what exactly you want to do.
Java to Managed
If you need to call some managed method, you may be able to use Android Callable Wrappers, which are generated for every Java.Lang.Object subclass. However, there are a number of limitations, so that may not be ideal.
If you need to create an Activity, you can use Context.startActivity(), the same as you would in Java. You can view the generated obj\Debug\android\AndroidManifest.xml to determine the appropriate class name to use, or you can use e.g. ActivityAttribute.Name to manually control the Java-side name. (Using ActivityAttribute.Name is not recommended, as it slows down type loading.)
The same is true for Services: use Context.startContext() and continue on your merry way.
If you need to share data, the easiest way would be to use a ContentProvider. ContentProviders are usually intended for cross-process data sharing, but they should be usable intra-process as well, when you need to share data between Java & managed code and you hit the limitations of Android Callable Wrappers.
Managed to Java
By and large, calling Java code from C# is the mirror of Java code calling C#: you can use e.g. Context.StartActivity() to start a Java activity, use a Java-side ContentProvider through the the Context.ContentResolver property, etc.
An example of starting a Java activity from managed code is the GoogleMaps sample, in which Context.StartActivity() is used to launch the included Java activity.
You can also use Java Native Interface (JNI) support to create Java instances from managed code and invoke methods on those instances. This is painful and brittle, but it works and allows invoking APIs that aren't otherwise exposed.
You can easily call Java activity from native code like this:
var intent = new Intent().SetClassName(this,"com.myapp.java.JavaActivity");
StartActivity(intent);
As I understood from this article you can invoke native code from Java via ACW, but I think that it's too difficult

How do I catch the read and writes in a java program?

I am trying to create a tool that can capture all the read and writes made by a java program. Also, I would like to know what fields of what object is access/modified.
I currently looked at:-
1) java.lang.instrument
I could not do much with that. I could not understand how to write an agent that can get access to the a running program and create a watch on different objects/fields and anything related. I would appreciated if you have any idea or information on that.
2) jvmti
I looked at jvmti and tried to create a jvmti tool, but I figured out that to get the objects, I would need the JVMTI_EVENT_OBJECT_ALLOC be a potential capability. But, I figured that, it is not. Moreover, I read that this event is not called for new command. Hence, at the moment, even this does not seem applicable.
So, I would like to know if you guys know any way to do what I want to do, either using the above mentioned methods or any other technique/tool that you may be aware of?
NOTE: I do not have access to the source code of the application. All, I have are the class files.
Check these out:
http://download.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html
http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html
http://jamonapi.sourceforge.net/
http://www.manageengine.com/products/applications_manager/java-runtime-monitoring.html
It's very easy to do with the ASM lib. Create a new Class Loader that instruments all classes before loading them and use it for loading the target classes. Create a new MethodAdapter and override the visitFieldInsn method. Then look for the PUTFIELD, PUTSTATIC, GETFIELD and GETSTATIC opcodes. Although this might look scary (as my explation is most likely gibberish), it's in fact pretty easy. Just download the ASM manual and you'll know how to do it in no time.
Edit: I was forgetting to tell that in order to be able to intercept the reads and writes of done by the JDK code you have to instrument those classes, save them to files and run the JVM with a modified bootstrap classpath, through command line argument -Xbootclasspath (java.* and some other packages; I believe that at least sun.* and javax.* also need this).
This may also be doable with AspectJ... but I'm not sure.

Is it possible to log if a class in the JVM is used?

I have a Tomcat with some applications running. I cannot restart the Tomcat but I would like to monitor the usage of class files.
I would like to log if a specified class is used. Is this possible?
How could I accomplish it?
Class Usage: If an object for this class is instantiated or methods are called etc.
Clarification: I cannot restart the application. Every solution with recompiling the running code are not acceptable. That makes the problem so hard.
Remote debugging/JMX is not enabled yet. It would be a similar effort like recompiling the application to activate it.
Platform is RHEL, 64 Bit.
I would like to log if a specified class is used; i.e. if an object for this class is instantiated or methods are called etc.
A memory profiler would tell you if a reachable instance of a class exists at the instant you run the profiler. An execution profiler could tell you that a method or constructor is called during some interval ... though it might also miss a call, due to the way that profilers work.
The webapp's classloader could in theory tell you if a class has been loaded, but I doubt there is a way to call the classloader's method that doesn't involve a restart. Also, there is no way to know if a method has EVER been called or an instance has EVER been created apart from adding monitoring hooks to the class. And adding those hooks would entail a restart.
And of course there are other ways that a class could be "used" that don't entail constructing instances or calling its methods.
So depending on what you are really trying to figure out, you may be out of luck.
I think you need profiling for that.
Profiler will allow you to see which classes are used.
Or the programmers fav - System.out.println :)
If you have access to the source files, you could simply put some log statements in the constructor of the class (assuming instantiation implies class use).
If object instantiation is not what you mean by "the usage of class files", then perhaps you mean that you'd like to know when a class is loaded by the JVM? If so, static initialization blocks may be able to help; you could put the log statements there.
If you are on Solaris or OS X, then a DTrace probe might on option.
Other than that, if you cannot attach a debugger or profiler or other monitoring tool to the already running JVM (which depends on options you would have needed to specify on startup), you are out of luck.
If you want to know it programatically then I don't think it is trivially possible.
But you can do some reflection to get to know, by calling this method.
ClassLoader#findLoadedClass()
If the method returns null, that means the class is not loaded and hence not in use.
The problem of course, is that the method is protected, so you need to use reflection.
You can define a static block in the class
class X {
static {
System.out.println("class X has been loaded");
}
...
}
that will be called once when the class object is loaded.
If you cannot edit the code, and you have a JRE 6, you might try the jmap tool
jmap -histo <pid>
it will print a histogram of your heap, including all loaded classes.
Using jps you can find out the pid
With the JRockit JVM you can start your application with -Xverbose:class=info to get information about class loading.

Categories