Frida - Dynamic Instrumentation Toolkit For Developers, Reverse-Engineers, And Security Researchers
Frida is a dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.
It is
- Scriptable: It lets you inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
- Portable: Works on Windows, macOS, GNU/Linux, iOS, Android, and QNX. Install the Node.js bindings from npm, grab a Python package from PyPI, or use Frida through its Swift bindings, .NET bindings, Qt/Qml bindings, or C API.
- Free: Frida is a free software.
- Battle-tested: It is very popular among security researchers and pentesters.
So, in other words, it's Greasemonkey for native apps.
Frida also provides you some simple tools built on top of the Frida API. These can be used as-is, tweaked to your needs, or serve as examples of how to use the API.
Why You Need Frida In Your Arsenal (Here are some use-cases):
- There's this new hot app everybody's so excited about, but it's only available for iOS and you'd love to interop with it. You realize it's relying on encrypted network protocols and tools like Wireshark just won't cut it. You pick up Frida and use it for API tracing.
- You're building a desktop app which has been deployed at a customer's site. There's a problem but the built-in logging code just isn't enough. You need to send your customer a custom build with lots of expensive logging code. Then you realize you could just use Frida and build an application- specific tool that will add all the diagnostics you need, and in just a few lines of Python. No need to send the customer a new custom build - you just send the tool which will work on many versions of your app.
- You'd like to build a Wireshark on steroids with support for sniffing encrypted protocols. It could even manipulate function calls to fake network conditions that would otherwise require you to set up a test lab.
- Your in-house app could use some black-box tests without polluting your production code with logic only required for exotic testing.
Tools:
- Frida CLI: Frida CLI is a REPL interface that aims to emulate a lot of the nice features of IPython (or Cycript), which tries to get you closer to your code for rapid prototyping and easy debugging.
# Connect Frida to an iPad over USB and start debugging Safari
$ frida -U Safari
_____
(_____)
| | Frida 4.0.0 - A world-class dynamic
| | instrumentation framework
|`-'|
| | Commands:
| | help -> Displays the help system
| | object? -> Display information about 'object'
| | exit/quit -> Exit
| |
| | More info at http://www.frida.re/docs/home/
`._.'
[USB::iPad 4::Safari]->
An example session:
# Connect Frida to a locally-running Calculator.app
$ frida Calculator
_____
(_____)
| | Frida 4.0.0 - A world-class dynamic
| | instrumentation framework
|`-'|
| | Commands:
| | help -> Displays the help system
| | object? -> Display information about 'object'
| | exit/quit -> Exit
| |
| | More info at http://www.frida.re/docs/home/
`._.'
# Look at the local variables/context
[Local::ProcName::Calculator]->
Backtracer Process
CpuContext Proxy
Dalvik Socket
DebugSymbol Stalker
File Thread
Frida WeakRef
Instruction clearInterval
Interceptor clearTimeout
Memory console
MemoryAccessMonitor gc
Module ptr
NULL recv
NativeCallback send
NativeFunction setInterval
NativePointer setTimeout
ObjC
# Look at things exposed through the ObjC interface
[Local::ProcName::Calculator]-> ObjC.
Object implement selector
available mainQueue selectorAsString
classes schedule
# List the first 10 classes (there are a lot of them!)
[Local::...::Calculator]-> Object.keys(ObjC.classes).slice(0, 10)
[
"NSDrawer",
"GEOPDETAFilter",
"NSDeserializer",
"CBMutableCharacteristic",
"NSOrthographyCheckingResult",
"DDVariable",
"GEOVoltaireLocationShiftProvider",
"LSDocumentProxy",
"NSPreferencesModule",
"CIQRCodeGenerator"
]
Loading a script:
# Connect Frida to a locally-running Calculator.app and load calc.js
$ frida Calculator -l calc.js
_____
(_____)
| | Frida 4.0.0 - A world-class dynamic
| | instrumentation framework
|`-'|
| | Commands:
| | help -> Displays the help system
| | object? -> Display information about 'object'
| | exit/quit -> Exit
| |
| | More info at http://www.frida.re/docs/home/
`._.'
# The code in calc.js has now been loaded and executed
[Local::ProcName::Calculator]->
# Reload it from file at any time
[Local::ProcName::Calculator]-> %reload
[Local::ProcName::Calculator]->
Enable the Node.js compatible debugger:
# Connect Frida to a locally-running Calculator.app
# and load calc.js with the debugger enabled
$ frida Calculator -l calc.js --debug
_____
(_____)
| | Frida 4.0.0 - A world-class dynamic
| | instrumentation framework
|`-'|
| | Commands:
| | help -> Displays the help system
| | object? -> Display information about 'object'
| | exit/quit -> Exit
| |
| | More info at http://www.frida.re/docs/home/
`._.'
Debugger listening on port 5858
# We can now run node-inspector and start debugging calc.js
[Local::ProcName::Calculator]->
- frida-ps: This is a command-line tool for listing processes, which is very useful when interacting with a remote system. (You can acquire device id from frida-ls-devices tool)
# Connect Frida to an iPad over USB and list running processes
$ frida-ps -U
# List running applications
$ frida-ps -Ua
# List installed applications
$ frida-ps -Uai
# Connect Frida to the specific device
$ frida-ps -D 0216027d1d6d3a03
- 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*"
# 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:
-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.
Note: 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:
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.
--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=duk|v8 script runtime to use (defaults to "duk")
--debug enable the Node.js compatible script debugger
-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
-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
-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.
Note: 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:
-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 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]');
},
- frida-discover: frida-discover is a tool for discovering internal functions in a program, which can then be traced by using frida-trace.
- frida-ls-devices: This is a command-line tool for listing attached devices, which is very useful when interacting with multiple devices.
# Connect Frida to an iPad over USB and list running processes
$ frida-ls-devices
# example output
Id Type Name
---------------------------------------- ------ ----------------
local local Local System
0216027d1d6d3a03 tether Samsung SM-G920F
1d07b5f6a7a72552aca8ab0e6b706f3f3958f63e tether iOS Device
tcp remote Local TCP
- frida-kill: This is a command-line tool for killing processes. You can acquire PIDs from frida-ps tool.
$ frida-kill -D
# List active applications
$ frida-ps -D 1d07b5f6a7a72552aca8ab0e6b706f3f3958f63e -a
PID Name Identifier
---- ------------------ -----------------------------------------------------
4433 Camera com.apple.camera
4001 Cydia com.saurik.Cydia
4997 Filza com.tigisoftware.Filza
4130 IPA Installer com.slugrail.ipainstaller
3992 Mail com.apple.mobilemail
4888 Maps com.apple.Maps
6494 Messages com.apple.MobileSMS
5029 Safari com.apple.mobilesafari
4121 Settings com.apple.Preferences
# Connect Frida to the device and kill running process
$ frida-kill -D 1d07b5f6a7a72552aca8ab0e6b706f3f3958f63e 5029
# Check if process has been killed
$ frida-ps -D 1d07b5f6a7a72552aca8ab0e6b706f3f3958f63e -a
PID Name Identifier
---- ------------------ -----------------------------------------------------
4433 Camera com.apple.camera
4001 Cydia com.saurik.Cydia
4997 Filza com.tigisoftware.Filza
4130 IPA Installer com.slugrail.ipainstaller
3992 Mail com.apple.mobilemail
4888 Maps com.apple.Maps
6494 Messages com.apple.MobileSMS
4121 Settings com.apple.Preferences
How To Install Frida
Requirements for Frida’s CLI tools:
- Python – latest 3.x is highly recommended
- Windows, macOS, or GNU/Linux
The best way to install Frida’s CLI tools is via PyPI:
$ pip install frida-tools
Install manually:Download binaries and install it.
Testing Your Installation
Start a process we can inject into:$ cat
Just let it sit and wait for input. On Windows you might want to use notepad.exe.
Note that this example won't work on macOS El Capitan and later, as it rejects such attempts for system binaries. However, if you copy the cat binary to e.g., /tmp/cat then run that instead the example should work:
$ cp /bin/cat /tmp/cat
$ /tmp/cat
In another terminal, make a file example.py with the following contents:
If you are on GNU/Linux, issue:
Most of the time, however, you want to spawn an existing program, attach to a running program, or hijack one as it’s being spawned, and then run your instrumentation logic inside of it. As this is such a common way to use Frida, it is what most of our documentation focuses on. This functionality is provided by frida-core, which acts as a logistics layer that packages up GumJS into a shared library that it injects into existing software, and provides a two-way communication channel for talking to your scripts, if needed, and later unload them. Beside this core functionality, frida-core also lets you enumerate installed apps, running processes, and connected devices. The connected devices are typically iOS and Android devices where frida-server is running. That component is essentially just a daemon that exposes frida-core over TCP, listening on localhost:27042 by default.
import frida
def on_message(message, data):
print("[on_message] message:", message, "data:", data)
session = frida.attach("cat")
script = session.create_script("""
rpc.exports.enumerateModules = function () {
return Process.enumerateModules();
};
""")
script.on("message", on_message)
script.load()
print([m["name"] for m in script.exports.enumerate_modules()])
If you are on GNU/Linux, issue:
$ sudo sysctl kernel.yama.ptrace_scope=0
to enable ptracing non-child processes. At this point, we are ready to take Frida for a spin! Run the example.py script and watch the magic: $ python example.py
The output should be something similar to this (depending on your platform and library versions):[u'cat', …, u'ld-2.15.so']
Modes of Operation
Frida provides dynamic instrumentation through its powerful instrumentation core Gum, which is written in C. Because such instrumentation logic is prone to change, you usually want to write it in a scripting language so you get a short feedback loop while developing and maintaining it. This is where GumJS comes into play. With just a few lines of C you can run a piece of JavaScript inside a runtime that has full access to Gum’s APIs, allowing you to hook functions, enumerate loaded libraries, their imported and exported functions, read and write memory, scan memory for patterns, etc. - Injected
Most of the time, however, you want to spawn an existing program, attach to a running program, or hijack one as it’s being spawned, and then run your instrumentation logic inside of it. As this is such a common way to use Frida, it is what most of our documentation focuses on. This functionality is provided by frida-core, which acts as a logistics layer that packages up GumJS into a shared library that it injects into existing software, and provides a two-way communication channel for talking to your scripts, if needed, and later unload them. Beside this core functionality, frida-core also lets you enumerate installed apps, running processes, and connected devices. The connected devices are typically iOS and Android devices where frida-server is running. That component is essentially just a daemon that exposes frida-core over TCP, listening on localhost:27042 by default. - Embedded
It is sometimes not possible to use Frida in Injected mode, for example on jailed iOS and Android systems. For such cases we provide you with frida-gadget, a shared library that you’re supposed to embed inside the program that you want to instrument. By simply loading the library it will allow you to interact with it remotely, using existing Frida-based tools like frida-trace. It also supports a fully autonomous approach where it can run scripts off the filesystem without any outside communication.
- Preloaded
This is where frida-gadget, the shared library. It is really useful when configured to run autonomously by loading a script from the filesystem.
Source: www.effecthacking.com
Frida - Dynamic Instrumentation Toolkit For Developers, Reverse-Engineers, And Security Researchers
Reviewed by Anonymous
on
2:45 AM
Rating: