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.
Related
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.
Is there a way to modify .class files in order to add Java annotations to certain methods? Basically I want to traverse methods of each class file in a jar file and annotate certain ones. Note that this is not at run-time while using the jar file. Rather, after I'm done I want to have modified class files with the annotations.
I do have access to the source code, so if there's an automatic source code modifier, that would work as well...
I'm assuming I'll need a tool such as Javassist or ASM. If so, which one should I use and how would I go about it?
Actually, this is a classic use case for AspectJ:
declare #method : public * BankAccount+.*(..) : #Secured(role="supervisor")
While I will grant you that direct byte code manipulation is more powerful, AspectJ is much more user-friendly, and it immediately gives you compiler warnings when you are doing something wrong.
Also, if you use Load Time Weaving, you can leave the original library jar unchanged, because the weaving happens at class-load time.
Reference:
Declare Annotation
AspectJ in Action (book)
Googling for an hour or so turned this article up which seems to completely answer my question: use ASM. To write class files using the changed bytecode, use ClassWriter.
Well, time to get to work then, I guess. :)
I'm writing a java framework, for a class file, sample.class, it generates a proxy file sample_proxy.class. When sample.testMethod() is called, it excutes sample_proxy.class. I already make an eclipse plugin to make the breakpoint work,
If I start from Main.java, and make a breakpoint in sample.testMethod(), the stack below looks like: Main.main-->sample.proxy_method-->sample_proxy.testMethod.
Is there any way to ingore the proxy to show like: Main.main-->sample.testMethod?
What you want to do is possible but a bit more complicated. First of all there is no way to change the StackTrace of a running program. So Thread.currentThread().getStackTrace() is not the way to go.
I'm writing a java framework, for a class file, sample.class, it
generates a proxy file sample_proxy.class.
When you do that, you have to inline the called method, instead of simply calling it. That is non-trivial technique also being used by ProGuard. You will find that it does different kinds of inlining. Most interested you could be in the functionality of "inlining short methods".
I suggest you copy it from the code there. I good point to start would be http://sourceforge.net/p/proguard/code/ci/default/tree/src/proguard/optimize/Optimizer.java#l156
But be aware that this requires fundamental knowledge about the JVM itself, so there won't be a simple code snippet that does what you want, in the context you expect.
I hope it helps.
I need to manually add a method call to a class file without decompiling and recompiling the code because It depends on thousands of other classes and I don't wan't have to do more than is nessescary. I know java but not how class files are made.
Any help is appreciated.
EDIT:
I am not the owner of the source and I need this to work on any computer, which means I cannot redistribute the sources and have them compiled realtime while my patcher is working.
You have the source code, and you have all other classes compiled. So you can recompile just that source file, passing compiled classes as parameters to java compiler with -classpath option.
You should use ASM or Javaassist to manipulate the bytecode. ASM is a little bit more complex and requires you to understand more about the JVM, but it's faster. Javaassist doesn't require you to know much about the JVM's internals.
However, I don't see why you can't just recompile that single sourcefile? If you only need to add this method once, it's very inefficient to learn ASM or Javaassist.
How about subclassing? Then you don't need to touch the sources.
So if you have the source code and want to add some methods into only one class. Then you don't have to worry about other classes even they are dependent on your current modified class. Re-compiling a file doesn't affect other classes. Since the output will be produced at run-time.
If your class is not declared final and the method you are interested is not final, you can extend the class and override just that method.
Just change the source code, recompile ! Everything will work fine. Subclassing won't work .Because Already existing classes won't know about the new subclass until you change their code to use the new subclass instead of old superclass.
For manual editing of classfiles, I'd recommend Krakatau. (Disclosure, I wrote it). It lets you disassemble a classfile, edit it, and reassemble. There are other assemblers out there, but AFAIK, Krakatau is the only one that supports all the weird edge cases in the classfile format.
The main caveat is that Krakatau by default does not preserve certain optional debugging attributes (specifically LineNumberTable, LocalVariableTable, and LocalVariableTypeTable), since there is no simple way to represent them in a human editable format, and failing to edit them when the bytecode changes will result in a verification error. Most likely you don't actually need this though so it shouldn't matter.
The other caveat of course is that you have to understand bytecode. But if you don't, you won't be able to manually edit classfiles anyway.
I got it now! I Created fake source files with the same names/methods but didn't add anything else except for class and method names. That way I only needed to pack the ones that are directly linked to my Class file. But now compiling takes a few milliseconds whereas it used to take around 124s, Lol. Works great!
I have a scenario where I have code written against version 1 of a library but I want to ship version 2 of the library instead. The code has shipped and is therefore not changeable. I'm concerned that it might try to access classes or members of the library that existed in v1 but have been removed in v2.
I figured it would be possible to write a tool to do a simple check to see if the code will link against the newer version of the library. I appreciate that the code may still be very broken even if the code links. I am thinking about this from the other side - if the code won't link then I can be sure there is a problem.
As far as I can see, I need to run through the bytecode checking for references, method calls and field accesses to library classes then use reflection to check whether the class/member exists.
I have three-fold question:
(1) Does such a tool exist already?
(2) I have a niggling feeling it is much more complicated that I imagine and that I have missed something major - is that the case?
(3) Do you know of a handy library that would allow me to inspect the bytecode such that I can find the method calls, references etc.?
Thanks!
I think that Clirr - a binary compatibility checker - can help here:
Clirr is a tool that checks Java libraries for binary and source compatibility with older releases. Basically you give it two sets of jar files and Clirr dumps out a list of changes in the public api. The Clirr Ant task can be configured to break the build if it detects incompatible api changes. In a continuous integration process Clirr can automatically prevent accidental introduction of binary or source compatibility problems.
Changing the library in your IDE will result in all possible compile-time errors.
You don't need anything else, unless your code uses another library, which in turn uses the updated library.
Be especially wary of Spring configuration files. Class names are configured as text and don't show up as missing until runtime.
If you have access to the source code, you could just compile source against the new library. If it doesn't compile, you have definitely a problem. If it compiles you may still have a problem if the program uses reflection, some kind of IoC stuff like Spring etc.
If you have unit tests, then you may have a better change catch any linking errors.
If you have only have a .class file of the program, then I don't know any tools that would help besides decomplining class file to source and compiling source again against the new library, but that doesn't sound too healthy.
The checks you mentioned are done by the JVM/Java class loader, see e.g. Linking of Classes and Interfaces.
So "attempting to link" can be simply achieved by trying to run the application. Of course you could hoist the checks to run them yourself on your collection of .class/.jar files. I guess a bunch of 3rd party byte code manipulators like BCEL will also do similar checks for you.
I notice that you mention reflection in the tags. If you load classes/invoke methods through reflection, there's no way to analyse this in general.
Good luck!