frida-trace
frida-trace is a tool for dynamically tracing function calls.
# Trace recv* and send* APIs in Safari, insert library names
# in logging
$ frida-trace --decorate -i "recv*" -i "send*" Safari
# Trace ObjC method calls in Safari
$ frida-trace -m "-[NSView drawRect:]" Safari
# Launch SnapChat on your iPhone and trace crypto API calls
$ frida-trace \
-U \
-f com.toyopagroup.picaboo \
-I "libcommonCrypto*"
# Launch YouTube on your Android device and trace Java methods
# with “certificate” in their signature (s), ignoring case (i)
# and only searching in user-defined classes (u)
$ frida-trace
-U \
-f com.google.android.youtube \
--runtime=v8 \
-j '*!*certificate*/isu'
# Trace all JNI functions in Samsung FaceService app on Android
$ frida-trace -U -i "Java_*" com.samsung.faceservice
# Trace a Windows process's calls to "mem*" functions in msvcrt.dll
$ frida-trace -p 1372 -i "msvcrt.dll!*mem*"
# Trace all functions matching "*open*" in the process except
# in msvcrt.dll
$ frida-trace -p 1372 -i "*open*" -x "msvcrt.dll!*open*"
# Trace an unexported function in libjpeg.so
$ frida-trace -p 1372 -a "libjpeg.so!0x4793c"
Full List of Options
--version show program's version number and exit
-h, --help show this help message and exit
-D ID, --device=ID connect to device with the given ID
-U, --usb connect to USB device
-R, --remote connect to remote frida-server
-H HOST, --host=HOST connect to remote frida-server on HOST
-f FILE, --file=FILE spawn FILE
-F, --attach-frontmost
attach to frontmost application
-n NAME, --attach-name=NAME
attach to NAME
-p PID, --attach-pid=PID
attach to PID
--stdio=inherit|pipe stdio behavior when spawning (defaults to “inherit”)
--runtime=qjs|v8 script runtime to use
--debug enable the Node.js compatible script debugger
--squelch-crash if enabled, will not dump crash report to console
-O FILE, --options-file=FILE
text file containing additional command line options
-I MODULE, --include-module=MODULE
include MODULE
-X MODULE, --exclude-module=MODULE
exclude MODULE
-i FUNCTION, --include=FUNCTION
include FUNCTION
-x FUNCTION, --exclude=FUNCTION
exclude FUNCTION
-a MODULE!OFFSET, --add=MODULE!OFFSET
add MODULE!OFFSET
-T, --include-imports
include program's imports
-t MODULE, --include-module-imports=MODULE
include MODULE imports
-m OBJC_METHOD, --include-objc-method=OBJC_METHOD
include OBJC_METHOD
-M OBJC_METHOD, --exclude-objc-method=OBJC_METHOD
exclude OBJC_METHOD
-j JAVA_METHOD, --include-java-method=JAVA_METHOD
include JAVA_METHOD
-J JAVA_METHOD, --exclude-java-method=JAVA_METHOD
exclude JAVA_METHOD
-s DEBUG_SYMBOL, --include-debug-symbol=DEBUG_SYMBOL
include DEBUG_SYMBOL
-q, --quiet do not format output messages
-d, --decorate add module name to generated onEnter log statement
-S PATH, --init-session=PATH
path to JavaScript file used to initialize the session
-P PARAMETERS_JSON, --parameters=PARAMETERS_JSON
parameters as JSON, exposed as a global named
'parameters'
-o OUTPUT, --output=OUTPUT
dump messages to file
-U, –usb: connect to USB device
This option tells frida-trace
to perform tracing on a remote device
connected via the host machine’s USB connection.
Example: You want to trace an application running on an Android device
from your host Windows machine. If you specify -U / --usb
,
frida-trace will perform the necessary work to transfer all data to
and from the remote device and trace accordingly.
Copy frida-server binary to remote device
When tracing a remote device, remember to copy the platform-appropriate frida-server binary to the remote device. Once copied, be sure to run the frida-server binary before beginning the tracing session.
For example, to trace a remote Android application, you would copy the 'frida-server-12.8.0-android-arm' binary to the Android's /data/local/tmp folder. Using adb shell, you would run the server in the background (e.g. frida-server-12.8.0-android-arm &).
-I, -X: include/exclude module
These options allow you to include or exclude all functions in a particular module (e.g., *.so, *.dll) in one, single option. The option expects a filename glob for matching one or more modules. Any module that matches the glob pattern will be either included or excluded in its entirety.
frida-trace
will generate a JavaScript handler file for each function matched
by the -I
option.
To exclude specific functions after including an entire module, see the -i
option.
-i, -x: include/exclude function (glob-based)
These options enable you to include or exclude matching functions according to your needs. This is a flexible option, allowing a granularity ranging from all functions in all modules down to a single function in a specific module.
frida-trace
will generate a JavaScript handler file for each function matched
by the -i
option.
The -i / -x
options differ syntactically from their uppercase counterparts
in that they accept any of the following forms (MODULE and FUNCTION are both
glob patterns):
- MODULE!FUNCTION - FUNCTION - !FUNCTION - MODULE!
Here are some examples and their descriptions:
Option Value | Description |
---|---|
-i "msvcrt.dll!*cpy*" | Matches all functions with 'cpy' in its name, ONLY in msvcrt.dll |
-i "*free*" | Matches all functions with 'free' in its name in ALL modules |
-i "!*free*" | Identical to -i "*free*" |
-i "gdi32.dll!" | Trace all functions in gdi32.dll |
frida-trace's working set and the order of inclusions and exclusions
frida-trace has an internal concept of a "working set", i.e., a set of "module:function" pairs whose handlers will be traced at runtime. The contents of the working set can be changed by an include / exclude command line option (-I / -X / -i / -x).
It is important to understand that the order of the include / exclude options is important. Each such option works on the current state of the working set, and different orderings of options can lead to different results. In other words, the include/exclude options are procedural (i.e., order counts) rather than simply declarative.
For example, suppose we want to trace all "str*" and "mem*" functions in all modules in a running process. In our example, these functions are found in three modules: ucrtbase.dll, ntdll.dll, and msvcrt.dll. To reduce the noise, however, we do not want to trace any functions found in the msvcrt.dll module.
We will describe three different option orders on the command line and show that they produce different results.
- -i "str*" -i "mem*" -X "msvcrt.dll"
- '-i "str*"'matches 80 functions in 3 modules, working set has 80 entries
- '-i "mem*"'matches 18 functions in 3 modules, working set has 98 entries
- '-X "msvcrt.dll"'removes the 28 "str" and 6 "mem" functions originating in msvcrt.dll, final working set has 64 entries.
- -i "str*" -X "msvcrt.dll" -i "mem*"
- '-i "str*"'matches 80 functions in 3 modules, working set has 80 entries
- '-X "msvcrt.dll"'removes the 28 "str" functions originating in msvcrt.dll, working set has 52 entries.
- '-i "mem*"'matches 18 functions in 3 modules including msvcrt.dll, final working set has 70 entries
- -X "msvcrt.dll" -i "str*" -i "mem*"
- '-X "msvcrt.dll"'tries to remove the 28 "str" and 6 "mem" functions originating in msvcrt.dll. Since the working set is empty, there is nothing to remove, working set has 0 entries.
- '-i "str*"'matches 80 functions in 3 modules, working set has 80 entries
- '-i "mem*"'matches 18 functions in 3 modules, final working set has 98 entries
-a: include function (offset-based)
This option enables tracing functions whose names are not exported by their modules (e.g., a static C/C++ function). This should not prevent you from tracing such functions, so long as you know that absolute offset of the function’s entry point.
Example: -a "libjpeg.so!0x4793c"
The option value provides both the full name of the module and the hex offset of the function entry point within the module.
frida-trace
will generate a JavaScript handler file for each function matched
by the -a
option.
-d, –decorate: add module name to log tracing
The --decorate
option is relevant when frida-trace
auto-generates JavaScript
handler scripts. By default, a handler’s onEnter
function looks like this:
onEnter: function (log, args, state) {
log('memcpy()');
},
The drawback is that, if the same function name exists in multiple modules,
it will be difficult to differentiate between function traces. The --decorate
function instructs frida-trace
to insert the module name in the default
onEnter
trace instruction:
onEnter: function (log, args, state) {
log('memcpy() [msvcrt.dll]');
},