mirror of
https://github.com/radareorg/r2flutter.git
synced 2026-11-07 06:26:00 -10:00
Apply dart pool refs to actual data strings with -AAA
This commit is contained in:
1 parent
db30ebcb55
commit
b7f425ca97
5 files changed
+96
-2
No files matched your search
@@ -1724,3 +1724,28 @@ This is exactly the primitive the FatalSec talk's Frida bypass keys on
|
||||
Verified count on AuthPass: ~6k true, ~7k false, ~31k null, ~23k null-compares.
|
||||
x26 (THR, the thread register with a large fixed-offset table of runtime stubs)
|
||||
is the natural next target but is version-specific and left as a follow-up.
|
||||
|
||||
## Apply data-image string references so axt resolves pool strings
|
||||
|
||||
A string loaded only through a const data structure (e.g. a `Uri` or a list of
|
||||
endpoints) is never loaded by a `ldr [x27, off]` in code, so the -AAA scan,
|
||||
which only walks disassembled functions, created no xref for it. `axt
|
||||
0x<string>` came back empty even though the string is clearly used. Example
|
||||
(an Android app): `https://pss.aakredit.in/` at 0x76a97 is referenced from a
|
||||
const object at 0x13a945 in `.rodata`; the scan never visits `.rodata`.
|
||||
|
||||
The reference was already recoverable - `r2flutter -z`/`-xz -r` lists each
|
||||
reliable ObjectPool string with its reference sites (`DartStringRef.source_addr`,
|
||||
including data-image addresses) and emits `ax <string> <source>` - but only as a
|
||||
script that nothing applied, and -AAA never ran it. -AAA now calls
|
||||
`dart_pool_apply_xrefs`, which walks `dart_pool_extract_pool_strings` and sets a
|
||||
real STRN xref from every `source_addr` to the string, so `axt` resolves
|
||||
pool-referenced strings that no instruction loads directly (4195 such xrefs on
|
||||
that app).
|
||||
|
||||
Gotcha: `-xz` resolves to the strings action (`z`), not xrefs (`x`) - the `ax`
|
||||
lines come from `dart_pool_strings.c` (string references), not
|
||||
`dart_pool_extract_xrefs` (which only yields metadata refs with no source
|
||||
address). The apply runs on a shallow DartCtx copy with its own read cache for
|
||||
the same reason as `r2flutter_setup_pp_gp`: the scan has already mutated
|
||||
app->dctx, and extraction needs the pristine state the standalone command sees.
|
||||
@@ -203,6 +203,7 @@ char *dart_pool_dump_strings(DartCtx *ctx, int fmt);
|
||||
char *dart_pool_dump_strings_fuzzy(DartCtx *ctx, int fmt);
|
||||
void dart_string_list_free(RList *list);
|
||||
char *dart_pool_dump_xrefs(DartCtx *ctx, int fmt);
|
||||
int dart_pool_apply_xrefs(DartCtx *ctx);
|
||||
char *dart_pool_dump_sbom(DartCtx *ctx, const char *input_path, int fmt);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -1015,3 +1015,42 @@ char *dart_pool_dump_xrefs(DartCtx *ctx, int fmt) {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Apply the recovered xref graph to the RCore as real r2 xrefs. Unlike the
|
||||
// analysis disassembly scan, which only sees loads inside functions, this also
|
||||
// surfaces references that live in the data image (e.g. a const object in
|
||||
// .rodata pointing at a string), so `axt` resolves pool-referenced strings that
|
||||
// no instruction loads directly. Returns the number of xrefs applied.
|
||||
int dart_pool_apply_xrefs(DartCtx *ctx) {
|
||||
if (!ctx || !ctx->core || !ctx->core->anal) {
|
||||
return 0;
|
||||
}
|
||||
// The reliable ObjectPool strings carry their reference sites (source_addr),
|
||||
// including references that live in the data image (e.g. a const object in
|
||||
// .rodata pointing at the string). The analysis disassembly scan only sees
|
||||
// loads inside functions, so without this `axt <string>` is empty for
|
||||
// strings no instruction loads directly.
|
||||
RList *strings = dart_pool_extract_pool_strings (ctx);
|
||||
if (!strings) {
|
||||
return 0;
|
||||
}
|
||||
int applied = 0;
|
||||
RListIter *it;
|
||||
DartStringInfo *si;
|
||||
r_list_foreach (strings, it, si) {
|
||||
if (!si || !si->address || !si->references) {
|
||||
continue;
|
||||
}
|
||||
RListIter *rit;
|
||||
DartStringRef *sr;
|
||||
r_list_foreach (si->references, rit, sr) {
|
||||
if (!sr || sr->source_addr == 0) {
|
||||
continue;
|
||||
}
|
||||
r_anal_xrefs_set (ctx->core->anal, sr->source_addr, si->address, R_ANAL_REF_TYPE_STRN | R_ANAL_REF_TYPE_READ);
|
||||
applied++;
|
||||
}
|
||||
}
|
||||
dart_string_list_free (strings);
|
||||
return applied;
|
||||
}
|
||||
@@ -1425,15 +1425,31 @@ bool r2flutter_analysis_run(RCore *core, DartCtx *dctx, bool quiet) {
|
||||
flutter_ensure_functions (core, entries);
|
||||
flutter_scan_functions (core, &model, &pp_strings, &pp_refs, entries, &stats);
|
||||
|
||||
// Apply the recovered xref graph (including data-image references such as a
|
||||
// const object pointing at a string) so `axt` resolves pool-referenced
|
||||
// strings that no instruction loads directly. Run it on a clean copy of the
|
||||
// original context - the scan above mutates app->dctx (read cache, layout),
|
||||
// and dart_pool_extract_xrefs needs the same pristine state the standalone
|
||||
// `-x` command sees. The copy shares heap-owned pointers, so we free only
|
||||
// the read cache it allocates.
|
||||
DartCtx xrctx = *dctx;
|
||||
xrctx.core = core;
|
||||
xrctx.rmem = NULL;
|
||||
xrctx.layout = NULL;
|
||||
xrctx.dump_string_refs = true;
|
||||
int graph_xrefs = dart_pool_apply_xrefs (&xrctx);
|
||||
dart_read_cache_free (xrctx.rmem);
|
||||
|
||||
if (!quiet) {
|
||||
R_LOG_INFO ("Flutter analysis: %d functions, %d calls, %d fields, %d classes, %d types, %d strings, %d PP refs",
|
||||
R_LOG_INFO ("Flutter analysis: %d functions, %d calls, %d fields, %d classes, %d types, %d strings, %d PP refs, %d graph xrefs",
|
||||
(int)stats.functions,
|
||||
(int)stats.call_xrefs,
|
||||
(int)stats.field_refs,
|
||||
(int)stats.class_refs,
|
||||
(int)stats.type_refs,
|
||||
(int)stats.string_refs,
|
||||
(int)stats.pp_refs);
|
||||
(int)stats.pp_refs,
|
||||
graph_xrefs);
|
||||
}
|
||||
|
||||
RVecFlutterEntry_free (entries);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
NAME=r2-pp-string-dataref-xref-android
|
||||
FILE=bins/android/w0rdle/libapp.so
|
||||
ARGS=-NN -e scr.color=0 -e bin.relocs.apply=true
|
||||
CMDS=<<EOF2
|
||||
L ../src/r2/core_flutter.so
|
||||
L ../src/r2/core_flutter.dylib
|
||||
r2flutter -AAA
|
||||
axt 0x177f3~0xdc8f7[1]
|
||||
EOF2
|
||||
EXPECT=<<EOF2
|
||||
0xdc8f7
|
||||
EOF2
|
||||
RUN
|
||||
Reference in new issue
Block a user