Frida is very commonly used to instrument Android applications written in Java and compiled to Dalvik bytecode. It is a less well known fact that Frida gained support for instrumenting Java programs running on the HotSpot JVM in a recent version which should work on most JVM versions running on Linux and macOS.
Attempting to instrument a program using the default JVM shipped with most Linux distributions should result in the following error:
[Local::PID::8297]-> Java.available
Error: Java API only partially available; please file a bug. Missing: _ZN6Method4sizeEb, _ZN6Method19set_native_functionEPhb, _ZN6Method21clear_native_functionEv, _ZN6Method24restore_unshareable_infoEP6Thread, _ZN6Method10jmethod_idEv, _ZN20ClassLoaderDataGraph10classes_doEP12KlassClosure, _ZN10JavaThread27thread_from_jni_environmentEP7JNIEnv_, _ZN8VMThread7executeEP12VM_Operation, _ZN11OopMapCache22flush_obsolete_entriesEv, _ZN14NMethodSweeper16sweep_code_cacheEv, _ZTV18VM_RedefineClasses, _ZN18VM_RedefineClasses4doitEv, _ZN18VM_RedefineClasses13doit_prologueEv, _ZN18VM_RedefineClasses13doit_epilogueEv, _ZNK18VM_RedefineClasses26allow_nested_vm_operationsEv, _ZN19Abstract_VM_Version19jre_release_versionEv, _ZN14NMethodSweeper11_traversalsE, _ZN14NMethodSweeper13_should_sweepE
at P (frida/node_modules/frida-java-bridge/lib/jvm.js:143)
at C (frida/node_modules/frida-java-bridge/lib/jvm.js:12)
at _tryInitialize (frida/node_modules/frida-java-bridge/index.js:17)
at v (frida/node_modules/frida-java-bridge/index.js:9)
at <anonymous> (frida/node_modules/frida-java-bridge/index.js:312)
at call (native)
at o (/_java.js)
at <anonymous> (/_java.js)
at <anonymous> (frida/runtime/java.js:1)
at call (native)
at o (/_java.js)
at r (/_java.js)
at <eval> (frida/runtime/java.js:3)
at _loadJava (native)
at get (frida/runtime/core.js:114)
at <anonymous> (<input>:22)
This is because Frida requires the JVM contain symbols in order to locate specific functions required for instrumentation. The default JVM shipped with most Linux distributions have symbols stripped.
$ nm /usr/lib/jvm/java-1.11.0-openjdk-amd64/lib/server/libjvm.so
nm: /usr/lib/jvm/java-1.11.0-openjdk-amd64/lib/server/libjvm.so: no symbols
The easiest way to obtain a JVM with symbols is by downloading a pre-built binary from the AdoptOpenJDK project. By configuring the target program to use a JVM with symbols, Frida can then be used for instrumentation.
____
/ _ | Frida 14.2.3 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://www.frida.re/docs/home/
[Local::PID::10925]-> Java.available
true
The full power of Frida can then be leveraged for reverse engineering and analysis of Java programs.