MASTG-TECH-0034: Native Code Tracing

Native methods tracing can be performed with relative ease compared to Java method tracing. frida-trace is a CLI tool for dynamically tracing function calls. It makes tracing native functions trivial and can be very useful for collecting information about an application.

In order to use frida-trace, a Frida server should be running on the device. An example for tracing libc's open function using frida-trace is demonstrated below, where -U connects to the USB device and -i specifies the function to be included in the trace.

frida-trace -U -i "open" com.android.chrome

Note how, by default, only the arguments passed to the function are shown, but not the return values. Under the hood, frida-trace generates one little JavaScript handler file per matched function in the auto-generated __handlers__ folder, which Frida then injects into the process. You can edit these files for more advanced usage such as obtaining the return value of the functions, their input parameters, accessing the memory, etc. Check Frida's JavaScript API for more details.

In this case, the generated script which traces all calls to the open function in libc.so is located in __handlers__/libc.so/open.js, it looks as follows:

{
  onEnter: function (log, args, state) {
    log('open(' +
      'path="' + args[0].readUtf8String() + '"' +
      ', oflag=' + args[1] +
    ')');
  },


  onLeave: function (log, retval, state) {
      log('\t return: ' + retval);      \\ edited
  }
}

In the above script, onEnter takes care of logging the calls to this function and its two input parameters in the right format. You can edit the onLeave event to print the return values as shown above.

Note that libc is a well-known library, Frida is able to derive the input parameters of its open function and automatically log them correctly. But this won't be the case for other libraries or for Android Kotlin/Java code. In that case, you may want to obtain the signatures of the functions you're interested in by referring to Android Developers documentation or by reverse engineer the app first.

Another thing to notice in the output above is that it's colorized. An application can have multiple threads running, and each thread can call the open function independently. By using such a color scheme, the output can be easily visually segregated for each thread.

frida-trace is a very versatile tool and there are multiple configuration options available such as:

  • Including -I and excluding -X entire modules.
  • Tracing all JNI functions in an Android application using -i "Java_*" (note the use of a glob * to match all possible functions starting with "Java_").
  • Tracing functions by address when no function name symbols are available (stripped binaries), e.g. -a "libjpeg.so!0x4793c".
frida-trace -U -i "Java_*" com.android.chrome

Many binaries are stripped and don't have function name symbols available with them. In such cases, a function can be traced using its address as well.

frida-trace -p 1372 -a "libjpeg.so!0x4793c"