Install
$ agentstack add skill-as0ler-skills-frida ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Frida 17 JavaScript API Reference
> Version: Frida 17.x (latest: 17.6.2, Feb 2026) · frida-tools 14+ > Runtimes: QuickJS (default), V8 (opt-in) · TypeScript supported via frida-compile > Script templates: See [EXAMPLES.md](./EXAMPLES.md) for ready-to-use iOS ARM64 & Android scripts.
Table of Contents
- [Setup & Tooling](#1-setup--tooling)
- [Migration Notes from Frida 16.x](#2-migration-notes-from-frida-16x)
- [Global / Script Scope](#3-global--script-scope)
- [Process](#4-process)
- [Module](#5-module)
- [Memory](#6-memory)
- [NativePointer](#7-nativepointer)
- [NativeFunction & NativeCallback](#8-nativefunction--nativecallback)
- [Interceptor](#9-interceptor)
- [Stalker](#10-stalker)
- [Thread](#11-thread)
- [DebugSymbol](#12-debugsymbol)
- [CModule](#13-cmodule)
- [ObjC Bridge (iOS/macOS)](#14-objc-bridge-iosmacos)
- [Java Bridge (Android)](#15-java-bridge-android)
- [Socket](#16-socket)
- [File & I/O](#17-file--io)
- [Hexdump & Utilities](#18-hexdump--utilities)
- [Script IPC (send / recv)](#19-script-ipc-send--recv)
- [Frida.Compiler](#20-fridacompiler)
- [Arm64Writer / X86Writer / ThumbWriter](#21-arm64writer--x86writer--thumbwriter)
- [Platform Tips: iOS ARM64](#22-platform-tips-ios-arm64)
- [Platform Tips: Android](#23-platform-tips-android)
- [Quick Reference Table](#24-quick-reference-table)
1. Setup & Tooling
Install Frida and launch an agent against a target process over USB, TCP, or locally.
# Minimal working setup
pip install frida frida-tools
frida -U -f com.example.App -l script.js # spawn via USB
frida -U -F -l script.js # attach to frontmost iOS app
# Full tooling reference
pip install frida frida-tools
# Spawn and inject
frida -U -f com.example.App -l script.js # USB, spawn
frida -U -F -l script.js # USB, frontmost app (iOS)
frida -H 192.168.1.10:27042 -f com.example.App -l script.js # remote TCP
# Interactive REPL (ObjC/Java bridges auto-loaded in frida-tools 14+)
frida -U -F
# Compile TypeScript agent
frida-compile agent.ts -o agent.js
frida-compile agent.ts -o agent.js -w # watch mode
# Auto-trace functions by name or glob pattern
frida-trace -U -F -i "open" -I "NSURLSession*"
# Push frida-server to Android device
adb push frida-server /data/local/tmp/
adb shell "chmod +x /data/local/tmp/frida-server && /data/local/tmp/frida-server &"
# iOS (jailbroken): install via Cydia/Sileo — package: re.frida.server
2. Migration Notes from Frida 16.x
Frida 17 removed three categories of long-deprecated APIs — update existing scripts before running them against a 17.x agent.
// Quick migration checklist — if your script uses any of these patterns, update it:
// ❌ enumerateModulesSync() or callback-style enumerate → ✅ returns array directly
// ❌ Memory.readU32(ptr) → ✅ ptr.readU32()
// ❌ Module.getExportByName('lib', 'fn') → ✅ Process.getModuleByName('lib').getExportByName('fn')
// ❌ ObjC/Java globals without import in TS agents → ✅ import "frida-objc-bridge"
// ── Enumeration APIs ──────────────────────────────────────────────────────
// ❌ OLD
Process.enumerateModules({ onMatch(m) { ... }, onComplete() { } });
Process.enumerateModulesSync();
// ✅ NEW — returns array directly
for (const mod of Process.enumerateModules()) { console.log(mod.name); }
// ── Memory read/write ─────────────────────────────────────────────────────
// ❌ OLD
Memory.readU32(ptr('0x1234'));
Memory.writeU32(ptr('0x1234'), 100);
// ✅ NEW — methods on NativePointer, chainable
ptr('0x1234').readU32();
ptr('0x1234').writeU32(100);
ptr('0x1234').add(4).writeU32(10).add(4).writeU16(20);
// ── Static Module helpers ─────────────────────────────────────────────────
// ❌ OLD
Module.getBaseAddress('libc.so');
Module.getExportByName('libc.so', 'open');
Module.findExportByName('libc.so', 'open');
Module.ensureInitialized('libc.so');
// ✅ NEW
Process.getModuleByName('libc.so').base;
Process.getModuleByName('libc.so').getExportByName('open');
Process.getModuleByName('libc.so').findExportByName('open');
Module.getGlobalExportByName('open'); // replaces getExportByName(null, 'open')
// ── Runtime bridges ───────────────────────────────────────────────────────
// ObjC / Java / Swift no longer bundled in Frida core.
// frida-tools 14+ REPL auto-loads them. TypeScript agents must import explicitly:
import "frida-objc-bridge"; // provides ObjC global
import "frida-java-bridge"; // provides Java global
3. Global / Script Scope
Top-level globals and built-ins available in every Frida agent without any import.
// Typical agent preamble
const base = Process.mainModule.base;
const libc = Process.getModuleByName('libc.so');
const openAddr = libc.getExportByName('open');
send({ type: 'ready', base: base.toString() });
// Full global reference
ptr(val) // Create NativePointer from hex string or number
NULL // NativePointer(0x0)
Process // Current process introspection
Memory // Memory utilities (alloc, scan, patch, protect)
Interceptor // Function hook engine
Stalker // Code tracing engine
Thread // Thread enumeration + backtrace
DebugSymbol // Address ↔ symbol resolution
CModule // Inline C compilation
Module // Static module helpers (getGlobalExportByName, load)
ObjC // Objective-C runtime bridge (iOS/macOS)
Java // Android ART/JVM bridge
console // console.log / console.warn / console.error
hexdump(buf) // Pretty hex dump to string
send(msg, data?) // Send message + optional binary to Python host
recv(type, cb) // Register handler for message from Python host
rpc.exports // Expose JS functions as RPC callable from host
// Script lifecycle
Script.pin(); // Prevent GC of this script object
Script.unpin();
// Top-level await is supported
const result = await SomeAsyncOperation();
4. Process
Provides identity, module lookup, memory range enumeration, thread listing, and exception handling for the instrumented process.
// Log process info and look up a module
console.log(Process.id, Process.arch, Process.platform);
const libc = Process.getModuleByName('libc.so');
console.log('libc base:', libc.base, 'size:', libc.size);
// ── Identity ──────────────────────────────────────────────────────────────
Process.id // PID (number)
Process.arch // 'arm64' | 'x64' | 'arm' | 'ia32'
Process.platform // 'darwin' | 'linux' | 'windows' | 'freebsd'
Process.pageSize // page size in bytes
Process.pointerSize // 4 or 8
Process.codeSigningPolicy // 'optional' | 'required'
Process.mainModule // Module object for the main executable
Process.currentDir // working directory string
// ── Module lookup ─────────────────────────────────────────────────────────
Process.enumerateModules() // → Module[]
Process.getModuleByName('libc.so') // throws if not found
Process.findModuleByName('libc.so') // → Module | null
Process.getModuleByAddress(ptr('0x1234'))
Process.findModuleByAddress(ptr('0x1234'))
// ── Memory ranges ─────────────────────────────────────────────────────────
Process.enumerateRanges('r-x') // → RangeDetails[]
Process.enumerateRanges({ protection: 'r-x', coalesce: true })
Process.enumerateMallocRanges() // heap chunks
// RangeDetails: { base: NativePointer, size: number, protection: string,
// file?: { path, offset, size } }
// ── Threads ───────────────────────────────────────────────────────────────
Process.enumerateThreads() // → ThreadDetails[] (Frida threads hidden)
Process.getCurrentThreadId() // → number
// ── Exception handler ─────────────────────────────────────────────────────
Process.setExceptionHandler((details) => {
console.log('Exception:', details.type, details.address);
return false; // false = propagate to OS
});
5. Module
Represents a loaded binary (.so, .dylib, or executable) and exposes its exports, symbols, imports, and sections.
// Look up a module and find two exports without redundant lookups
const libc = Process.getModuleByName('libc.so');
const openFn = libc.getExportByName('open');
const readFn = libc.getExportByName('read');
console.log('open @', openFn, 'read @', readFn);
// ── Module object properties ──────────────────────────────────────────────
mod.name // 'libgame.so'
mod.path // full filesystem path
mod.base // NativePointer — load address
mod.size // size in bytes
// ── Instance methods (Frida 17+) ──────────────────────────────────────────
mod.enumerateImports() // → ImportDetails[]
mod.enumerateExports() // → ExportDetails[]
mod.enumerateSymbols() // → SymbolDetails[]
mod.enumerateSections() // → SectionDetails[]
mod.enumerateDependencies() // → string[]
mod.findExportByName('fn') // → NativePointer | null
mod.getExportByName('fn') // → NativePointer (throws if missing)
mod.findSymbolByName('_ZN…') // → NativePointer | null
mod.getSymbolByName('_ZN…') // → NativePointer
// ExportDetails: { type: 'function'|'variable', name: string, address: NativePointer }
// ── Static global helpers ─────────────────────────────────────────────────
Module.getGlobalExportByName('open') // search all loaded modules; throws if missing
Module.findGlobalExportByName('open') // → NativePointer | null
Module.load('/path/to/lib.so') // dlopen and return Module
6. Memory
Allocates, copies, protects, patches, and scans process memory.
// Allocate a C string and scan for its bytes
const buf = Memory.allocUtf8String('FIND_ME');
Memory.scan(buf, 8, '46 49 4e 44', {
onMatch(addr) { console.log('found at', addr); },
onError() {},
onComplete() {}
});
// ── Allocation ────────────────────────────────────────────────────────────
Memory.alloc(256) // zeroed buffer → NativePointer
Memory.allocUtf8String('hello') // null-terminated UTF-8
Memory.allocUtf16String('hello') // null-terminated UTF-16
Memory.allocByteArray(new Uint8Array([0x90, 0x90]))
// ── Copy / duplicate ──────────────────────────────────────────────────────
Memory.copy(dst, src, n) // copy n bytes src → dst
Memory.dup(src, n) // allocate + copy → new NativePointer
// ── Protection ────────────────────────────────────────────────────────────
Memory.protect(addr, size, 'rwx') // change page protection
Memory.queryProtection(addr) // → 'r-x' | 'rwx' | etc.
// ── Code patching (W^X safe) ──────────────────────────────────────────────
Memory.patchCode(addr, size, (code) => {
const w = new Arm64Writer(code, { pc: addr });
w.putNop();
w.flush();
});
// ── Scanning (async, callback-based — remains async in Frida 17) ──────────
// Pattern format: 'AA BB ?? DD' — ?? is a wildcard byte
Memory.scan(base, size, 'DE AD BE EF', {
onMatch(address, size) { console.log('found @', address); },
onError(reason) { /* skip unreadable pages */ },
onComplete() { }
});
// NOTE: Memory.readXxx() / Memory.writeXxx() static methods REMOVED in 17.
// Use NativePointer instance methods instead — see §7.
7. NativePointer
The universal address type in Frida — every memory address is a NativePointer with built-in arithmetic, read, and write methods.
// Read a simple struct: vtable pointer + two 32-bit fields
const obj = ptr('0x200000');
const vtbl = obj.readPointer();
const hp = obj.add(8).readU32();
const mp = obj.add(12).readU32();
console.log('vtable:', vtbl, 'hp:', hp, 'mp:', mp);
const p = ptr('0x100400000');
// ── Arithmetic (returns new NativePointer) ────────────────────────────────
p.add(0x10) p.sub(4)
p.and(0xFFF) p.or(1) p.xor(0xFF)
p.shl(2) p.shr(1) p.not()
// ── Comparison ────────────────────────────────────────────────────────────
p.equals(q) // boolean
p.compare(q) // -1 | 0 | 1
p.isNull()
// ── Conversion ────────────────────────────────────────────────────────────
p.toInt32() p.toUInt32()
p.toString() p.toString(16)
p.toMatchPattern() // → 'AA BB CC DD' byte string for use in Memory.scan
// ── Read ──────────────────────────────────────────────────────────────────
p.readPointer() // → NativePointer
p.readS8() p.readU8()
p.readS16() p.readU16()
p.readS32() p.readU32()
p.readS64() p.readU64()
p.readFloat() p.readDouble()
p.readByteArray(n) // → ArrayBuffer
p.readCString() // null-terminated ASCII/UTF-8
p.readUtf8String(len?)
p.readUtf16String(len?)
p.readAnsiString(len?) // Windows only
// ── Write (returns same NativePointer for chaining) ───────────────────────
p.writePointer(q)
p.writeS8(v) p.writeU8(v)
p.writeS16(v) p.writeU16(v)
p.writeS32(v) p.writeU32(v)
p.writeS64(v) p.writeU64(v)
p.writeFloat(v) p.writeDouble(v)
p.writeByteArray(arrayBuffer)
p.writeUtf8String('hello')
p.writeUtf16String('hello')
// ── Chaining ──────────────────────────────────────────────────────────────
ptr('0x5000')
.add(8).writeU32(100)
.add(4).writeU16(42)
.add(2).writeU8(1);
8. NativeFunction & NativeCallback
Wraps a native C function so it can be called directly from JavaScript, and creates a native-callable stub backed by a JavaScript function.
// Call strlen directly from JS
const strlen = new NativeFunction(
Module.getGlobalExportByName('strlen'), 'int', ['pointer']
);
console.log('length:', strlen(Memory.allocUtf8String('hello'))); // → 5
// ── NativeFunction: call any native function from JS ─────────────────────
const open = new NativeFunction(
Process.getModuleByName('libc.so').getExportByName('open'),
'int', // return type
['pointer', 'int'], // argument types
{ abi: 'default' } // optional: 'win64' | 'sysv' | 'stdcall' | 'fastcall'
);
const fd = open(Memory.allocUtf8String('/etc/hosts'), 0 /* O_RDONLY */);
// Supported type strings:
// 'void' 'bool' 'char' 'uchar' 'short' 'ushort' 'int' 'uint'
// 'long' 'ulong' 'longlong' 'ulonglong' 'float' 'double'
// 'pointer' 'size_t' 'ssize_t' 'int8_t' … 'uint64_t'
// ── NativeCallback: expose a JS function as a native C function ───────────
const myHook = new NativeCallback(
(a, b) => {
console.log('called with:', a, b);
return a + b;
},
'int', // return type
['int', 'int'] // argument types
);
// myHook is a NativePointer — pass it to Interceptor.replace() or any C API
9. Interceptor
The primary hooking engine — attaches onEnter/onLeave callbacks to observe any native function, or replaces it entirely with a new implementation.
// Log every call to open() and override the return value
Interceptor.attach(Module.getGlobalExportByName('open'), {
onEnter(args) {
console.log('[open]', args[0].readCString(), 'flags:', args[1].toInt32());
},
onLeave(retval) {
console.log('[open] fd =', retval.toInt32());
}
});
// ── attach: observe without replacing ─────────────────────────────────────
const hook = Interceptor.attach(targetPtr, {
onEnter(args) {
// args[n] → NativePointer (n-th argument)
// this.context → CpuContext: pc, sp, fp, x0–x28 (ARM64) / rax… (x64)
// this.threadId, this.returnAddress, this.depth, this.errno
this.savedArg = args[0].readUtf8String(); // stash state for onLeave
},
onLeave(retval) {
retval.replace(ptr(1)); // override return value
}
});
hook.detach(); // remove this specific
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [as0ler](https://github.com/as0ler)
- **Source:** [as0ler/skills](https://github.com/as0ler/skills)
- **License:** Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.