JavaScript API

Frida JavaScript API

Source: frida/frida-website (_i18n/en/_docs/javascript-api.md) Runtime: QuickJS (default) or V8 (Script.runtime) TypeScript bindings: npm install @types/frida-gum + clone frida-agent-example


Runtime Information

Frida

PropertyTypeDescription
Frida.versionstringCurrent Frida version
Frida.heapSizenumberCurrent size of Frida’s private heap (bytes), shared across all scripts

Script

APIReturnsDescription
Script.runtimestring"QJS" or "V8"
Script.evaluate(name, source)anyEvaluate JS string in global scope; name is a UNIX-style virtual path used in stack traces. Supports source maps via Script.registerSourceMap().
Script.load(name, source)Promise<namespace>Compile and evaluate as ES module. Parent script can export values importable by the child. Requires frida-compile’s ES module bundle format.
Script.registerSourceMap(name, json)voidRegister source map JSON for a script path. Call before loading the script for accurate stack traces.
Script.nextTick(func[, ...params])voidRun func on next tick (when current native thread exits JS runtime)
Script.pin()voidPrevent script unload (reference-counted; must pair with unpin())
Script.unpin()voidReverse a previous pin()
Script.bindWeak(value, fn)idCall fn when value is GC’d or script unloads. Returns ID for unbindWeak().
Script.unbindWeak(id)voidStop monitoring value and call fn immediately
Script.setGlobalAccessHandler(handler|null)voidInstall handler for undefined global access. Handler object: { enumerate(): string[], get(property): any }

Process, Thread, Module, Memory

Process

APIReturnsDescription
Process.idnumberPID
Process.archstring"ia32" | "x64" | "arm" | "arm64"
Process.platformstring"windows" | "darwin" | "linux" | "freebsd" | "qnx" | "barebone"
Process.pageSizenumberVirtual memory page size in bytes
Process.pointerSizenumberPointer size in bytes
Process.codeSigningPolicystring"optional" or "required". "required" means Interceptor API is off-limits and unsigned code cannot run (set via Gadget config).
Process.mainModuleModuleMain executable module
Process.getCurrentDir()stringCurrent working directory path
Process.getHomeDir()stringCurrent user home directory path
Process.getTmpDir()stringTemp directory path
Process.isDebuggerAttached()booleanWhether a debugger is attached
Process.getCurrentThreadId()numberCurrent thread OS ID
Process.enumerateThreads()Thread[]All running threads
Process.attachThreadObserver(callbacks)observerWatch thread add/remove/rename events. callbacks: { onAdded(thread), onRemoved(thread), onRenamed(thread, previousName) }. Call .detach() on returned observer.
Process.runOnThread(id, callback)Promise<any>Run JS function on specific thread. Use with caution — may interrupt non-reentrant code.
Process.findModuleByAddress(address)Module|nullFind module by address (null if not found)
Process.getModuleByAddress(address)ModuleGet module by address (throws if not found)
Process.findModuleByName(name)Module|nullFind module by name
Process.getModuleByName(name)ModuleGet module by name (throws if not found)
Process.enumerateModules()Module[]All loaded modules
Process.attachModuleObserver(callbacks)observerWatch module load/unload. callbacks: { onAdded(module), onRemoved(module) }. onAdded fires before app can use the module — ideal time to apply instrumentation.
Process.findRangeByAddress(address)range|nullMemory range containing address
Process.getRangeByAddress(address)rangeMemory range (throws if not found)
Process.enumerateRanges(protection|specifier)range[]Memory ranges matching protection string (e.g. "rw-"). Specifier: { protection, coalesce: bool }. Range fields: base (NativePointer), size, protection, file? ({ path, offset, size }).
Process.enumerateMallocRanges()range[]Individual heap allocations
Process.setExceptionHandler(callback)voidProcess-wide native exception handler. callback(details): { type, address, memory?, context, nativeContext }. Return true to resume, else forward to OS.

Thread

Objects returned by Process.enumerateThreads():

Property/MethodTypeDescription
idnumberOS thread ID
namestring|undefinedThread name if available
statestring"running" | "stopped" | "waiting" | "uninterruptible" | "halted"
contextobjectCPU registers snapshot: pc, sp, arch-specific (eax, rax, r0, x0, etc.)
entrypointobject|undefined{ routine: NativePointer, parameter?: NativePointer }
setHardwareBreakpoint(id, address)voidSet hardware breakpoint. Use with Process.setExceptionHandler().
unsetHardwareBreakpoint(id)voidRemove hardware breakpoint
setHardwareWatchpoint(id, address, size, conditions)voidWatch memory region. conditions: "r" | "w" | "rw"
unsetHardwareWatchpoint(id)voidRemove hardware watchpoint
Thread.backtrace([context, backtracer])NativePointer[]Generate backtrace. Pass this.context from Interceptor callbacks for accuracy. backtracer: Backtracer.ACCURATE (default, needs debug info) or Backtracer.FUZZY (stack forensics, false positives). Limit: 16 frames.
Thread.sleep(delay)voidSleep for delay seconds (e.g. 0.05 = 50ms)
1// Backtrace example in Interceptor
2Interceptor.attach(Module.getGlobalExportByName('open'), {
3  onEnter(args) {
4    console.log(Thread.backtrace(this.context, Backtracer.ACCURATE)
5      .map(DebugSymbol.fromAddress).join('\n'));
6  }
7});

Module

Objects returned by Module.load() and Process.enumerateModules():

Property/MethodReturnsDescription
namestringCanonical module name
baseNativePointerBase address
sizenumberSize in bytes
pathstringFull filesystem path
ensureInitialized()voidRun module initializers. Required during early instrumentation before interacting with APIs (e.g. ObjC classes).
enumerateImports()object[]{ type, name, module, address, slot }. Only name is guaranteed.
enumerateExports()object[]{ type, name, address }
enumerateSymbols()object[]{ isGlobal, type, section?, name, address, size? }. Only on i/macOS and Linux.
enumerateRanges(protection)range[]Module-scoped memory ranges
enumerateSections()object[]{ id, name, address, size }
enumerateDependencies()object[]{ name, type }. Types: regular, weak, reexport, upward
findExportByName(name)NativePointer|nullExport address (null if not found)
getExportByName(name)NativePointerExport address (throws if not found)
findSymbolByName(name)NativePointer|nullSymbol address
getSymbolByName(name)NativePointerSymbol address (throws)
Module.load(path)ModuleLoad module from filesystem path
Module.findGlobalExportByName(name)NativePointer|nullSearch all modules for export (expensive)
Module.getGlobalExportByName(name)NativePointerSame but throws

Symbol type values:

ModuleMap

1const map = new ModuleMap([filter]);  // filter: (Module) => boolean
MethodReturnsDescription
has(address)booleanWhether address belongs to any module in map
find(address)Module|nullModule containing address
get(address)ModuleModule containing address (throws)
findName(address) / getName(address)string|nullJust the name field
findPath(address) / getPath(address)string|nullJust the path field
update()voidRefresh after module load/unload
values()Module[]Deep copy of current modules (unaffected by future update())

Memory

APIReturnsDescription
Memory.scan(address, size, pattern, callbacks)voidScan memory range for pattern. Pattern format: "13 37 ?? ff" (hex bytes, ?? = wildcard). r2-style mask: "13 37 : 1f ff". Nibble wildcards: "?3 37". Callbacks: { onMatch(address, size), onError(reason), onComplete() }. Return "stop" from onMatch to cancel.
Memory.scanSync(address, size, pattern){address, size}[]Synchronous scan, returns array of matches
Memory.alloc(size[, options])NativePointerAllocate heap memory. If size is multiple of Process.pageSize, allocates raw OS pages. Options: { near: address, maxDistance: bytes }. Memory released when all JS handles gone — keep reference alive!
Memory.copy(dst, src, n)voidmemcpy equivalent
Memory.dup(address, size)NativePointeralloc + copy
Memory.protect(address, size, protection)booleanUpdate memory protection (e.g. "rw-")
Memory.queryProtection(address)stringGet protection string at address
Memory.patchCode(address, size, apply)voidSafely modify code. apply(writable_ptr) — write to the writable pointer, not address directly (iOS may use a temp buffer).
Memory.allocUtf8String(str)NativePointerAllocate and write UTF-8 string (NUL-terminated)
Memory.allocUtf16String(str)NativePointerAllocate and write UTF-16 string
Memory.allocAnsiString(str)NativePointerAllocate and write ANSI string
1// patchCode example: make get_lives_left() return 9000
2const getLivesLeft = Process.getModuleByName('game-engine.so').getExportByName('get_lives_left');
3Memory.patchCode(getLivesLeft, 64, code => {
4  const cw = new X86Writer(code, { pc: getLivesLeft });
5  cw.putMovRegU32('eax', 9000);
6  cw.putRet();
7  cw.flush();
8});

MemoryAccessMonitor

APIDescription
MemoryAccessMonitor.enable(ranges, callbacks)Monitor memory ranges for first access per page. ranges: { base, size } or array. callbacks.onAccess(details): { threadId, operation, from, address, rangeIndex, pageIndex, pagesCompleted, pagesTotal, context }
MemoryAccessMonitor.disable()Stop monitoring

CModule

Compile C source code to machine code in memory. Useful for hot Interceptor/Stalker callbacks.

1new CModule(code[, symbols, options])
1const cm = new CModule(`
2#include <stdio.h>
3void hello(void) { printf("Hello from CModule\\n"); }
4`);
5const hello = new NativeFunction(cm.hello, 'void', []);
6hello();

CModule.builtins: object with defines and headers available during compilation (arch/version-specific).

RustModule

1new RustModule(code[, symbols, options])

ApiResolver

1const resolver = new ApiResolver(type);
2// type: "module" | "swift" | "objc"

Lazy-loads data on creation. Reuse instance for batch queries; recreate for fresh data.

1resolver.enumerateMatches(query)  // returns [{name, address, size?}]

Query syntax:

Suffix /i for case-insensitive matching.

DebugSymbol

APIReturnsDescription
DebugSymbol.fromAddress(address)symbol{ address, name, moduleName, fileName, lineNumber }. Supports toString().
DebugSymbol.fromName(name)symbolSame
DebugSymbol.getFunctionByName(name)NativePointerFirst matching function address (throws if not found)
DebugSymbol.findFunctionsNamed(name)NativePointer[]All matching function addresses
DebugSymbol.findFunctionsMatching(glob)NativePointer[]Functions matching glob pattern
DebugSymbol.load(path)voidLoad debug symbols for a module

Kernel

Requires Kernel.available === true before use.

APIReturnsDescription
Kernel.availablebooleanWhether Kernel API is available
Kernel.baseUInt64Kernel base address
Kernel.pageSizenumberKernel page size
Kernel.enumerateModules(){name, base, size}[]Kernel modules
Kernel.enumerateRanges(protection|specifier)range[]Kernel memory ranges
Kernel.enumerateModuleRanges(name, protection)range[]Ranges for a kernel module (use null for kernel itself)
Kernel.alloc(size)UInt64Allocate kernel memory (rounded to page size)
Kernel.protect(address, size, protection)voidUpdate kernel memory protection
Kernel.readByteArray(address, length)ArrayBufferRead from kernel memory
Kernel.writeByteArray(address, bytes)voidWrite to kernel memory
Kernel.scan(address, size, pattern, callbacks)voidScan kernel memory
Kernel.scanSync(address, size, pattern)match[]Synchronous kernel memory scan

Data Types, Function and Callback

Int64 / UInt64

1const v = new Int64(v)   // or int64(v)
2const v = new UInt64(v)  // or uint64(v)
3// v: number or decimal/hex string ("0x1234")
MethodDescription
add(rhs), sub(rhs), and(rhs), or(rhs), xor(rhs)Arithmetic/bitwise, returns new Int64/UInt64
shr(n), shl(n)Bit shift, returns new value
compare(rhs)Like String#localeCompare
toNumber()Cast to JS number
toString([radix=10])Convert to string

NativePointer

1const p = new NativePointer(s)  // or ptr(s)
2// s: decimal or "0x..." hex string
3NULL  // shorthand for ptr("0")

Arithmetic:

MethodDescription
add(rhs), sub(rhs), and(rhs), or(rhs), xor(rhs)Returns new NativePointer
shr(n), shl(n)Bit shift
not()Bitwise NOT
isNull()Returns boolean
equals(rhs)Equality check
compare(rhs)Like String#localeCompare
toInt32()Cast to signed 32-bit int
toString([radix=16])Default hex string
toMatchPattern()Returns Memory.scan()-compatible pattern string

Pointer Authentication (AArch64 PAC):

MethodDescription
sign([key, data])Add PAC bits. Keys: "ia" (default), "ib", "da", "db". No-op if PAC not supported.
strip([key])Remove PAC bits. Defaults to "ia".
blend(smallInteger)Blend constant into pointer (use as data for sign())

Read/Write:

MethodDescription
readPointer() / writePointer(ptr)Read/write pointer-sized value
readS8()readDouble()Read signed/unsigned integers and floats
writeS8(v)writeDouble(v)Write values
readS64(), readU64(), readLong(), readULong()Returns Int64/UInt64
writeS64(v), writeU64(v), writeLong(v), writeULong(v)Write 64-bit values
readByteArray(length)Returns ArrayBuffer
writeByteArray(bytes)bytes: ArrayBuffer or [0x13, 0x37, ...]
readVolatile(length) / writeVolatile(bytes)Safe read/write via syscall — use when memory may be inaccessible or threads are running
readCString([size=-1])Read ASCII/NUL-terminated
readUtf8String([size=-1])Read UTF-8
readUtf16String([length=-1])Read UTF-16
readAnsiString([size=-1])Read ANSI (Windows only)
writeUtf8String(str) / writeUtf16String(str) / writeAnsiString(str)Write encoded string with NUL terminator

All read/write methods throw JS exception on inaccessible memory (except readVolatile/writeVolatile).

ArrayBuffer

APIDescription
ArrayBuffer.wrap(address, size)Create ArrayBuffer backed by existing memory. No validation — bad pointer crashes process.
buffer.unwrap()Returns NativePointer to backing store. Caller must keep buffer alive.

NativeFunction

1new NativeFunction(address, returnType, argTypes[, abi])
2new NativeFunction(address, returnType, argTypes[, options])

Supported types: void, pointer, int, uint, long, ulong, char, uchar, size_t, ssize_t, float, double, int8int64, uint8uint64, bool

Structs by value: use array of field types: ['int', 'int', 'int']. Nestable. C++ classes with vtables: first field is pointer to vtable.

Supported ABIs:

PlatformValues
Default"default"
Win32"sysv", "stdcall", "thiscall", "fastcall", "mscdecl"
Win64"win64"
UNIX x86"sysv", "unix64"
UNIX ARM"sysv", "vfp"

Options object:

KeyValuesDescription
abisee aboveABI selection
scheduling"cooperative" (default), "exclusive"Whether to release JS lock during call
exceptions"steal" (default), "propagate"How to handle native exceptions
traps"default", "none", "all"Interceptor/Stalker activation during call. "all" enables Stalker for coverage/step-into.

Variadic functions: add '...' between fixed and variadic args in argTypes.

NativeCallback

1new NativeCallback(func, returnType, argTypes[, abi])

Creates a native-callable JS function. Returns a NativePointer. When used with Interceptor.replace(), func receives this bound to the same invocation object as Interceptor.attach().

SystemFunction

1new SystemFunction(address, returnType, argTypes[, abi|options])

Like NativeFunction but return value is { value, errno } (UNIX) or { value, lastError } (Windows).


Network

Socket

APIReturnsDescription
Socket.listen([options])Promise<SocketListener>Open TCP or UNIX listening socket. Options: family ("unix","ipv4","ipv6"), host, port, type (UNIX: "path","abstract","abstract-padded","anonymous"), path, backlog (default 10)
Socket.connect(options)Promise<SocketConnection>Connect to TCP or UNIX server. Options: family, host (default "localhost"), port, type, path
Socket.type(handle)string|nullOS socket type: "tcp","udp","tcp6","udp6","unix:stream","unix:dgram"
Socket.localAddress(handle){ip?,port?,path?}|nullLocal address
Socket.peerAddress(handle){ip?,port?,path?}|nullPeer address

SocketListener

All methods async (return Promise).

Property/MethodDescription
pathUNIX socket path
portIP port
close()Release resources
accept()Wait for next client → Promise<SocketConnection>

SocketConnection

Inherits from IOStream. All methods async.

MethodDescription
setNoDelay(noDelay)Disable Nagle algorithm when true

File and Stream

File

APIDescription
File.readAllBytes(path)Synchronously read all bytes → ArrayBuffer
File.readAllText(path)Synchronously read all text (UTF-8) → string
File.writeAllBytes(path, data)Synchronously write ArrayBuffer
File.writeAllText(path, text)Synchronously write UTF-8 string
new File(filePath, mode)Open file. mode like C fopen() (e.g. "wb")
tell()Current file pointer position
seek(offset[, whence])Move pointer. whence: File.SEEK_SET, File.SEEK_CUR, File.SEEK_END
readBytes([size])Read bytes → ArrayBuffer (reads to EOF if no size)
readText([size])Read UTF-8 text → string
readLine()Read next line (no newline in result)
write(data)Write string or ArrayBuffer
flush()Flush buffered data
close()Close file

IOStream / InputStream / OutputStream

All methods async (return Promise).

IOStream:

InputStream:

OutputStream:

Platform-specific Streams

ClassPlatformConstructor
UnixInputStream(fd[, options])UNIXoptions.autoClose: close fd on stream release
UnixOutputStream(fd[, options])UNIXSame
Win32InputStream(handle[, options])Windowshandle is Windows HANDLE
Win32OutputStream(handle[, options])WindowsSame

Database

SqliteDatabase

APIDescription
SqliteDatabase.open(path[, options])Open SQLite v3 database. options.flags: array of "readonly","readwrite","create"
SqliteDatabase.openInline(encodedContents)Open in-memory DB from Base64-encoded (optionally gzipped) content. Read-write, never touches filesystem.
close()Close database
exec(sql)Execute raw SQL (result ignored; use for DDL)
prepare(sql)Compile SQL → SqliteStatement
dump()Dump to gzip+Base64 string (for use with openInline)

SqliteStatement

MethodDescription
bindInteger(index, value)Bind integer
bindFloat(index, value)Bind float
bindText(index, value)Bind text
bindBlob(index, bytes)Bind blob (ArrayBuffer, byte array, or string)
bindNull(index)Bind null
step()Advance and return row as array, or null at end
reset()Reset for re-use
1const db = SqliteDatabase.open('/path/to/people.db');
2const smt = db.prepare('SELECT name FROM people WHERE age = ?');
3smt.bindInteger(1, 42);
4let row;
5while ((row = smt.step()) !== null) console.log(row[0]);
6smt.reset();

Instrumentation

Interceptor

APIDescription
Interceptor.attach(target, callbacks[, data])Hook function at target (NativePointer). On 32-bit ARM: LSB=0 for ARM, LSB=1 for Thumb — Frida handles this automatically for addresses from its own APIs. Returns listener with .detach().
Interceptor.detachAll()Remove all hooks
Interceptor.replace(target, replacement[, data])Replace function implementation. Use NativeCallback for JS replacement; CModule NativePointer for C replacement. data accessible via gum_invocation_context_get_listener_function_data().
Interceptor.replaceFast(target, replacement)Like replace() but patches target directly (less overhead). Returns pointer to original implementation.
Interceptor.revert(target)Revert replacement
Interceptor.flush()Commit pending changes to memory. Call after attach/replace before calling the function via NativeFunction. Auto-flushed on thread exit from JS runtime, send(), RPC return, console.*.
Interceptor.breakpointKind"soft" (default) or "hard". Barebone backend only.

callbacks object:

CallbackSignatureDescription
onEnter(args)args: NativePointer arrayRead/write arguments. args[0], args[1], etc.
onLeave(retval)retval: NativePointer-derivedRead/replace return value. retval.replace(1337) or retval.replace(ptr("0x1234")). Don’t store retval — it’s recycled. Copy with ptr(retval.toString()).

Both callbacks can also be NativePointer values pointing to C functions (from CModule) with signatures:

this inside callbacks:

PropertyDescription
returnAddressNativePointer
contextCPU registers: pc, sp, arch-specific (eax, rax, r0, x0, etc.). Writable.
errno(UNIX) current errno, writable
lastError(Windows) OS error, writable
threadIdOS thread ID
depthCall depth relative to other invocations

this is thread-local per invocation — use it to pass data between onEnter and onLeave.

Performance notes:

 1// Basic attach
 2Interceptor.attach(Module.getGlobalExportByName('read'), {
 3  onEnter(args) {
 4    this.fd = args[0].toInt32();
 5    this.buf = args[1];
 6    this.count = args[2].toInt32();
 7  },
 8  onLeave(retval) {
 9    const n = retval.toInt32();
10    if (n > 0) console.log(hexdump(this.buf, { length: n }));
11  }
12});
13
14// Replace function
15const openPtr = Module.getGlobalExportByName('open');
16const open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
17Interceptor.replace(openPtr, new NativeCallback((pathPtr, flags) => {
18  console.log('Opening:', pathPtr.readUtf8String());
19  return open(pathPtr, flags);
20}, 'int', ['pointer', 'int']));

Stalker

Per-thread code tracing engine. Instruments basic blocks by copying them to RWX slabs.

APIDescription
Stalker.follow([threadId, options])Start stalking thread (or current thread if omitted)
Stalker.unfollow([threadId])Stop stalking
Stalker.exclude(range)Exclude memory range from tracing ({ base, size })
Stalker.parse(events[, options])Parse GumEvent binary blob. Options: { annotate: bool, stringify: bool }
Stalker.flush()Flush buffered events immediately
Stalker.garbageCollect()Free memory after unfollow() at a safe point
Stalker.invalidate(address)Invalidate current thread’s translated code for a basic block
Stalker.invalidate(threadId, address)Invalidate specific thread’s translated code
Stalker.addCallProbe(address, callback[, data])Call callback synchronously on every call to address. Returns probe ID. C signature: void onCall(GumCallSite *site, gpointer user_data)
Stalker.removeCallProbe(id)Remove call probe
Stalker.trustThresholdint: -1 (never trust), 0 (always trust), N (trust after N executions). Default: 1
Stalker.queueCapacityEvent queue size in events. Default: 16384
Stalker.queueDrainIntervalDrain interval in ms. Default: 250. Set to 0 to disable periodic drain (call flush() manually).

follow() options:

 1Stalker.follow(threadId, {
 2  events: {
 3    call: true,    // CALL instructions
 4    ret: false,    // RET instructions
 5    exec: false,   // all instructions (high volume)
 6    block: false,  // block executed (coarse)
 7    compile: false // block compiled (coverage)
 8  },
 9  // Choose ONE of:
10  onReceive(events) { /* raw GumEvent binary blob */ },
11  onCallSummary(summary) { /* { address: callCount } */ },
12
13  // Optional transformer (rewrite basic blocks):
14  transform(iterator) {
15    let insn;
16    while ((insn = iterator.next()) !== null) {
17      // inspect insn.mnemonic, insn.address, etc.
18      iterator.keep(); // emit instruction (drop by not calling keep())
19    }
20  },
21  // C transformer for performance:
22  // transform: cm.transform,
23  // onEvent: cm.process,
24  // data: ptr(1337)
25});

Performance: Use onCallSummary instead of onReceive when only call counts are needed. Use CModule for transform/onEvent callbacks in hot paths.

ObjC

Frida 17+: No longer bundled in GumJS. Install: npm install frida-objc-bridge and import ObjC from 'frida-objc-bridge'. REPL and frida-trace still include it automatically.

Prerequisite: check ObjC.available before using any ObjC API.

APIDescription
ObjC.availableboolean — ObjC runtime loaded
ObjC.apiObject mapping ObjC runtime function names to NativeFunction instances
ObjC.classesObject mapping class names to ObjC.Object wrappers. Method call: replace : with _: NSString.stringWithString_("Hello")
ObjC.protocolsObject mapping protocol names to ObjC.Protocol wrappers
ObjC.mainQueueGCD main queue
ObjC.schedule(queue, work)Schedule JS function on GCD queue (auto NSAutoreleasePool)
new ObjC.Object(handle[, protocol])Wrap existing ObjC instance at NativePointer handle
new ObjC.Protocol(handle)Wrap existing protocol
new ObjC.Block(target[, options])Wrap or define a block. For new block: { implementation, types } or { implementation, retType, argTypes }. Call declare(signature) if existing block lacks metadata.
ObjC.implement(method, fn)Create NativeCallback compatible with method signature
ObjC.registerProxy(properties)Create proxy class: { protocols?, methods?, events: { dealloc(), forward(name) } }
ObjC.registerClass(properties)Create ObjC class: { name?, super?, protocols?, methods }
ObjC.registerProtocol(properties)Create ObjC protocol: { name?, protocols?, methods }
ObjC.bind(obj, data)Bind JS data to ObjC instance
ObjC.unbind(obj)Unbind JS data
ObjC.getBoundData(obj)Look up bound data
ObjC.enumerateLoadedClasses([options,] callbacks)Enumerate classes. options.ownedBy: ModuleMap filter. Callbacks: { onMatch(name, owner), onComplete() }
ObjC.enumerateLoadedClassesSync([options])Sync version → { modulePath: [className] }
ObjC.choose(specifier, callbacks)Scan heap for live instances. specifier: ObjC.Object class or { class, subclasses: bool }
ObjC.chooseSync(specifier)Sync version → instance[]
ObjC.selector(name)JS string → selector
ObjC.selectorAsString(sel)selector → JS string

ObjC.Object special properties:

PropertyDescription
$kind"instance" | "class" | "meta-class"
$superObjC.Object for chaining super calls
$superClassSuper-class as ObjC.Object
$classClass of this object
$classNameClass name string
$moduleNameModule path string
$protocols{ name: ObjC.Protocol }
$methodsNative method names (including inherited)
$ownMethodsNative method names (own class only)
$ivarsInstance variables (read/write via assignment)
equals(other)Reference equality check
clone(options)New method wrapper with custom NativeFunction options
 1// Hook ObjC method
 2const { NSSound } = ObjC.classes;
 3Interceptor.attach(NSSound.play.implementation, {
 4  onEnter() { send('[NSSound play]'); }
 5});
 6
 7// Replace implementation
 8const oldImpl = NSSound.play.implementation;
 9NSSound.play.implementation = ObjC.implement(NSSound.play, (handle, sel) => {
10  return oldImpl(handle, sel);
11});
12
13// Intercept block argument
14Interceptor.attach(someMethod, {
15  onEnter(args) {
16    const block = new ObjC.Block(args[4]);
17    const orig = block.implementation;
18    block.implementation = (err, val) => {
19      console.log('block called', err, val);
20      return orig(err, val);
21    };
22  }
23});

Java

Frida 17+: No longer bundled. Install: npm install frida-java-bridge and import Java from 'frida-java-bridge'. REPL and frida-trace still include it automatically.

Prerequisite: check Java.available before using any Java API.

APIDescription
Java.availableboolean — Dalvik/ART VM loaded
Java.androidVersionAndroid version string
Java.perform(fn)Ensure thread attached to VM, call fn. Defers if app class loader not ready.
Java.performNow(fn)Like perform() but doesn’t wait for class loader
Java.scheduleOnMainThread(fn)Run on VM main thread
Java.use(className)Get class wrapper. $new() = constructor, $dispose() = cleanup. Method replacement: Activity.onResume.implementation = function() {...}
Java.cast(handle, klass)Wrap raw pointer as class instance. Has .class and .$className properties.
Java.array(type, elements)Create Java array from JS array. Pass by reference to Java APIs.
Java.openClassFile(filePath)Open .dex: { load(), getClassNames() }
Java.choose(className, callbacks)Scan heap for live instances: { onMatch(instance), onComplete() }
Java.retain(obj)Duplicate wrapper for use outside replacement method
Java.enumerateLoadedClasses(callbacks){ onMatch(name, handle), onComplete() }
Java.enumerateLoadedClassesSync()Returns class name array
Java.enumerateClassLoaders(callbacks){ onMatch(loader), onComplete() }
Java.enumerateClassLoadersSync()Returns loader array
Java.enumerateMethods(query)Query: "class!method" with globs. Modifiers: /i (case-insensitive), /s (include signatures), /u (user classes only)
Java.backtrace([options])options.limit (default 16). Returns { id, frames: [{signature, origin, className, methodName, methodFlags, fileName, lineNumber}] }
Java.isMainThread()boolean
Java.registerClass(spec)Create Java class: { name, superClass?, implements?, fields?, methods }
Java.deoptimizeEverything()Force interpreter execution (enables ART instrumentation)
Java.deoptimizeBootImage()Deoptimize boot image only
Java.vm{ perform(fn), getEnv(), tryGetEnv() }
Java.classFactoryDefault factory (app main class loader)
Java.ClassFactory.get(classLoader)Factory for specific class loader

Method flag constants: ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, etc.

 1// Hook Android method
 2Java.perform(() => {
 3  const Activity = Java.use('android.app.Activity');
 4  Activity.onResume.implementation = function() {
 5    send('onResume called');
 6    this.onResume();
 7  };
 8});
 9
10// SSL pinning bypass pattern
11Java.perform(() => {
12  const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
13  const MyTM = Java.registerClass({
14    name: 'com.example.MyTM',
15    implements: [X509TrustManager],
16    methods: {
17      checkClientTrusted(chain, authType) {},
18      checkServerTrusted(chain, authType) {},
19      getAcceptedIssuers() { return []; }
20    }
21  });
22});

CPU Instruction

Instruction

1const insn = Instruction.parse(target);  // target: NativePointer

Fields: address, next (NativePointer to next insn), size, mnemonic, opStr, operands, regsRead, regsWritten, groups, toString()

On 32-bit ARM: LSB=0 for ARM, 1 for Thumb.

Writer Classes

All writers share this interface:

Property/MethodDescription
new XxxWriter(codeAddress[, {pc}])Create writer. pc option needed when writing to scratch buffer (e.g. Memory.patchCode() on iOS).
reset(codeAddress[, {pc}])Recycle instance
dispose()Eagerly free memory
flush()Resolve labels and write pending data. Always call when done.
baseNativePointer to first byte of output
codeNativePointer to next byte of output
pcProgram counter at next output byte
offsetCurrent offset as number
putLabel(id)Place label for forward/backward references
putBytes(data)Write raw ArrayBuffer
putNop()NOP
putBreakpoint()OS/arch-specific breakpoint

X86Writer — also: putCallAddressWithArguments, putCallReg, putJmpAddress, putJmpReg, putJccShortLabel, putJccNearLabel, putMovRegReg, putMovRegU32, putMovRegU64, putAddRegImm, putSubRegImm, putPushReg, putPopReg, putRet, putLeave, putCmpRegI32, putTestRegReg, putXchgRegRegPtr, putLockXaddRegPtrReg, putFxsaveRegPtr, putU8, putS8

ArmWriter — also: putBImm, putBLabel, putBlImm, putBlxImm, putBxReg, putLdrRegAddress, putLdrRegU32, putStrRegReg, putMovRegReg, putAddRegRegImm, putSubRegRegImm, putVpushRange, putVpopRange, putInstruction

ThumbWriter — also: putBImm, putBlImm, putBlxImm, putBxReg, putCbzRegLabel, putCbnzRegLabel, putPushRegs, putPopRegs, putLdrRegAddress, putStrRegReg, putMovRegReg, putAddRegImm, putSubRegImm, putInstruction, putInstructionWide, commitLabel

Arm64Writer — also: putBImm, putBLabel, putBCondLabel, putBlImm, putBlrReg, putBrReg, putBrRegNoAuth, putBlrRegNoAuth, putRetReg, putCbzRegLabel, putCbnzRegLabel, putTbzRegImmLabel, putLdrRegAddress, putLdrRegU64, putLdrRegRef/putLdrRegValue, putAdrpRegAddress, putStrRegReg, putLdpRegRegRegOffset, putStpRegRegRegOffset, putMovRegReg, putAddRegRegImm, putSubRegRegImm, putXpaciReg, sign(value), putMrs

MipsWriter — also: putJAddress, putJrReg, putJalAddress, putBeqRegRegLabel, putLaRegAddress, putLwRegRegOffset, putSwRegRegOffset, putMoveRegReg, putAdduRegRegReg, putInstruction

Relocator Classes

1new XxxRelocator(inputCode, output)
2// inputCode: NativePointer; output: corresponding XxxWriter
MethodDescription
reset(inputCode, output)Recycle
dispose()Free memory
inputLatest Instruction read (null initially)
eobEnd-of-block reached (branch/call/ret)
eoiEnd-of-input reached
readOne()Buffer next instruction, returns bytes read so far (0 = EOI)
peekNextWriteInsn()Peek next Instruction to write
peekNextWriteSource()Peek next source address
skipOne()Skip next instruction
writeOne()Write next buffered instruction
writeAll()Write all buffered instructions

ThumbRelocator also has copyOne().

Enum Types

x86 Register: xax xcx xdx xbx xsp xbp xsi xdi eax ecx … rax rcx … r8-r15 eip rip x86 InstructionId: jo jno jb jae je jne jbe ja js jns jp jnp jl jge jle jg jcxz jecxz jrcxz x86 BranchHint: no-hint likely unlikely x86 PointerTarget: byte dword qword

ARM Register: r0-r15 sp lr sb sl fp ip pc s0-s31 d0-d31 q0-q15 ARM ConditionCode: eq ne hs lo mi pl vs vc hi ls ge lt gt le al ARM Shifter: asr lsl lsr ror rrx asr-reg lsl-reg lsr-reg ror-reg rrx-reg

AArch64 Register: x0-x30 w0-w30 sp lr fp wsp wzr xzr nzcv ip0 ip1 s0-s31 d0-d31 q0-q31 AArch64 ConditionCode: eq ne hs lo mi pl vs vc hi ls ge lt gt le al nv AArch64 IndexMode: post-adjust signed-offset pre-adjust

MIPS Register: v0 v1 a0-a3 t0-t9 s0-s8 k0 k1 gp sp fp ra hi lo zero at 0-31


Others

Console

1console.log(line)    // stdout
2console.warn(line)   // stderr
3console.error(line)  // stderr

ArrayBuffer arguments are auto-formatted via hexdump().

Hexdump

1hexdump(target[, options])
2// target: ArrayBuffer or NativePointer
3// options: { offset: 0, length: 64, header: true, ansi: false, address: ptr('0x...') }

Shorthand

ShorthandEquivalent
int64(v)new Int64(v)
uint64(v)new UInt64(v)
ptr(s)new NativePointer(s)
NULLptr("0")

Communication (send/recv/rpc)

APIDescription
send(message[, data])Send JSON-serializable object to host. Optional data: ArrayBuffer or byte array. Async but not optimized for high frequency — batch values.
recv([type,] callback)Register one-shot callback for next message from host. Optionally filter by type field. Call again to receive next. Callback: (message, data|null)
rpc.exportsAssign object to expose RPC methods. Values can return plain values or Promises.
1// Agent side
2rpc.exports = {
3  add(a, b) { return a + b; },
4  sub(a, b) { return new Promise(r => setTimeout(() => r(a - b), 100)); }
5};
6
7// Host side (Python)
8print(script.exports.add(2, 3))   # 5
9print(script.exports.sub(5, 3))   # 2

Timing Events

APIDescription
setTimeout(func, delay[, ...params])Call after delay ms. Returns ID.
clearTimeout(id)Cancel
setInterval(func, delay[, ...params])Call every delay ms. Returns ID.
clearInterval(id)Cancel
setImmediate(func[, ...params])Schedule on next tick. Returns ID.
clearImmediate(id)Cancel

Garbage Collection

1gc()  // Force GC. Useful for testing Script.bindWeak() logic.

Worker

Isolated JS heap/lock for background processing.

1const w = new Worker(url[, { onMessage }]);
2w.post(message[, data]);   // send to worker (use recv() inside)
3w.exports.method();        // call rpc.exports defined by worker → Promise
4w.terminate();

Cloak

Hide Frida’s resources from introspection APIs (Process.enumerateThreads(), etc.). Frida’s own resources are cloaked automatically.

APIDescription
Cloak.addThread(id) / removeThread(id)Hide/show thread
Cloak.hasCurrentThread() / hasThread(id)Check if cloaked
Cloak.addRange(range) / removeRange(range)Hide/show memory range ({ base, size })
Cloak.hasRangeContaining(address)Check if address in cloaked range
Cloak.clipRange(range)Returns visible parts of range as array (empty = all cloaked, null = all visible)
Cloak.addFileDescriptor(fd) / removeFileDescriptor(fd)Hide/show fd
Cloak.hasFileDescriptor(fd)Check if fd is cloaked

Profiler

Worst-case profiler built on Interceptor. Tracks maximum time per function call.

1const profiler = new Profiler();
2profiler.instrument(functionAddress, sampler[, { describe(args) }]);
3// describe: called on new worst-case; return string describing args
4const xml = profiler.generateReport();

Samplers

ClassDescription
new CycleSampler()CPU cycles (e.g. RDTSC on x86)
new BusyCycleSampler()CPU cycles for current thread only (e.g. QueryThreadCycleTime on Windows)
new WallClockSampler()Wall clock time
new UserTimeSampler([threadId])User-space time for thread (default: current)
new MallocCountSampler()Count malloc/calloc/realloc calls
new CallCountSampler(functions)Count calls to specified NativePointer functions

All samplers have sample() → bigint.