Commit Graph
48 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås 2f61937d75 agent: Bump @types/frida-gum to 19.11.0 2026-09-25 17:55:01 +02:00
Ole André Vadla Ravnås b092b17bc2 core: Fix disassembling what the map misses
Open through the r2 command so what it opens is mapped: the
disassembler skips whatever falls outside a map, and reading is not
enough. Drop the bin load, which only sniffed formats at address zero.

Let a failed read say so instead of returning null, remember the pages
that have none, and resolve an anchor live or not at all -- a stale
address lands on whatever occupies it now.
2026-09-10 16:30:19 +02:00
Ole André Vadla Ravnås 21121accb1 disassembler: Ask the agent for functions only
Analysis pulled every export, import and symbol across the wire
and then kept the handful that name code -- 87k rows for a
kernel, each carrying a type and an address as text.

Ask for what it uses instead: the offset, name and source of each
function the module knows about, chosen where the rows already
are.
2026-09-09 23:27:01 +02:00
Ole André Vadla Ravnås 0eca90a473 agent: Index module symbols as they are asked for
Every lookup built all three categories, gave each row a lowered
key to search by, and sorted each with a callback -- 14 seconds
before the first row of a kernel's 87k exports reached the view,
and most of it for rows nobody asked to see.

Keep what the runtime hands back, put it in order with the
engine's own sort, and report a row only when it goes out. Build
the text to search by when a query first arrives.
2026-09-09 20:54:41 +02:00
Ole André Vadla Ravnås 2360fcfa4d agent: Encode values without recursing
The encoder walked a value by calling itself through map(), and a
patch pass walked the tree again the same way. Inside a kernel,
where a script runs on a 16 KiB stack, that ran out after three
levels: each map() level costs a native frame plus two JS frames,
where a plain loop costs one.

Walk from an explicit list of what is left to encode, and let the
byte chunks patch themselves once their offsets are known, so the
second pass is gone.
2026-09-09 20:38:37 +02:00
Ole André Vadla Ravnås b88a9be290 Replace SwiftyMonaco with native editors
Drop the Monaco webview. Edit in a GtkSourceView on GTK and in a
native text view on Apple, both speaking to Frida.Compiler's
in-process language server for completions, signature help,
hovers and diagnostics.

Color, complete and indent code natively, matching the GitHub
theme in light and dark.
2026-09-08 19:52:31 +02:00
Ole André Vadla Ravnås 87ea1b4590 agent: Dedupe imports by name and origin
enumerateImports lists a symbol once per binding slot, so the same
import surfaced as several identical rows. Keep the first per
name+module.
2026-07-10 18:40:22 +02:00
Ole André Vadla Ravnås 035160a1e8 Paginate module symbols and focus filter with Cmd+F
Serve symbol pages by offset and step through them with prev/next
controls showing the current range. Reset to the first page when
the filter or category changes. Clamp the page index at the
mutation site and floor the offset in the agent so hammering
prev/next can't run past the ends into a negative range.

Bind Cmd+F (Ctrl+F on GTK) to focus the filter input.
2026-07-10 18:40:22 +02:00
Ole André Vadla Ravnås 4ffcbc31f3 Page module symbols to keep the UI responsive
Modules like YouTube Kids export 100k+ symbols. Enumerating and
marshalling the whole set per open stalled the UI, and both
frontends re-filtered the full arrays on the main thread on every
keystroke.

Build a cached, pre-sorted, pre-lowercased index in the agent and
serve filtered, capped pages. Add queryModuleSymbols returning a
window plus match and category counts. Wire both frontends to it
with a debounced filter; drop the client-side filtering.
2026-07-10 17:01:44 +02:00
Ole André Vadla Ravnås b9ea0cd1ba build: Bump @types/frida-gum to 19.8.0 2026-07-10 15:23:56 +02:00
Ole André Vadla Ravnås 93d9554993 agent: Share scope across REPL evaluations
Run each submission through indirect eval so declarations land
on the global object and persist. Rewrite a leading let/const to
var so it survives too, matching the Node REPL.
2026-07-06 18:06:13 +02:00
necpition205 79651b5407 Guard runtime parsing and rendering 2026-06-28 02:02:14 +02:00
Ole André Vadla Ravnås 8a5f13df97 Sort completions with properties before functions
Have the agent classify each member as callable via its property
descriptor (no getter side effects), then order properties ahead
of functions, alphabetically within each group.
2026-06-27 04:14:51 +02:00
Ole André Vadla Ravnås 1e4e3fdcde agent: Stop REPL completion dumping global scope
Return no members when the base expression fails to resolve instead
of falling back to the global scope.

Walk the prototype chain so resolved objects surface inherited
members.
2026-06-26 12:32:07 +02:00
Ole André Vadla Ravnås fb7972e500 agent: Cap ITrace by captures, not invocations
Consume a capture index only when a trace is actually recorded,
so raising the limit or re-arming resumes capture instead of
staying stuck at the old invocation count.
2026-06-24 13:23:19 +02:00
Ole André Vadla Ravnås 3823abc645 agent: Hex-encode vector registers
Vector registers are ArrayBuffers; toString rendered them as
"[object ArrayBuffer]".
2026-06-22 23:42:31 +02:00
Ole André Vadla Ravnås e26720355e agent: Skip undefined symbols in module view
Undefined entries have no address and merely duplicate the
imports list.
2026-06-22 23:42:31 +02:00
Ole André Vadla Ravnås acc9cdcb6b agent: Look up thread via findThreadById
Avoids enumerating all threads just to read one.
2026-06-19 13:59:28 +02:00
Ole André Vadla Ravnås 18477f66eb build: Bump @types/frida-gum to 19.7.0 2026-06-19 13:59:28 +02:00
Ole André Vadla Ravnås 81aad349b4 agent: Read thread registers via toJSON
Object.entries on the context returns nothing: register fields are
non-enumerable accessors. Use toJSON() to get all of them.
2026-06-18 17:15:57 +02:00
Ole André Vadla Ravnås 407c8ea6e2 build: Bump Frida deps and @types/frida-gum 2026-06-17 15:47:53 +02:00
Ole André Vadla Ravnås ebe973eb3c build: Bump frida deps and @types/frida-gum 2026-06-05 19:54:14 +02:00
Ole André Vadla Ravnås 7f4bdc65e0 build: Bump frida deps and @types/frida-gum 2026-06-02 12:42:32 +02:00
Ole André Vadla Ravnås de4c469393 itrace: Give each trace its own buffer
Drop the shared-buffer rendezvous. Each trace now owns its
buffer, created before Stalker is armed and announced to Luma
via a token-keyed start/ack handshake. The ack carries the
drain verdict: Luma remaps the buffer out-of-process while the
agent blocks, so an early crash still yields data; on
task_for_pid denial (cached per target) the agent drains and
pushes chunks itself.

Fold all itrace into the tracer instrument. Function-arm traces
and thread traces share one Trace registry; thread traces become
threadTraces config entries on a find-or-created tracer instance.
Core no longer exports itrace, and the drain agent keys its
readers by session so concurrent traces stay separate.
2026-05-31 15:12:17 +02:00
Ole André Vadla Ravnås 2ea83c5cae tracer: Update hooks in place, don't re-attach
Re-attaching the interceptor on an itrace_arming change relocated
its own live redirect as the original prologue, so the trampoline
dereferenced the hooked function's bytes as a pointer and crashed.

A hook's target never moves via update, so reconcile in place when
code and state are unchanged. Snapshot the pristine prologue at
first attach so arming a live hook still has the original bytes.
2026-05-31 03:26:52 +02:00
Ole André Vadla Ravnås 8d6f91fe1e Plumb image attachments through to the LLM
Console widgets get an appendImage / respond.image API on the
agent. read_widget_state surfaces image entries as attachments
scaled to at most max_dimension pixels (default 1568) on the
longest edge. Anthropic nests image blocks inside tool_result;
OpenAI gets a synthetic follow-up user message. The host scales
via CoreImage on macOS and GdkPixbuf on GTK.
2026-05-22 12:15:53 +02:00
Ole André Vadla Ravnås 202a6ad40a agent: Dedupe resolver matches sharing an address 2026-05-21 00:37:25 +02:00
Ole André Vadla Ravnås 12d5491c22 Sync disasm cache across collab
Identify a process instance by a deterministic identity returned
from the agent (per-OS, with a Process.mainModule + pid fallback)
and stash it on ProcessSession.processInfo. Rekey memory_page
into memory_page_module (module UUID + offset) so cached bytes
survive ASLR, and memory_page_anon (process identity + address)
for JIT / heap regions that only survive within one process
instance. Purge stale anon pages on every fresh attach.

Add updateProcessInfo, updateModuleAnalysis and updateInsight
SessionOps plus a side-channel publish-memory-page op and a
+fetch-memory-page request. The driver write-throughs every
page it fetches; non-drivers pull on miss and persist locally.
Module-analysis rows flow the same way so non-drivers can key
their cache by module UUID. The lab-join snapshot now carries
processInfo and module_analyses too.

Refresh actions on the insight detail view: Reread Bytes drops
the pages overlapping the visible range; Reanalyze Module drops
the module's analysis and pages, re-running r2 on next access.

The macOS detail view now reads the insight live from
insightsBySession via observation; GTK forwards .insightUpdated
into the detail and reschedules a refresh when the resolved
address changes.
2026-05-19 15:16:48 +02:00
Ole André Vadla Ravnås 143df80073 Bound disasm at function end
Persist per-session module analysis (executable ranges + known
functions, keyed by module name + LC_UUID) so on-demand
analysis runs once per binary and rebases on reattach. The
agent gains enumerateModuleRanges and getModuleIdentity; the
store gains a module_analysis table.

Disassembler queries $FB/$FE for the request address; when it
hits a function start, fetch via pDJ bounded to the function's
byte range. Otherwise fall back to pdJ N. Filter pdJ
decoration entries (xrefs, fcn headers, var summaries) that
share the addr of an instruction.

DisassemblyPage carries a scope (.function/.span) so the
SwiftUI and GTK insight views can disable loadMore when the
page is function-bounded. The disassemble AI tool surfaces the
scope too, so the model knows whether it has the whole
function or just an N-instruction span.

Go-to-Function-Start now opens (or selects) the insight rooted
at the function start, which then renders via the bounded
path.
2026-05-19 09:53:41 +02:00
Ole André Vadla Ravnås 20a8229d84 agent: Pass responder to onConsoleInput 2026-05-17 01:49:17 +02:00
Ole André Vadla Ravnås 88bda13f6c agent: Add appendValue on console widget 2026-05-17 00:55:15 +02:00
Ole André Vadla Ravnås e67e155fd7 agent: Reorder instrument.ts to newspaper order 2026-05-17 00:38:51 +02:00
Ole André Vadla Ravnås 8f6ccbc3f0 core: Add console widget kind
Hook packs and custom instruments can declare a console widget for
REPL-style input. Adds a WidgetConsoleEntry update kind, per-session
persistence, an agent-side appendConsole/onConsoleInput API, and a
ConsoleView-backed renderer card.

Regroups all widget kinds across the codebase as
counter, histogram, graph, list, table, hex, console
(aggregates, collections, raw, interactive).
2026-05-16 22:07:43 +02:00
Ole André Vadla Ravnås 40ac60baea build: Generate TS typings via bundle config
Bundle compiler reads Agent/bundle.json describing outputs,
bundles, typings, and externals. Package install is driven by
Agent/package.json + Agent/package-lock.json (managed via
frida-pm), so the lockfile is the source of truth for resolved
versions.

@types/frida-gum and @types/node are embedded into
LumaTypings.swift at build time; the Resources d.ts is no
longer checked in. Editor profiles append both as extra libs.
2026-05-15 18:09:41 +02:00
Ole André Vadla Ravnås e23043758a core: Expose structured event payloads to LLM
summarize_recent_events and wait_for_event embed each
event's payload as JSON with $type sentinels for
NativePointer, BigInt, Date, typed arrays, Map, Set, and
friends. Tracer events decode into named fields with
caller and backtrace pre-symbolicated.

Add read_event(event_id) for the full uncapped payload.

SymbolicateResult collapses to one struct with optional
offset and source. Agent symbolicate returns objects with
a numeric offset field.
2026-05-14 22:28:50 +02:00
Ole André Vadla Ravnås f3d35e9c32 tracer: Make hook state an enum
TracerConfig.Hook.State holds .enabled / .disabled, with
room for future cases (e.g. .muted: installed but no-op).
The mission tool's update_tracer_hook accepts a "state"
string; list/read return state as a string. The agent's
HookConfig wire format matches.
2026-05-11 21:47:47 +02:00
Ole André Vadla Ravnås 4a99bddc3e tracer: Remove unused isPinned hook field
Never read anywhere. Settable via update_tracer_hook, but
no UI, agent branch, or Swift consumer ever used the value.
2026-05-11 21:36:29 +02:00
Ole André Vadla Ravnås 479c0d51e6 Audit and expand MCP tools
Add write_memory, list_threads, list_session_instruments,
arm_session, disarm_session, list_address_insights, unpin_insight,
detach_session, read_widget_state, and invoke_widget_action.
read_memory grows an explicit format hint (hex/utf8/cstring);
eval_repl's description clarifies that the intent string lands
in the audit log.

Failure paths now emit a machine-readable code alongside the
human message (invalid_input, not_found, unavailable, rejected,
failed) so LLM-driven missions can react without parsing prose.
2026-05-10 22:57:17 +02:00
Ole André Vadla Ravnås 2b221f10d9 Add table, counter, histogram, hex widgets
Table mirrors list with multi-column rows + per-row actions and
configurable column alignment. Counter is a single big value
with optional unit and signed delta. Histogram supports both
setHistogram and incrementBucket and renders as a bar chart.
Hex shows a live binary buffer with a base address, capped to a
trailing window.

Agent SDK gains upsertRow/removeRow/setCounter/setHistogram/
incrementBucket/setHex on ctx.widget(id). Per-def TS narrows
table column ids and action ids the same way list actions are
narrowed; restored snapshots get matching shapes.
2026-05-10 22:03:32 +02:00
Ole André Vadla Ravnås 26d687cecd Wire widgets through agent, UI, and collab
Engine owns the widget state cache, applies inbound updates from
the agent, persists session-scoped widgets, and broadcasts to
collaborating peers (action invocations route to the host).
Renderers in both UIs read the cache and the unified update
stream, with a Clear button that propagates to peers.

Agent SDK adds ctx.widget(id) with push/upsertItem/removeItem/
clear, plus a typed onAction handler. create() now takes a
restored snapshot seeded from persisted state and the join
snapshot.

Per-def .d.ts narrows the widget map, restored shape, and action
union to the exact ids declared in the editor.
2026-05-10 21:02:42 +02:00
Ole André Vadla Ravnås 38fb69fa1a agent: Cap itrace by bytes per invocation
ITraceArming gains maxBytesPerInvocation (default 1 MB).
The itrace core polls each open session every 100 ms,
streams the drained chunk back via itrace:chunk, and stops
the session as soon as cumulative bytes cross the
threshold. The tracer config UI grows a second stepper for
the byte budget alongside the invocation counter, and
update_tracer_hook accepts max_bytes_per_invocation in
itrace_arming.
2026-05-10 11:03:12 +02:00
Ole André Vadla Ravnås 804086184e agent: Arm itrace with a max-invocations cap
Replace TracerConfig.Hook.itraceEnabled (Bool) with
itraceArming (ITraceArming?) carrying maxInvocations.
The agent only opens an itrace session while
callIndex < maxInvocations, so a flooding hook can no
longer flood the trace store. The tracer config UI gets a
stepper for the cap and shows captured/cap live, derived
from saved ITrace rows. update_tracer_hook now takes
itrace_arming as an object {max_invocations} or null to
disarm.
2026-05-10 10:51:09 +02:00
Ole André Vadla Ravnås 425aa555eb core: Unify ITrace concept and wire session node
Drop the dual ITraceCaptureRecord/CapturedITrace types in favour of
a single ITrace covering both function-call and thread origins.
Promote itrace-capture from an instrument into a core service so
both origins share the same start/stop/drain machinery.

ProcessNode now keys pending traces by an opaque session id, hands
finalized data to a TraceStore, throttles running emits, drains
in-process when no system-drain is available, and skips the
Interceptor-trampoline trim for thread origin. ModuleDelta carries
incremental module updates.

LumaDocument grows sqliteURL and tracesDirectory accessors so the
project file can be a directory holding both the index and
per-trace blobs.
2026-05-07 16:39:47 +02:00
Ole André Vadla Ravnås ca7914b715 core: Surface modules and threads from agent
Add agent-side observers for the live module list and thread list
plus an RPC to enumerate a module's exports/imports/symbols. Mirror
in LumaCore as ProcessThread and ModuleSymbolBundle.
2026-05-07 16:37:42 +02:00
Ole André Vadla Ravnås 32c7e3d557 tracer: Reword Java hint, show compiler errors
- Agent now says "The 'frida-java-bridge' package is required
  for Java tracing." when the module can't be imported, and
  "No Java runtime detected in this process." when the bridge
  is loaded but the target isn't a JVM. Neither conflates the
  two cases.
- Surface the actual compiler diagnostics from Engine.loadPackage
  when propagating an installed package fails, so "Compilation
  failed" doesn't stand alone in the log.
- Replace the inline error row with a rounded banner carrying a
  package icon, caption text, and a bordered Install button.
  The GTK side already renders a flat button + label in a row
  so string matching is the only update there.
2026-04-16 15:03:02 +02:00
Ole André Vadla Ravnås 2d7cb2ed58 tracer: Support Java method hooks via the bridge
Add a javaMethod anchor kind and the matching java-method scope
so the tracer can target JVM methods. Resolution uses
Java.enumerateMethods through the bridge; attachment replaces
each method's implementation and restores it on detach.

The bridge isn't bundled into our agent, since only one copy
can live in a process at a time. Instead it's marked external
so frida-compile leaves the imports as runtime lookups, and our
agent does `await import("frida-java-bridge")` on demand. If
the user hasn't installed the package via the Packages panel,
we surface a message pointing them there.

To let frida-compile honour the external, LumaBundleCompiler
grew a --external <name> flag that forwards to
BuildOptions.externals. Both the Xcode Run Script phase and the
GTK Makefile now pass --package [email protected] (for
TypeScript types) alongside --external frida-java-bridge (so
the runtime code isn't embedded).

Java resolves to no native address, so ProcessNode.resolve and
the instruction annotation map throw / skip rather than trying
to materialise one. The seed code for new Java hooks matches
frida-tools' pattern: log args via JSON.stringify.
2026-04-16 14:33:59 +02:00
Ole André Vadla Ravnås 126843ce10 tracer: Support objc/swift/debug-symbol scopes
Extend the resolver path so traced targets can be described by more
anchor kinds than just module exports. The agent now exposes a
unified resolveTargets RPC on top of Frida's ApiResolver (module,
objc, swift) plus DebugSymbol.findFunctionsMatching, and a
lookupAnchorAddress entry point that resolves a stored anchor back
to an address.

AddressAnchor gains objcMethod, swiftFunc, and debugSymbol cases
with matching Codable round-tripping. ProcessNode.resolve routes
the new cases through the agent; the sync fast-path only handles
anchors that don't require the target runtime.

Both Add-Hook UIs keep using scope:"function" for now so behaviour
is unchanged; Stage 2 will expose a scope picker. The search-result
rows now carry a pre-resolved AddressAnchor instead of reconstructing
module+export pairs, and subtitle switches are exhaustive over the
new cases.
2026-04-16 12:46:07 +02:00
Ole André Vadla Ravnås 92357bfd80 Add LumaCore package + cross-platform scaffolding
Lay the groundwork for a GTK/Adwaita frontend by extracting
shared infrastructure into a LumaCore Swift package. Agent
sources and LumaBundleCompiler move to top-level locations
so both the Xcode project and SPM can reference them.

New structure:
- Package.swift: root manifest with LumaCore lib + compiler
- Sources/LumaCore/: engine, persistence, models, and
  platform-abstracted token store
- Sources/LumaBundleCompiler/: moved from LumaBundleCompiler/
- Agent/: moved from Luma/Agent/
- LumaGtk/: skeleton GTK app package
2026-04-06 18:59:29 +02:00