0

In my quest to understand the Frida magic regarding re-implementing methods, I am having trouble running JDB in parallel with Frida on a simple Java application.

The Frida script is as follows, only adding logs when passing through the method Main.a :

Java.perform(() => {
    Java.use("Main").a.overload("java.lang.String").implementation = function(s) {
        console.log('hooked!');
        this.a(s);
    };

})

This alone works perfectly. However, when I try to attach JDB to the simple Java program, JDB hangs, whereas when the main program is not instrumented with Frida, I can attach JDB easily and it works flawlessly.

Do you know what migth cause this behavior ? Any workaround ?

NB : answering the above interrogations will help me towards understanding the Frida magic regarding re-implementing Java methods, but if you know precisely how Frida does that do not hesitate to reach out.
As far as I know :

  • Frida compiles my javascript code into C
  • it injects it in frida-agent.so
  • it replaces the function pointer of the original method with a pointer towards the native code in frida-agent.so ?? This is the part I do not understand. I assume it works like this (opposed to adding a call to a subroutine in frida-agent.so at the first line of Main.a) because I inspected the bytecode of Main.a before and after reimplementation, and it stays exactly the same.
  • When I call this.a in the new implementation, it calls back to the original location of Main.a

I do not understand why that would break the debugging interface.

AntoineG
  • 93
  • 7
  • 1
    Effectively Frida is a debugger just with an unusual interface and you can't connect two debuggers at the same time. And Frida does not compile your JS code to C, it injects a JS-engine into the app and executes your JS code there. How Frida works in detail for Android I don't know. My assumption is that there is a central pointer to `Main.a` method in some table in memory and that pointer gets redirected by Frida. – Robert Oct 05 '21 at 14:55
  • Thank you very much ! But then, why is it that I can run frida scripts and still debug with JDB, and it is only when I try and re-implement a method that JDB breaks ? For instance, I can set a breakpoint on `Main.a` in JDB and then inject a Frida script which calls `Main.a`, and the debugging works as expected. – AntoineG Oct 05 '21 at 15:04
  • 1
    Right we are talking about JDB, not a real native debugger. Frida operates as a native debugger like gdb. JDB is as far as I know a separate interface on a higher level. If it only happens if you hook a method that the cause should be the manipulations Frida makes to the process which let JDB to fail. BTW: Android does not (or very seldom) execute byte code at all (assuming you don't use a device from Android stone age 4.4). Because of ART Android only executes native ARM[64] code that was generated from DEX byte code. – Robert Oct 05 '21 at 15:45
  • I actually use "real" Java (on a PC) with the Hotspot JVM, supported by Frida since June 2020. And my VM is set-up so that it only uses the bytecode interpreter (`java -Xint`). – AntoineG Oct 05 '21 at 16:21
  • 1
    Sorry, I missed that. Most people using Frida with Java are on Android. No matter expect for the DEX and ART part the rest should be still valid. – Robert Oct 06 '21 at 07:56

0 Answers0