MASTG-TOOL-0031: Frida
Frida is a free and open source dynamic code instrumentation toolkit written by Ole André Vadla Ravnås that works by injecting the QuickJS JavaScript engine (previously Duktape and V8) into the instrumented process. Frida lets you execute snippets of JavaScript into native apps on Android and iOS (as well as on other platforms).

Installation¶
To install Frida locally, simply run:
pip install frida-tools
Or refer to the installation page for more details.
Modes of Operation¶
Code can be injected in several ways. For example, Xposed permanently modifies the Android app loader, providing hooks for running your own code every time a new process is started. In contrast, Frida implements code injection by writing code directly into the process memory. When attached to a running app:
- Frida uses ptrace to hijack a thread of a running process. This thread is used to allocate a chunk of memory and populate it with a mini-bootstrapper.
- The bootstrapper starts a fresh thread, connects to the Frida debugging server that's running on the device, and loads a shared library that contains the Frida agent (
frida-agent.so). - The agent establishes a bi-directional communication channel back to the tool (e.g. the Frida REPL or your custom Python script).
- The hijacked thread resumes after being restored to its original state, and process execution continues as usual.

- Frida Architecture, source: https://www.frida.re/docs/hacking/
Frida offers three modes of operation:
- Injected: this is the most common scenario when frida-server is running as a daemon in the iOS or Android device. frida-core is exposed over TCP, listening on localhost:27042 by default. Running in this mode is not possible on devices that are not rooted or jailbroken.
- Embedded: this is the case when your device is not rooted nor jailbroken (you cannot use ptrace as an unprivileged user), you're responsible for the injection of the frida-gadget library by embedding it into your app, manually or via third-party tools such as objection.
- Preloaded: similar to
LD_PRELOADorDYLD_INSERT_LIBRARIES. You can configure the frida-gadget to run autonomously and load a script from the filesystem (e.g. path relative to where the Gadget binary resides).
APIs¶
Independently of the chosen mode, you can make use of the Frida JavaScript APIs to interact with the running process and its memory. Some of the fundamental APIs are:
- Interceptor: When using the Interceptor API, Frida injects a trampoline (aka in-line hooking) at the function prologue which provokes a redirection to our custom code, executes our code, and returns to the original function. Note that while very effective for our purpose, this introduces a considerable overhead (due to the trampoline related jumping and context switching) and cannot be considered transparent as it overwrites the original code and acts similar to a debugger (putting breakpoints) and therefore can be detected in a similar manner, e.g. by applications that periodically checksum their own code.
- Stalker: If your tracing requirements include transparency, performance and high granularity, Stalker should be your API of choice. When tracing code with the Stalker API, Frida leverages just-in-time dynamic recompilation (by using Capstone): when a thread is about to execute its next instructions, Stalker allocates some memory, copies the original code over, and interlaces the copy with your custom code for instrumentation. Finally, it executes the copy (leaving the original code untouched, and therefore avoiding any anti-debugging checks). This approach increases instrumentation performance considerably and allows for very high granularity when tracing (e.g. by tracing exclusively CALL or RET instructions). You can learn more in-depth details in the blog post "Anatomy of a code tracer" by Frida's creator Ole [#vadla]. Some examples of use for Stalker are, for example who-does-it-call or diff-calls. For practical tutorials and advanced usage patterns, see the Stalker section in the Frida Handbook.
- Java: When working on Android you can use this API to enumerate loaded classes, enumerate class loaders, create and use specific class instances, enumerate live instances of classes by scanning the heap, etc.
- ObjC: When working on iOS you can use this API to get a mapping of all registered classes, register or use specific class or protocol instances, enumerate live instances of classes by scanning the heap, etc.
Frida 17¶
Frida 17 introduces breaking changes, such as the removal of the bundled runtime bridges as well as changes to several native APIs.
Bridges:
Frida 17 removes the bundled runtime bridges (frida-{objc,swift,java}-bridge) within Frida's GumJS runtime. When you use CLI tools such as frida, frida-trace or Frooky, this doesn't have any noticeable impact, as they come with the Java, Objective-C, and Swift bridges pre-bundled, so you can still use them as before.
However, if you are writing your own custom Frida-based tooling or scripts that depend on these bridges, you will now need to install them separately via frida-pm, Frida's package manager. For example, to install the Java bridge, run:
frida-pm install frida-java-bridge
And then, in your scripts, you can import and use the bridge as follows:
import JavaBridge from 'frida-java-bridge';
JavaBridge.load();
You'll need to use frida-compile to bundle your scripts with the required bridges before running them with Frida from your own tooling (e.g. from a custom Python script):
npx frida-compile -o agent.js -o _agent.js
API Changes:
Frida has made changes to its native APIs. While these changes may break some of your existing scripts, they encourage you to write more readable and performant code. See a full overview in the MASTG Frida scripts writing guide.
For instance, now, Process.enumerateModules() returns an array of Module objects, allowing you to work with them directly.
for (const module of Process.enumerateModules()) {
console.log(module.name);
}
Another API that was removed is Module.getSymbolByName, which is used in many scripts. Depending on if you know which module the symbol is located in or not, you can use one of the following two alternatives:
// If you know the module
Process.getModuleByName('libc.so').getExportByName('open')
// If you don't (i.e., the old Module.getSymbolByName(null, 'open'); )
Module.getGlobalExportByName('open');
For more details, see:
Tools¶
Frida also provides a couple of simple tools built on top of the Frida API and available right from your terminal after installing frida-tools via pip. For instance:
frida: Frida CLI for quick script prototyping and try/error scenarios.frida-ps: lists all processes (apps) running on the device, including their names, identifiers, and PIDs.frida-ls-devices: lists your connected devices running Frida servers or agents.frida-trace: traces function calls without writing Frida scripts.
In addition, you'll also find several open source Frida-based tools, such as:
- Grapefruit: a Runtime Application Instrument toolkig for iOS.
- Fridump: a memory dumping tool for both Android and iOS.
- objection: a runtime mobile security assessment framework.
- r2frida: a project merging the powerful reverse engineering capabilities of radare2 with the dynamic instrumentation toolkit of Frida.
- JNITrace: a tool for tracing usage of the Android JNI runtime methods by a native library.
We will be using all of these tools throughout the guide.
You can use these tools as-is, tweak them to your needs, or take as excellent examples on how to use the APIs. Having them as an example is very helpful when you write your own hooking scripts or when you build introspection tools to support your reverse engineering workflow.
Frida Handbook¶
The Frida Handbook is a comprehensive resource that extends the MASTG's Dynamic Binary Instrumentation (DBI) testing techniques with in-depth tutorials and practical examples for using Frida in mobile security testing.
The handbook covers a wide range of topics including:
- Getting Started: Installation, basic setup, and running your first Frida scripts across different platforms.
- Core Concepts: Understanding Frida's architecture, JavaScript API fundamentals, and how to effectively use the Frida REPL for rapid prototyping.
- Hooking Techniques: Comprehensive guides on intercepting functions, methods, and native code across Android (Java/Kotlin and JNI) and iOS (Objective-C and Swift).
- Memory Analysis: Techniques for reading, writing, and searching process memory, as well as working with pointers and data structures.
- Advanced Usage: In-depth coverage of advanced features like Stalker for code tracing, custom instrumentation patterns, and performance optimization.
- Tool Integration: Using Frida with other security tools, including r2frida for combining radare2's reverse engineering capabilities with Frida's dynamic instrumentation.
- iOS-Specific Topics: Working with Objective-C runtime, Swift internals, bypassing jailbreak detection, and instrumenting iOS system frameworks.
- Android-Specific Topics: Instrumenting Java/Kotlin code, working with native libraries, bypassing root detection, and analyzing Android framework components.
- Practical Examples: Real-world scenarios and case studies demonstrating how to solve common mobile security testing challenges.
The Frida Handbook serves as an excellent companion to the MASTG, providing detailed explanations and hands-on examples that complement the testing methodologies described in this guide.
Tests¶
MASTG-TEST-0206: Undeclared PII in Network Traffic Capture MASTG-TEST-0028: Testing Deep Links MASTG-TEST-0048: Testing Reverse Engineering Tools Detection MASTG-TEST-0091: Testing Reverse Engineering Tools Detection