100 Commits
Author SHA1 Message Date
pancake 02b0b84fa6 Release 0.6.0 2026-11-06 14:03:14 +01:00
pancake 0ee5e01498 Give duplicate Dart method names unique r2 flags and function names
r2 flag names are unique, so flagging a second function with a repeated
Dart name (e.g. Native._anon_closure) moved the flag away from the first
one, and current r2's af then named it after the Mach-O sym.func.* flag.
Suffix repeats with their address, use the same names for afs, and rename
analyzed functions after the af pass.

Also skip var recovery, call-following and jump tables in the signature
af pass (AuthPass -AAA 47s -> 29s) and raise R2R_TIMEOUT to 60s.
2026-11-06 13:54:07 +01:00
pancake cc338995cf Update mafia -z goldens for VM base-object pool strings 2026-11-06 13:37:57 +01:00
pancake 8a9e54be29 Support RVec fcn->bbs on R2_ABIVERSION >= 168 2026-11-05 12:57:12 +01:00
pancake 441d614937 Scan complete instruction ranges for standalone xrefs 2026-10-21 12:47:42 +02:00
pancake 25a5b3f026 Decode Record fields in snapshot value graphs 2026-10-21 12:46:56 +02:00
pancake 3bfdd5601a Resolve direct ObjectPool Code targets 2026-10-21 12:20:58 +02:00
pancake 84a25ea38c Resolve ObjectPool Field names and owners 2026-10-21 12:12:31 +02:00
pancake 2bf613618f Propagate ObjectPool collection strings into analysis 2026-10-21 10:52:18 +02:00
pancake a2fd82106e Include ObjectPool instance strings in -z output 2026-10-21 10:39:11 +02:00
pancake bd6f596279 Fix ObjectPool string xrefs through instance fields 2026-10-21 09:32:21 +02:00
pancake 878a588adf Release 0.5.0 2026-10-16 00:26:17 +02:00
pancake d0215dbfc2 Use r2-6.2.4 2026-10-16 00:26:09 +02:00
pancake 3cef0ce07a Fix signed 64-bit varint decoding
cs_read_tagged64 biased the final byte by -64 instead of -192, adding
128 << shift to every Mint/Smi value, which inflated field offsets and
decoded constants.
2026-10-09 16:05:25 +02:00
pancake 7d019ea748 Resolve class method entry points
Map each Function's code index (a raw InstructionTable slot, including
discarded-Code slots) to its entry address. Class-derived names only
replace placeholder names when merged into the function list, so
InstructionTable names stay authoritative for deduplicated code.
2026-10-09 16:05:23 +02:00
pancake f7c6cc5b3d Extract class metadata from Dart 2.14-3.3 snapshots
modern_can_extract_classes only accepted OBJECT_HEADER (3.4+) snapshots,
so CID_SHIFT1 apps such as Dart 2.19 fell back to the string heuristic
after the legacy parser failed. Gate on modern_supported instead.
2026-10-09 16:05:20 +02:00
pancake 24e3502737 Complete code xrefs for Dart 2.19 2026-10-06 17:50:40 +02:00
pancake 78719df43e Fix Dart 2.19 ObjectPool xrefs after Type fill parsing 2026-10-06 17:30:45 +02:00
pancake 3fe3c11bac Register the r2flutter pkg 2026-10-06 16:55:12 +02:00
pancake fa854fb648 Release 0.4.0 2026-10-06 00:43:14 +02:00
pancake a9efd1d262 doc: record x86-64 Dart AOT scan support 2026-10-02 12:33:45 +02:00
pancake 01db9e6b54 Seed anal.gp with the right PP register per arch
r2flutter_setup_pp_gp now sets anal.gpseed/anal.roregs to r15 on x86-64 and
x27 on arm64, so plain-r2 ESIL resolves [PP, off] pool loads on both.
2026-10-02 12:33:43 +02:00
pancake abcdbb2b11 Resolve x86-64 pool slots by adding back the heap tag
On x86-64 the pool pointer r15 carries the heap tag, so a [r15, off]
instruction offset is one less than the collector/arm64 slot offset. Detect
x64 from asm.arch/bits and add the tag (+1) back to get the canonical slot
offset used for the string/ref map lookups and the pool-slot address.

This makes the whole chain line up on x64: the code->pool-slot xref now lands
on the same slot the data-image string ref targets, pool strings resolve
inline, and a real code->string xref is emitted. On the Android x86_64 app
axt 0x76a97 now shows 'method.DioManager.initParams ... mov rax, [r15 +
str.https:__pss.aakredit.in_]' with the value inlined; resolved strings went
1455 -> 7411. arm64 is unchanged (slot_off == pp_off).
2026-10-02 12:33:40 +02:00
pancake 05ebbd2c2d Detect x86-64 pool loads and xref the pool slot from code
- flutter_reg_is_pp now recognises r15 (x64 PP) alongside x27 (arm64).
- Reclassify x86-64 'mov reg,[mem]' / 'mov [mem],reg' (typed MOV by r2) as
  LOAD/STORE via an effective op type, so the pool-load logic runs on x64.
- Emit a code->pool-slot xref (pp_base + off) on every pool load, for both
  arches, so axt on a slot shows the loading code - the 'link code to the PP
  table' that was missing.
- Drop the (pp_off & 7) alignment guard: it assumed arm64's even PP base and
  rejected x64's tagged-base odd offsets, and the has_pp_slot fix already
  prevents the field-deref it guarded against (arm64 still shows 0 misaligned).

x64 (an Android x86_64 app) went from 0 to 36467 PP refs; arm64 is unchanged
(w0rdle still 27388 PP refs, 0 misaligned).
2026-10-02 12:33:37 +02:00
pancake cd90ffe555 Recognize x86-64 registers and operand syntax in the scan
Add an x86-64 general-purpose register name->slot mapping (rax..r15, 32-bit
aliases) to flutter_reg_index and accept the x64 '[reg + disp]' memory operand
form alongside arm64's '[reg, disp]'. Foundation for scanning x64 Dart AOT
snapshots; arm64 behaviour is unchanged (names never collide).
2026-10-02 12:33:35 +02:00
pancake 05c0616b37 Add r2flutter.str options to configure string parsing limits 2026-10-01 17:41:24 +02:00
pancake 49f174f3cd Fix extras tests for tiered -A/-AA/-AAA and the analysis log line
- r2flutter-help: the help now lists -A/-AA/-AAA separately instead of
  -A[AA], so update both expected copies.
- analysis: run -qAAA and drop the EXPECT_ERR count line. The summary now
  carries the graph-xref count and the x22 fix changed the PP-ref total, and
  those counts also drift with the r2 build; the version-independent
  dart.class flag list remains the real assertion.
2026-10-01 17:01:12 +02:00
pancake cfb6448172 Dartpool refs moved into -AA and speedup AAA 2026-10-01 16:46:58 +02:00
pancake b7f425ca97 Apply dart pool refs to actual data strings with -AAA 2026-10-01 16:34:11 +02:00
pancake db30ebcb55 Annotate NULL_REG (x22) null/true/false idioms in -AAA
x22 caches Object::null() program-wide; the VM places null/true/false as
adjacent heap objects, so the compiler materialises booleans with add off
NULL_REG (true = null+0x20, false = null+0x30 on arm64, constant across Dart
versions and pointer compression). The scan now comments add x22,#0x20/#0x30
as true/false, mov from x22 as null, and compares against x22 as null checks -
the primitive the certificate-pinning bypass keys on. Verified on iOS
(cws=8) and Android (cws=4).
2026-10-01 14:30:49 +02:00
pancake 5651efc492 Expose the ObjectPool as anal.gp in r2flutter-A
x27/PP is the only Dart reserved register with a static address (the pool is
in the snapshot). r2flutter -A now seeds anal.gp with the pool base,
anal.gpseed=x27, anal.roregs=x27,gp,zero and an 'f PP' flag, so plain-r2
analysis/ESIL resolves [x27, off] pool loads - matching what -p -r already
set up. Resolution runs on a shallow DartCtx copy so the per-command read
cache (ctx->rmem) is not shared into the analysis DartApp and double-freed.
2026-10-01 14:30:46 +02:00
pancake a6fc7e4829 Fix PP mis-identification: a loaded pool value is not a PP pointer
The tracker marked the destination of a pool load as a PP pointer, so a later
[dst, field] deref was read as another slot: ldr x30,[x27,0x18] (a Code
object) then ldur x30,[x30,7] (entry-point) produced a bogus PP slot +0x1f,
and the blr reported 'indirect call via PP+0x1f'. Now:
- pp_load tags the dest with has_pp_slot/pp_slot (the slot it came from),
  never has_pp_off;
- flutter_process_pp_slot_deref carries that taint across the entry-point
  deref so the blr names the real slot and can xref it;
- a hard guard rejects any pp_off & 7, since valid slots are always
  word-aligned ((index+2)*8), killing every misaligned +0x..7 bogus comment.
2026-10-01 12:23:36 +02:00
pancake d0467e4e41 Resolve PP-slot comments to kind/name and add xrefs
After -AAA, non-string PP slots were left as bare 'dart: PP slot +0x..'
comments even though -O resolves them by hand. Resolve every slot up front
with modern_collect_direct_pool_refs and, in the analysis:
- inline the resolved name for function/class slots,
- add a navigable xref to the entrypoint for code/function slots (CALL for
  blr, DATA otherwise), mapping code_index through the instruction table,
- label every remaining slot by its kind, so none stays a bare offset.
2026-10-01 12:23:31 +02:00
pancake f35d5b569d Add modern_collect_direct_pool_refs batch pool resolver
Single-pass counterpart of the per-slot -O decode: walk every direct
(tagged, snapshotable) ObjectPool entry once and report its resolved
kind/name/cid/code_index via modern_resolve_pool_entry, the same resolver -O
uses. Non-object entries (native stubs, reset/bootstrap behaviors) are
labeled by kind; only plain immediates are skipped. Lets a caller resolve
tens of thousands of PP slots without building a value graph per slot.
2026-10-01 12:23:28 +02:00
pancake 2396599251 Clear dangling ctx->layout in the PP-string loader
dart_ctx_init_layout returns NULL (not an owned layout) when it loads the
layout into the caller's stack tmp buffer, leaving ctx->layout pointing at
that stack. The loader only cleared it when an owned layout came back, so on
return ctx->layout dangled and the next consumer of the shared DartCtx read
through freed stack. Clear it whenever we initialised it, regardless of the
return value.
2026-10-01 12:23:22 +02:00
pancake 7d283902f3 Support pre r2-6.2.4 triplets 2026-09-30 11:32:54 +02:00
pancake 30b8fe76d9 Improve the ci builds to make binary r2pm possible 2026-09-30 11:10:21 +02:00
pancake 3e12922ba0 Release 0.3.6 2026-09-08 13:30:40 +02:00
pancake 42b606ae7f Build the debian package in the ci 2026-09-08 13:30:06 +02:00
pancake 507994deda Add dist/debian 2026-09-08 13:26:00 +02:00
pancakeandClaude Opus 5 ce97e96eda Ship the r2 plugin in the windows zip and strip the binaries before packaging
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EUoqrdf1quwjg3MsThyq1B
2026-09-08 11:50:25 +02:00
pancake 2f8343b97b Release 0.3.4 2026-09-08 11:14:04 +02:00
pancake 5394a6f6e6 Use r_str_tok_r in the sbom parser to link on windows 2026-09-08 09:52:56 +02:00
pancake b2d8a4917a Fix the windows build by avoiding posix-only apis and translating the r2 flags for msvc 2026-09-08 09:52:56 +02:00
pancake 2f53ba301d Release 0.3.2 2026-09-07 21:49:17 +02:00
pancake 116aa82551 Release artifacts for windows linux and mac 2026-09-07 14:04:34 +02:00
pancake d80fa5bd2e Autorelease when pushing numeric tags 2026-09-07 13:58:56 +02:00
pancake ae66842877 Release 0.3.0 2026-09-07 13:01:47 +02:00
pancake e6b9eefae9 Use r2-6.2.2 2026-09-07 01:07:16 +02:00
pancake 5d86dff9fa Update all tests to use commands instead of !! oneliners 2026-09-03 18:09:11 +02:00
pancake 14c1847177 Probe Snapshot Layouts for Unknown Hashes 2026-09-01 16:18:24 +02:00
pancake edd90ba5c7 Retain Snapshot Object Value Graph 2026-09-01 15:36:07 +02:00
pancake a7317c7705 Retain Serialized Class Layout Metadata 2026-09-01 15:20:54 +02:00
pancake 3fe9dff0cc Support Dart 3.13 Single Snapshots 2026-09-01 15:16:12 +02:00
pancake 2e85b70bda Parse Versioned Code Cluster Layouts 2026-09-01 14:58:59 +02:00
pancake b45d487fd3 Handle Versioned ObjectPool Entry Bits 2026-09-01 14:54:37 +02:00
pancake b1994cd98e Add Versioned Snapshot Reference Decoding 2026-09-01 14:51:16 +02:00
pancake 3b9d12efea Parse Version-Specific Snapshot Headers 2026-09-01 14:46:26 +02:00
pancake f5d7bb15f1 List dae in the readme 2026-09-01 14:25:59 +02:00
pancake 66b294ab7c Use r2-6.2.0 in the ci 2026-08-22 12:20:03 +02:00
pancake 5a3da4b149 Add w0rdle test asserting recovered function signatures 2026-08-21 19:47:53 +02:00
pancake 545a2161ca Recover Dart function signatures with receiver and return types 2026-08-21 19:47:53 +02:00
pancake 6bad309eb6 Add w0rdle tests for ObjectPool decode, string/method recovery and header JSON 2026-08-21 18:47:48 +02:00
pancake 283242b724 Assert recovered w0rdle method names and pool strings in tests 2026-08-21 17:28:03 +02:00
pancake 81acc1c5df Decode ObjectPool and recover names/strings for Dart 2.x cws=4 snapshots 2026-08-21 17:28:03 +02:00
pancake 5d745cdd6b Add w0rdle Flutter crackme sample and regression tests 2026-08-21 16:43:11 +02:00
pancake 54c7aed1ba Performance improvement 1.6x for -x 2026-08-14 20:39:18 +02:00
pancakeandClaude Fable 5 75ad39a7cb Add macOS cws=8 class-extraction regression test
The cws=8 class/field extraction (f85bd3b) enabled the macOS OBJECT_HEADER
path but only iOS Runner goldens covered it. dump-classes-macos asserts
real class/field recovery on hello.aot (_Closure size=64, _Uri size=96,
field offsets) and, negatively, that the old size=0 fallback garbage is
gone. Verified as a real anchor: reverting the cws==8 gate fails all six
of its assertions.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-14 18:25:01 +02:00
pancake 1f36c65729 Use bin.lang=dart instead of repeating that attribute for all 2026-08-14 18:15:06 +02:00
pancake 2e9bb55763 Export class/method/field information for latest r2 2026-08-14 18:06:44 +02:00
pancake f85bd3beae Extract classes and fields from uncompressed (cws=8) snapshots 2026-08-14 10:24:14 +02:00
pancake 791547c855 Updated readme 2026-08-12 17:42:19 +02:00
pancake ef2fd323d7 Fix test with improved output 2026-08-12 16:09:49 +02:00
pancake bea45d8348 Better api names 2026-08-12 15:19:50 +02:00
pancake 43671cfcb3 Fix tests to use only r2 commands 2026-08-12 14:14:17 +02:00
pancake 2db2a74bc7 Fix pp string references on iOS, better perf and more testing 2026-08-12 13:41:45 +02:00
pancake 02efb309a2 Fix ppstring recovery in disasm and add tests 2026-08-12 12:55:44 +02:00
pancake 08001fe45b Tutorial to bypass ssl pinning on iOS/flutter 2026-08-12 12:30:46 +02:00
pancake b6ea0b8923 Synthetic legacy tags 2026-08-12 00:09:05 +02:00
pancake 540efcf5e1 Fix remaining iOS symbol recovery blockers 2026-08-11 21:07:03 +02:00
pancake 25dc49ef8f Fix -x reading JSON keys that pdj does not emit
* Side effect is 2x speedup
* 3 bugs fixed here affected to 96 instruction window when 28 ops is enough
2026-08-11 19:47:18 +02:00
pancake 6a7e01b0c9 Fix tags reads on iOS 2026-08-11 19:30:45 +02:00
pancake 334c97b88d Resolve the CID-table fallback via the newest profile 2026-08-11 17:13:51 +02:00
pancake f10d30dd6f Replace the fake CID enum with layout-resolved class ids
* Memoize cid table for 100x speedup in -x,-f,-c
* Fix Builtin.TypeName
2026-08-11 16:38:03 +02:00
pancakeandClaude Fable 5 f138b952c9 Fix discovery-stripped-ios test on r2 release builds
The r2 6.1.6 release parses the bare '>' redirect inside the quoted
!!sh -c one-liner and truncates the command, so the test produced no
output on CI while passing against r2 git. Move the pipeline into a
helper script so the r2 command line carries no quotes or redirects.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-11 15:54:30 +02:00
pancake 833f89a5d9 Remove legacy cluster walker 2026-08-11 15:49:26 +02:00
pancake 897a98d24d Unify the tag from cid getter for the 3 possible formats 2026-08-11 14:17:36 +02:00
pancake e9fa905562 Handle read-only clusters in uncompressed Dart snapshots 2026-08-11 14:08:07 +02:00
pancake 33bb19bbe0 Refactor modern snapshot parsing around a shared cluster walker 2026-08-11 13:31:11 +02:00
pancake d11ebc35b9 Fix modern fill rules for shifted Dart CIDs 2026-08-11 12:55:41 +02:00
pancakeandClaude Opus 4.8 5592349d99 Update TODO roadmap: rank by priority, record solved items
Rewrites the roadmap now that four items have landed. Adds a status table
(d387c0b fingerprinting/provenance, 2391781 explicit 3.7-3.12 profiles, cd6b655
discovery hardening, 0716a95 structural instruction location) and records the two
corrected assumptions worth remembering: the CID tables were already correct by
floor across 2.10-3.12, and the kDart* symbols survive strip.

Re-ranks everything P0..P4 by concrete failure instead of the old section order,
driven by a new finding: only 1 of 5 sample binaries (mafia, 3.9.2) exercises the
modern cluster decoder, because dart_modern_is_supported_snapshot() also gates on
compressed_word_size == 4. That makes two items P0 -- the modern_get_fill_spec
rules[] table is keyed on absolute 3.6/3.9-era CIDs and desyncs the fill stream on
Dart 3.4/3.5 compressed snapshots (cid 46 TYPE_ARGUMENTS read as LIBRARY_PREFIX,
89 ARRAY as CONST_SET), invisible to CI for exactly that reason; and widening the
modern decoder to uncompressed snapshots, which currently skips most iOS/macOS
samples. Also notes the new latent P2.3: the CID fallback still uses a literal
3.9.2 while unknown-hash fingerprinting now resolves to 3.12.0.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-11 12:32:38 +02:00
pancakeandClaude Opus 4.8 986e2cb42a Locate Dart instruction images without symbols on stripped Mach-O
The four kDart*Snapshot* symbols are external/global and load-bearing (the engine
resolves them at runtime), so they survive strip; but obfuscators/repackagers can
remove them, leaving only the two data snapshots findable by magic scan
(instruction images carry no magic) and iso_instr=0, which disables IT name
recovery.

Add locate_instr_images_structural(): vm_instr = start of the first executable
section; read the Dart Image header (word0=ImageSize) and chain
iso_instr = align_up(vm_instr + ImageSize, 64). Every step is cross-checked
(plausible headers; the isolate image must end where the first data image
begins), so an unknown/gapped layout degrades to 0 (no IT names) rather than junk
addresses. No-op when symbols already resolved the instructions.

Verified against symbol-derived ground truth: Runner (0x4000/0xe700, full 7671
IT entries recovered) and AuthPass (0x5a80/0xfdc0); the gapped macOS hello.aot
safely falls back to 0. Symbol-present bins unchanged; suite green (95 db/cmd,
3 extras, 35 custom).

Adds scripts/strip_macho_symbols.py (zeroes LC_SYMTAB + dyld export trie, since
strip cannot) and test/db/cmd/discovery-stripped-ios which builds the fixture
from the committed Runner App and asserts structural recovery. Remaining
follow-ups tracked in COMMIT2.md.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-11 12:32:01 +02:00
pancake cd6b655c0c Harden Dart snapshot discovery and drop bogus instruction-blob classification
* Only data snapshots carry the 0xf5f5dcdc magic
* A stray f5f5dcdc byte run could poison vm_instr/iso_instr on symbol-stripped Mach-O
* Preserve symbol-derived addresses instead of letting scan guesses overwrite them
2026-08-11 12:08:50 +02:00
pancake 239178152b Fill in the Dart 3.7-3.12 CID/layout tables 2026-08-11 11:29:36 +02:00
pancake d387c0b15b Harden unknown-hash handling and report version provenance
- Replaces the hardcoded 'v3.9.2 defaults' fallback
- Fix load_layout_from_json to use that profile on the -f/-A decode path for
  unknown hashes, instead of a degenerate zeroed layout (cws=0/alignment=0);
- Adds a version_source field to -H, guessed layout is never exact match now
2026-08-11 11:29:32 +02:00
pancake 19d8b96fc5 Fix build for latest r2 2026-07-23 14:12:33 +02:00
pancake 7e1803998e Fix build with latest r2 from git 2026-07-09 15:07:42 +02:00
pancake 4eede7cb33 Fix configure behaviour 2026-07-07 18:08:11 +02:00
pancake 48736a2a89 Properly set anal.roregs for x27 2026-07-07 16:15:27 +02:00
pancake f680d5551a Properly compute the pp.vaddr with baddr in mind 2026-07-07 16:09:27 +02:00