Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooking functions on JDK17 (HotSpot) crashes the instrumented application #333

Open
c8rri3r opened this issue Aug 16, 2024 · 1 comment
Open

Comments

@c8rri3r
Copy link

c8rri3r commented Aug 16, 2024

Summary

Hooking a function on JDK17 (HotSpot) causes the instrumented application to crash. Other features such as searching methods with Java.enumerateMethods(query) work as expected as far as I can tell. This happens each and every time a Java function is hooked. Given this sample application:

public class App 
{
    public static void main( String[] args )
    {
        System.out.println("[*] Checking status of someTest()...");
        try {
            while(true) {
                boolean result = someTest();
                if(result) {
                    System.out.println("[*] Congrats, result has been changed!");
                }
                TimeUnit.SECONDS.sleep(10);
            }
        } catch (InterruptedException e) { }
    }
    public static boolean someTest() {
        return false;
    }
}

Hooking the someTest() function with this instrumentation code will cause the crash:

Java.perform(function () {
    console.log("Is Java Available: " + Java.available)
    var MyClass = Java.use('com.frida.App');

    // Hook the "someTest" function
    MyClass.someTest.implementation = function () {
        console.log('someTest() function called');
        return true;
    };
});

The error message (trimmed for brevity) doesn't immediately indicate where the issue is.

└─$ $JAVA_HOME/bin/java -jar target/frida-java-demo-1.0-SNAPSHOT-jar-with-dependencies.jar
[*] Checking status of someTest()...
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000000000000, pid=4713, tid=4714
#
# JRE version: OpenJDK Runtime Environment Temurin-17.0.12+7 (17.0.12+7) (build 17.0.12+7)
# Java VM: OpenJDK 64-Bit Server VM Temurin-17.0.12+7 (17.0.12+7, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# j  com.frida.App.main([Ljava/lang/String;)V+8
...

The Frida console provides a more descriptive error message:

Is Java Available: true
Error: Unable to make thread_from_jni_environment() helper for the current architecture
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/jvm.js:232)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/jvm.js:276)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:12)
    at j (frida/node_modules/frida-java-bridge/lib/jvm.js:291)

This is despite the fact that Frida indicates the JVM should be supported, the Java.api command was trimmed for brevity.

[Local::PID::25154 ]-> Java.available
true
[Local::PID::25154 ]-> Java.api
{
    "flavor": "jvm",
    "jvmti": {
        "handle": "0x7efb500023e0",
        "vm": {
            "handle": "0x7efc279674e0"
        },
        "vtable": "0x7efc27970640"
    },
    "version": 17,
    "versionS": "17.0.12+7",
    "vm": "0x7efc279674e0",
}

This exact same application and instrumentation code works perfectly fine on JDK11 and JDK16 though.

Multiple versions of JDK17 have been used from multiple vendors - Azul, Oracle JDK and Adoptium - and each one leads to a crash.

Test Environment

  • Frida 16.4.8 (installed via Python Pip)
  • Adoptium JDK17
  • Kali Linux under WSL x64 and Ubuntu 22.02 x64

Steps to Reproduce

I created a GitHub repo with the sample code and instrumentation script mentioned above, alongside build and reproduction steps here.

Related Issues

It's difficult to tell by the information provided in the ticket, but these other issues may be related:

@c8rri3r
Copy link
Author

c8rri3r commented Nov 9, 2024

Update: Some progress made. The Unable to make thread_from_jni_environment() helper for the current architecture error message is thrown because an offset between the findClassImpl function entry point and a lea instruction can't be found using the hardcoded limit of 10.

I set that value to 12, and while it isn't throwing that error message anymore, the instrumented application still crashes.

java -jar target/frida-java-demo-1.0-SNAPSHOT-jar-with-dependencies.jar
[*] Checking status of someTest()...
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000000000000, pid=67514, tid=67515
#
# JRE version: OpenJDK Runtime Environment (17.0.11+9) (build 17.0.11+9-Debian-1)
# Java VM: OpenJDK 64-Bit Server VM (17.0.11+9-Debian-1, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# j  com.frida.App.main([Ljava/lang/String;)V+8
#
# Core dump will be written. Default location: Core dumps may be processed with "/wsl-capture-crash %t %E %p %s" (or dumping to /home/kurt/repos/c8rri3r/frida-java-demo/core.67514)
#
# An error report file with more information is saved as:
# /home/kurt/repos/c8rri3r/frida-java-demo/hs_err_pid67514.log
#
# If you would like to submit a bug report, please visit:
#   https://bugs.debian.org/openjdk-17
#
Aborted (core dumped)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant