Dynamic instrumentation toolkit

Reprogram running software, from the app down to the kernel.

Frida puts your code inside live processes and operating system kernels. Hook any function, trace private code, rewrite behavior, and see the result the moment you hit save. No source, no recompile, no restart.

User mode: Windows, macOS, GNU/Linux, iOS, watchOS, tvOS, Android, FreeBSD, QNX, PlayStation 5.
Kernel mode: Windows NT from XP through 11, Windows 9x/ME, XNU, and Linux, in virtual machines or on physical hardware.
Bare metal: microcontrollers and custom kernels over a debug stub.

Your tooling reaches processes directly, or goes in through the kernel, loaded as a driver or over a GDB remote stub, and from there into every process. Your tooling PYTHON · NODE.JS · RUST · SWIFT · LUMA TARGET · VM OR HARDWARE USER SPACE · RING 3 KERNEL · RING 0 HARDWARE app gum agent service gum agent daemon gum agent Kernel agent frida-barebone-agent hooks the kernel itself reaches every process invisible to user space CPU GDB REMOTE STUB · JTAG · SWD QEMU, VirtualBox, or a hardware debugger
One API at every level. Go in through a process, or through the kernel and reach them all.

Where it runs

Three ways in.

Pick the vantage point the target allows. Everything above it, from the scripting API to frida-trace and Luma, stays the same.

Injected

frida-core

Attach to a running process, or spawn one with your hooks in place before its first instruction. frida-core does the injecting, from inside your own tool on the machine you are on. On a remote device it runs headless as frida-server, so a frida-core elsewhere can reach it. frida-portal fronts a whole fleet the same way, exposing the processes that have joined it.

How injection works

As a library

frida-gadget

No root or jailbreak? Frida injects Gadget into a debuggable iOS or Android app for you. Elsewhere, preload it with LD_PRELOAD or DYLD_INSERT_LIBRARIES, load it from your own test runner, or repackage an app with it when you want custom tweaks baked in. It waits for you to connect, or runs scripts on its own from the filesystem.

About Gadget

In the kernel

frida-barebone-agent

Load the Barebone agent into the operating system kernel. Instrument the kernel itself and every process above it, from one session, with nothing left for the process to detect. No kernel to speak of? Barebone drives microcontrollers and custom kernels over a GDB remote stub, with no agent on the target at all.

Meet Barebone

Barebone

An agent that lives in ring 0.

Barebone is Frida's bare-metal backend. Its agent is written in Rust around the same GumJS engine that runs inside user processes, so the API you already know now works against a kernel. Where there is no kernel to host it, the same API works over a debug stub alone.

Getting it in

Through a GDB remote stub
QEMU, VirtualBox, Parallels and the Android emulator all expose one. So does a hardware debugger, which puts a physical device's kernel in reach over JTAG or SWD.
As a driver
On Linux and Android, insmod frida-agent.ko. On macOS, load the agent as a kernel extension. Then ask frida-core for the barebone device, from the CLI or the API. add_barebone_device() on the DeviceManager takes options, and FRIDA_BAREBONE_CONFIG points the default device at a JSON config. Only tools on another machine need a frida-server --device=barebone in between.
Or with no kernel at all
A microcontroller, a bootloader, or a custom kernel with no room for an agent: point Barebone at its GDB remote stub and your script runs on the host instead. Memory access such as readU32() becomes a stub read, and Interceptor with JavaScript callbacks becomes a software or hardware breakpoint. Hand Interceptor a NativePointer instead and it places an inline hook in the target's memory, usually code you built with RustModule, the Barebone runtime's counterpart to CModule.

What you get

Kernel and user mode, together
Enumerate processes, attach, spawn with instrumentation in place, hook functions, query the kernel's BTF types, and watch kernel modules come and go. From the kernel, the agent injects into user processes itself.
Invisible from inside the process
The kernel half cloaks the user-mode agent's threads and memory mappings. Runtime application self-protection looking from inside the process finds nothing to see.
Light on memory
User-mode agents map the same physical pages the kernel agent already uses. Each instrumented process allocates only its own writable portion.

Agents shipped with every release, as frida-barebone-agent-*:

linux-arm64linux-armlinux-x86_64linux-x86 xnu-arm64xnu-kext-arm64e winnt-x86_64winnt-x86winnt-arm64 win9x-x86

Loadable as a driver. The Linux module is built against your exact kernel from the GumJS devkit, so it is not a prebuilt download.

Languages

JavaScript is the fast path, not the only path.

Most people start with a few lines of JavaScript because the edit, save, see loop takes seconds. The rest of the stack speaks whatever you do, on the host and inside the target.

Interceptor.attach(Module.getGlobalExportByName('recvfrom'), {
  onEnter(args) {
    this.fd = args[0].toInt32();
  },
  onLeave(retval) {
    console.log(`recvfrom(fd=${this.fd}) => ${retval.toInt32()} bytes`);
  }
});

The agent side

This runs inside the target, in a process or in a kernel, on QuickJS or V8. Write it in TypeScript if you like, with autocompletion from the bundled type definitions. Hot paths can drop into C with CModule.

JavaScript API reference

For developers

Debug the build you already shipped.

Logging has blind spots, and you find them in the field. Instead of redeploying a special build just to see more, build a tool on Frida that attaches to the software your customers are already running.

Look anywhere, after the fact

Hook the function that the logs do not cover, inspect its arguments, and change what it returns, on the process that is misbehaving right now. No new build, no restart, no lost state.

One tool, every version

Resolve symbols, offsets and types at runtime, so a single product-specific tool supports the versions out in the field. That is more elegant than a tracing feature per release, and it ages better.

In-house or in-product

Keep the tool external and leave the product untouched, or ship Gadget inside your own software as a first-party inspector. Build it in Python, Rust, Swift or Node.js, or as a Luma workspace your whole team shares.

Quick start

Up and running in seconds.

One pip install gives you frida-trace, the REPL, frida-ps and friends. Point them at a local process, a phone over USB, or a kernel. Full quick-start guide

$ pip install frida-tools
$ frida-trace -i "recv*" Twitter
recvfrom: Auto-generated handler: …/recvfrom.js
Started tracing 21 functions.
1442 ms  recvfrom()
# Live-edit recvfrom.js and watch the magic!
5374 ms  recvfrom(socket=67, buffer=0x252a618, length=65536, flags=0, address=0xb0420bd8, address_len=16)
Luma's Tracer: a handler for open() in the built-in editor, the hook list beside it, and the event stream of traced calls from Telegram below
Tracer in Luma: edit the handler, see the calls stream in.

Prefer a GUI?

Luma is the official Frida app.

A native workspace for everything above, with the sessions and handlers kept between runs.

  • Persistent sessions that re-attach when the target comes back
  • A live REPL with type-aware autocompletion, and frida-trace with the editor built in
  • Real-time collaboration on the same target, with chat and a shared notebook

Free software

Frida is and will always be free as in freedom, so the next generation of developer tools can build on it.

Battle-tested

NowSecure uses Frida to analyze mobile apps at scale, and a comprehensive test suite runs on every change.

Scales down

Build only what you need. The same core fits embedded systems, with a footprint you control feature by feature.

Built in the open

Over a decade of releases, with detailed notes for every one, and a community that ships fixes upstream.