So I saw some code in passing that referenced com.sun.tools.javac.Main, and I got curious, can I run the java process AS A THREAD inside my process? Other executables? I've loaded other java programs from ClassLoaders and injected them with Java Agents, but now I'm curious, could one load an EXE inside java?
I assume it's possible with memory reading/writing, but there aught to be a safer way. (If not, where would one find some specification?)
Extendings the Answer by Banthar:
Every process on a system has his own adress space.:
Threads are so called light - weighted processes which are related to the parent - process they were started from.:
Within assembly code or C / C++ where you can directly access hardware adresses :
you could break into the adress space of another process perhaps, though :
usually the system which is responsible for creating them will try to avoid such things.:
AFAIK there is no direct access to a certain memory region not allocated by the :
process trying to access it. IPC (inter process communication) is a good starting point to find out more about how to connect processes
So no access to other processes not started by your process.:
Still you can start other java processes (threads are processes, too):
or execute commandlines like 'java -jar xx.jar'.:
:
And of course nothing stops you from doing things such as calling a method on an object which is declared pulic such as static public void main within your classpath.
This is not possible in general. Executable files have to be loaded at specific address. This address is already occupied by java executable. In general one process can execute only one executable.
You can invoke other Java programs. Just add the jar to classpath and invoke main() method. That's probably how you saw com.sun.tools.javac.Main invoked.
If you have native shared library you can load it into java process with System.loadLibrary.
If you want to execute non-shared, native executable, the only way is to create new process.
You can compile classes in your code, if that is what your asking? See method getClass in https://github.com/tgkprog/jCompile/blob/master/JCompService/src/main/java/s2n/jComp/services/impl/DefaultClazzCompilerService.java
Can see other examples on the internet too. Javac compiler is just another written in Java tool since ages back. I'm guessing the next version of Java gets compiled by javac written in the previous version :) Sounds strange but fine if you think about what a java compiler does.
So you could call it as an API as above or make a process and call it (so its not part of your JVM just that your JVM invoked it). Not sure about calling the main method in a thread, i dont see why they would stop you. But it would not be heavy weight process, just an API call to the main mehtod if the class like this:
public static void main(String[] args) throws Exception {
com.sun.tools.javac.Main.main(args);
}
Similar : No com.sun.tools.javac in JDK7 , how to set classpath for com.sun.tools.javac.Main.compile() function?
Related
I have an exe that is starting a JVM and loading java classes into memory. I was successfully able to dump these classes with a -javaagent from the running JVM by attaching it to the process and retransforming the classes. Now I am trying to modify the classes as they are loaded. My issue is that my java agent cannot handle premain as I cannot add command line options without modifying the loader executable, which is packed with Themida. By the time my java agent has been attached, the classes to be modified have already been loaded. I was thinking I could use the JVMTI class load hook to capture the class file and transfer it to a separate JVM and modify it with javassist or ASM then return it to to the original JVM via the JVMTI Agent. If I use JVMTI I'd need to load my agent with -agentlib, which brings me back to the problem of having to modify the executable. Can you think of any other ways I could preform this modification? Could I modify the JVM itself to load a java agent always on startup? Is there some other way to force the JVM to always load a java agent? To see if the software was calling any sort of exe in the JRE, I removed all of the exes from j64\bin. The program still loaded without error. When I removed java.dll, the program failed to load entirely, while the program still loads but throws an error when other dlls are removed. If I found which JRE dll was receiving the command line args from the loader, could I implement a dll proxy? Is java.dll the dll I'd want to proxy?
I can't really speak to the idea of proxying the jvm.dll. Sounds like very delicate and error-prone work. Don't know much about Themida either, but from some cursory browsing, you would be deliberately breaking Themida's security intent.
Without the ability to change JVM command line parameters, you don't really have a lot of options. (Rhetorical: What do you do if you need to change heap sizes etc. ?)
However, if you can append and additional execution after the JVM launches, you could use a JVM Attach execution to connect to the running JVM and and load your JVMTI agent via loadAgent. It's a real race-condition threat since your app could very well be under-way by the time you get your instrumentation installed, but as I said, your options are limited.
I would look into how you can use Themida to re-package the application and introduce a proper javaagent command line parameter. Plus, if you don't, you may find that Themida may detect your workarounds and disable them, or disable the JVM altogether.
I would like to know what happens internally at the machine level when I try to run a java compiled file using the command "java class_name" If you know how the classes loaded into JVM will start executing with the help of Program Counter (PC) or any other pointers to the memory please explain it.
Like,
what loadClass() will do and its internal calls to findClass() and other methods. In that detail I am expecting the answer to be.
From Java doc
The java command starts a Java application. It does this by starting
a Java runtime environment, loading a specified class, and calling
that class's main method.
Read more.
Does the JVM read a .jar file from disk more than once for a long running program or is it read only once and the whole image is in memory until the JVM terminates?
I was running a job that took about 26 hours and near the end there was an undefined object exception (NoClassDefFoundError) that I think might be due to the fact that I was making code changes and re-exported the .jar from the development environment (that is, I created a new one on the disk at the same place the old one was) while the application was running.
You may want to run your code with the flag -verbose:class and you will see that class loading is extremely lazy. The JVM loads just the classes it absolutely must have to go on. If, on the end of your program, you're doing something that requires a class that was not absolutly needed before, it'll get loaded just then.
This explains very well the error you got, and you should notice that you shouldn't replace a jar (or class) file that is running, exactly for that reason.
No, JVM reads from jar every time when it needs to load a new class.
If you are using import and normal use of classes, than only once per class.
If you play with class loaders, reflections than you can make extra reads and "not planed behavior" - it means many times per class.
Is there a way to reconstruct the command line arguments passed to Java within a Java program, including the JVM options and classpath option?
I have a Java program that needs to restart the JVM and manipulate its bootclasspath (i.e. trying to override some system classes). I use the libc system method to invoke the new JVM.
I'm open for better approaches, but Java agents isn't an option.
Why not use a file that has these properties just like the Eclipse ini file and NetBeans conf files. That way you just read these properties and spawn the new Java process with these properties.
Back to your question, this previous answer should do
I agree that futzing with the bootclasspath is generally a poor idea. But...
Grab the code for "java.c" - the C program that compiles down to java.exe. You'll find that it just uses the JNI Invocation API to construct a JVM and call the main method. You could modify and re-compile this to look for particular exit codes, etc. and loop around and re-launch the JVM if required.
Alternatively, Eclipse does this (or at least used to), but having one Java program construct the command line (from a props file, etc.) and launch a sub-process. Again, it hooked the sub-process exit code and used that to decide whether or not to re-launch a new sub-process.
Err... modifying a whole core java class at runtime is a very very bad idea.
Whats wrong with subclassing here? Are you trying to modify an external library, add functionality, or be lazy?
I need to invoke .jar file in separate JVM from another java application, and it very CPU-consuming, so it should run with background priority in order not to affect the rest of the system. Is there any cross-platform method to do this?
The simple answer is that there is no portable way to change the priority of a Process in Java. (Threads - yes, Processes - no.)
If your Java application needs to start a new JVM to run the CPU intensive application, then the chances are that it is already not entirely portable. For example, you will typically need to give the pathname of the java command (or equivalent), a -cp argument (or equivalent), system specific JVM options, and so on.
So, assuming that the command to launch the JVM is already non-portable, it should hardly matter if you replace the command with a wrapper script that does OS-specific things to change the priority of the launched process. (For example, for UNIX or Linux you could simply use nice to launch the JVM.)
I don't know the way to set the priority for an external process. Thread however has a setPriority method, so if you control the target application, you could perhaps add a switch, telling the application to set its own priority to minimum:
theThread.setPriority(Thread.MIN_PRIORITY);
If it still affects the system, I suggest you interleave some short sleeping to offload the cpu.
Another option:
If you put the target .jar in the classpath of the "initiating" application, you can simply invoke the main-method of the jar-file in a newly created thread, and then set the priority using the above method. (This should work even if you don't control the source-code of the target jar file.)