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?
CodePudding user response:
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.