From 05c0616b3782422978cd0befc2b30af1c59ca41a Mon Sep 17 00:00:00 2001 From: pancake Date: Thu, 1 Oct 2026 17:41:24 +0200 Subject: [PATCH] Add r2flutter.str options to configure string parsing limits --- doc/learn.md | 13 +++ doc/support.md | 5 + include/r2flutter/dart_r2.h | 5 + src/lib/dart_pool_strings.c | 184 ++++++++++++++++++------------- src/r2/core_flutter.c | 20 ++++ src/tool/main.c | 1 + test/db/cmd/strings-config-mafia | 41 +++++++ 7 files changed, 195 insertions(+), 74 deletions(-) create mode 100644 test/db/cmd/strings-config-mafia diff --git a/doc/learn.md b/doc/learn.md index a4e36d7..72df3f2 100644 --- a/doc/learn.md +++ b/doc/learn.md @@ -1749,3 +1749,16 @@ lines come from `dart_pool_strings.c` (string references), not 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. + +## String dump config (`r2flutter.str.*`) + +`r2flutter.str.limit`, `.minlen`, `.maxlen` and `.filter` replace the old +hardcoded `DART_STRING_SCAN_LIMIT` (50000). The defaults are unlimited/empty: +no test sample reaches 50k carved strings (mafia ~41k in 0.7s), and the carved +regions are already capped by `DART_SNAPSHOT_SCAN_MAX`/`DART_DATA_IMAGE_SCAN_MAX`. +minlen/maxlen/filter only filter what `-z`/`-zz` print, because the carved list +also feeds enum recovery and string-ref population. `str.limit` caps printed +matches and only stops the `-zz` carving early (`ctx->str_scan_limit`) when no +filter is set; otherwise the scan would stop before reaching the matches. +Careful: `r_regex_check` returns `r_regex_exec` as-is, i.e. **false on match**; +compare `r_regex_exec (rx, s, 0, NULL, 0) == 0` explicitly. diff --git a/doc/support.md b/doc/support.md index bd2eece..fa3d736 100644 --- a/doc/support.md +++ b/doc/support.md @@ -390,6 +390,11 @@ Config keys: - `r2flutter.mapfile`: Flutter obfuscation map JSON path - `r2flutter.namepool`: enable heuristic name-pool fallback +- `r2flutter.profile`: override Dart snapshot profile by 32-byte hash or Dart version +- `r2flutter.str.limit`: max number of strings printed by `-z`/`-zz` (default `0`, unlimited); without filters it also stops the `-zz` carving early +- `r2flutter.str.minlen`: skip printing strings shorter than N (default `0`) +- `r2flutter.str.maxlen`: skip printing strings longer than N (default `0`, unlimited) +- `r2flutter.str.filter`: only print strings matching this extended regex (default empty) Plugin modifiers: diff --git a/include/r2flutter/dart_r2.h b/include/r2flutter/dart_r2.h index 6684f66..27b3fa7 100644 --- a/include/r2flutter/dart_r2.h +++ b/include/r2flutter/dart_r2.h @@ -81,6 +81,11 @@ typedef struct { int dump_fields; int dump_strings; bool dump_string_refs; + ut64 str_limit; // max strings to print (0 = unlimited) + ut64 str_scan_limit; // max strings to carve in the fuzzy scan (0 = unlimited) + int str_minlen; // skip printing strings shorter than this + int str_maxlen; // skip printing strings longer than this (0 = unlimited) + const char *str_filter; // only print strings matching this regex const char *obf_map_path; HtPP *obf_by_obfuscated; bool obf_map_tried; diff --git a/src/lib/dart_pool_strings.c b/src/lib/dart_pool_strings.c index 0de0b37..69998ca 100644 --- a/src/lib/dart_pool_strings.c +++ b/src/lib/dart_pool_strings.c @@ -26,7 +26,17 @@ void dart_string_list_free(RList *list) { r_list_free (list); } -#define DART_STRING_SCAN_LIMIT 50000 +typedef struct { + RList *list; + HtUP *seen_addrs; + ut64 ref_counter; + ut64 limit; // 0 means unlimited +} StringScan; + +static bool string_scan_full(const StringScan *ss) { + return ss->limit && (ut64)r_list_length (ss->list) >= ss->limit; +} + DartStringCategory dart_string_classify_value(const char *s) { if (R_STR_ISEMPTY (s)) { return DART_STRING_CAT_UNKNOWN; @@ -57,7 +67,7 @@ static const char *string_category_name(DartStringCategory cat) { } } -static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter); +static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, StringScan *ss); static bool should_scan_section(const RBinSection *sec); static bool is_common_text_punct(ut8 ch) { @@ -146,31 +156,28 @@ static void packed_string_record_fini(PackedStringRecord *rec) { rec->value = NULL; } -static void append_string_info(RList *list, HtUP *seen_addrs, const char *value, ut32 len, ut32 flags, ut64 addr, DartStringCategory cat, ut64 *ref_counter) { - if (!list || !value) { +static void append_string_info(StringScan *ss, const char *value, ut32 len, ut32 flags, ut64 addr, DartStringCategory cat) { + if (!value || string_scan_full (ss)) { return; } - if (r_list_length (list) >= DART_STRING_SCAN_LIMIT) { - return; - } - if (seen_addrs && addr && ht_up_find (seen_addrs, addr, NULL)) { + if (addr && ht_up_find (ss->seen_addrs, addr, NULL)) { return; } DartStringInfo *si = R_NEW0 (DartStringInfo); - si->ref_id = ref_counter? (*ref_counter)++: 0; + si->ref_id = ss->ref_counter++; si->length = len; si->flags = flags | DART_STRING_CANONICAL; si->address = addr; si->category = cat; si->references = r_list_newf ((RListFree)dart_string_ref_free); si->value = strdup (value); - r_list_append (list, si); - if (seen_addrs && addr) { - ht_up_insert (seen_addrs, addr, si); + r_list_append (ss->list, si); + if (addr) { + ht_up_insert (ss->seen_addrs, addr, si); } } -static void scan_ascii_strings(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { +static void scan_ascii_strings(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) { if (!buf || !size) { return; } @@ -190,7 +197,7 @@ static void scan_ascii_strings(const ut8 *buf, ut64 base, ut64 size, RList *list memcpy (tmp, buf + start, length); tmp[length] = '\0'; if (looks_like_text (tmp)) { - append_string_info (list, seen_addrs, tmp, (ut32)length, 0, base + start, dart_string_classify_value (tmp), ref_counter); + append_string_info (ss, tmp, (ut32)length, 0, base + start, dart_string_classify_value (tmp)); } free (tmp); } @@ -334,12 +341,12 @@ static bool parse_packed_string_record_text(const ut8 *buf, ut64 size, ut64 pos, return out->value != NULL; } -static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { - if (!buf || !size || !list) { +static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) { + if (!buf || !size) { return; } ut64 pos = 0; - while (pos < size && r_list_length (list) < DART_STRING_SCAN_LIMIT) { + while (pos < size && !string_scan_full (ss)) { PackedStringRecord probe = { 0 }; if (!parse_packed_string_record_text (buf, size, pos, &probe)) { pos++; @@ -372,9 +379,9 @@ static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, RList skips++; } if (n_records >= DART_PACKED_STRING_MIN_RUN) { - for (int i = 0; i < n_records && r_list_length (list) < DART_STRING_SCAN_LIMIT; i++) { + for (int i = 0; i < n_records && !string_scan_full (ss); i++) { PackedStringRecord *rec = &records[i]; - append_string_info (list, seen_addrs, rec->value, rec->length, rec->flags, base + rec->payload_off, dart_string_classify_value (rec->value), ref_counter); + append_string_info (ss, rec->value, rec->length, rec->flags, base + rec->payload_off, dart_string_classify_value (rec->value)); } pos = run_end; } else { @@ -386,8 +393,8 @@ static void scan_packed_string_runs(const ut8 *buf, ut64 base, ut64 size, RList } } -static void scan_packed_strings_from_snapshot(DartCtx *ctx, ut64 snapshot_base, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { - if (!ctx || !snapshot_base || !list) { +static void scan_packed_strings_from_snapshot(DartCtx *ctx, ut64 snapshot_base, StringScan *ss) { + if (!ctx || !snapshot_base) { return; } ut8 hdrbuf[12]; @@ -417,23 +424,23 @@ static void scan_packed_strings_from_snapshot(DartCtx *ctx, ut64 snapshot_base, if (ctx->verbose > 1) { fprintf (stderr, "[r2flutter] packed string scan snapshot=0x%" PFMT64x " cluster_start=0x%" PFMT64x " total=0x%" PFMT64x "\n", snapshot_base, snapshot_base + hdr.cluster_start, hdr.total_len); } - scan_packed_string_runs (buf + hdr.cluster_start, snapshot_base + hdr.cluster_start, hdr.total_len - hdr.cluster_start, list, seen_addrs, ref_counter); + scan_packed_string_runs (buf + hdr.cluster_start, snapshot_base + hdr.cluster_start, hdr.total_len - hdr.cluster_start, ss); free (buf); } #define DART_SNAPSHOT_SCAN_MAX (64ULL << 20) #define DART_DATA_IMAGE_SCAN_MAX (8ULL << 20) -static void scan_string_buffer(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { - if (!buf || !size || !list) { +static void scan_string_buffer(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) { + if (!buf || !size) { return; } - scan_ascii_strings (buf, base, size, list, seen_addrs, ref_counter); - scan_utf16_strings (buf, base, size, list, seen_addrs, ref_counter); + scan_ascii_strings (buf, base, size, ss); + scan_utf16_strings (buf, base, size, ss); } -static void scan_snapshot_region(DartCtx *ctx, ut64 start, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { - if (!ctx || !ctx->core || !ctx->core->bin || !start || !size || !list || size > DART_SNAPSHOT_SCAN_MAX) { +static void scan_snapshot_region(DartCtx *ctx, ut64 start, ut64 size, StringScan *ss) { + if (!ctx || !ctx->core || !ctx->core->bin || !start || !size || size > DART_SNAPSHOT_SCAN_MAX) { return; } ut64 end = start + size; @@ -468,16 +475,16 @@ static void scan_snapshot_region(DartCtx *ctx, ut64 start, ut64 size, RList *lis free (buf); continue; } - scan_string_buffer (buf, chunk_start, chunk_size, list, seen_addrs, ref_counter); + scan_string_buffer (buf, chunk_start, chunk_size, ss); free (buf); } } -static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base, ut64 upper_bound, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { - if (!ctx || !snapshot_base || !list) { +static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base, ut64 upper_bound, StringScan *ss) { + if (!ctx || !snapshot_base) { return; } - ut64 before_count = r_list_length (list); + ut64 before_count = r_list_length (ss->list); DartSnapshotHeader sh; if (!dart_snapshot_header_read (ctx, snapshot_base, &sh)) { goto fallback; @@ -486,10 +493,10 @@ static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base, goto fallback; } if (ctx->compressed_word_size == 4) { - scan_packed_strings_from_snapshot (ctx, snapshot_base, list, seen_addrs, ref_counter); + scan_packed_strings_from_snapshot (ctx, snapshot_base, ss); return; } - scan_snapshot_region (ctx, snapshot_base + sh.cluster_start, sh.total_len - sh.cluster_start, list, seen_addrs, ref_counter); + scan_snapshot_region (ctx, snapshot_base + sh.cluster_start, sh.total_len - sh.cluster_start, ss); ut64 align = ctx->layout && ctx->layout->max_alignment? (ut64)ctx->layout->max_alignment: 16; if (align == 0) { align = 16; @@ -497,18 +504,18 @@ static void scan_strings_from_snapshot_window(DartCtx *ctx, ut64 snapshot_base, ut64 data_start = snapshot_base + ((sh.total_len + (align - 1)) & ~ (align - 1)); ut64 data_end = upper_bound; if (data_end > data_start && (data_end - data_start) <= DART_DATA_IMAGE_SCAN_MAX) { - scan_snapshot_region (ctx, data_start, data_end - data_start, list, seen_addrs, ref_counter); + scan_snapshot_region (ctx, data_start, data_end - data_start, ss); } - if ((ut64)r_list_length (list) > before_count) { + if ((ut64)r_list_length (ss->list) > before_count) { return; } fallback: if (upper_bound > snapshot_base + 0x100 && (upper_bound - (snapshot_base + 0x100)) <= DART_DATA_IMAGE_SCAN_MAX) { - scan_snapshot_region (ctx, snapshot_base + 0x100, upper_bound - (snapshot_base + 0x100), list, seen_addrs, ref_counter); + scan_snapshot_region (ctx, snapshot_base + 0x100, upper_bound - (snapshot_base + 0x100), ss); } } -static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, RList *list, HtUP *seen_addrs, ut64 *ref_counter) { +static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, StringScan *ss) { if (!buf || size < 8) { return; } @@ -536,7 +543,7 @@ static void scan_utf16_strings(const ut8 *buf, ut64 base, ut64 size, RList *list if (utf8 && units >= 4 && utf16le_has_ascii_profile (buf, start, start + (units * 2))) { ut32 ulen = (ut32)strlen (utf8); if (ulen >= 4 && ulen <= 512 && looks_like_text (utf8)) { - append_string_info (list, seen_addrs, utf8, ulen, DART_STRING_TWO_BYTE, base + start, dart_string_classify_value (utf8), ref_counter); + append_string_info (ss, utf8, ulen, DART_STRING_TWO_BYTE, base + start, dart_string_classify_value (utf8)); } } r_strbuf_fini (&sb); @@ -583,16 +590,15 @@ RList *dart_pool_extract_strings(DartCtx *ctx) { return NULL; } RList *string_list = r_list_newf ((RListFree)dart_string_info_free); - HtUP *seen_addrs = ht_up_new0 (); - if (!seen_addrs) { - return string_list; - } RVecRBinSection *sections = r_bin_get_sections_vec (ctx->core->bin); if (!sections) { - ht_up_free (seen_addrs); return string_list; } - ut64 ref_counter = 0; + StringScan ss = { + .list = string_list, + .seen_addrs = ht_up_new0 (), + .limit = ctx->str_scan_limit + }; if (find_snapshots (ctx) == 0 && ctx->vm_data) { DartVerLayout layout_tmp; DartVerLayout *layout_owned = dart_ctx_init_layout (ctx, &layout_tmp); @@ -608,14 +614,14 @@ RList *dart_pool_extract_strings(DartCtx *ctx) { } else if (ctx->iso_instr > ctx->iso_data) { iso_upper = ctx->iso_instr; } - scan_strings_from_snapshot_window (ctx, ctx->vm_data, vm_upper, string_list, seen_addrs, &ref_counter); - scan_strings_from_snapshot_window (ctx, ctx->iso_data, iso_upper, string_list, seen_addrs, &ref_counter); + scan_strings_from_snapshot_window (ctx, ctx->vm_data, vm_upper, &ss); + scan_strings_from_snapshot_window (ctx, ctx->iso_data, iso_upper, &ss); if (r_list_length (string_list) == 0) { if (vm_upper > ctx->vm_data + 0x100) { - scan_snapshot_region (ctx, ctx->vm_data + 0x100, vm_upper - (ctx->vm_data + 0x100), string_list, seen_addrs, &ref_counter); + scan_snapshot_region (ctx, ctx->vm_data + 0x100, vm_upper - (ctx->vm_data + 0x100), &ss); } if (iso_upper > ctx->iso_data + 0x100) { - scan_snapshot_region (ctx, ctx->iso_data + 0x100, iso_upper - (ctx->iso_data + 0x100), string_list, seen_addrs, &ref_counter); + scan_snapshot_region (ctx, ctx->iso_data + 0x100, iso_upper - (ctx->iso_data + 0x100), &ss); } } dart_ctx_fini_layout (ctx, layout_owned); @@ -637,9 +643,9 @@ RList *dart_pool_extract_strings(DartCtx *ctx) { free (buf); continue; } - scan_string_buffer (buf, sec->vaddr, size, string_list, seen_addrs, &ref_counter); + scan_string_buffer (buf, sec->vaddr, size, &ss); free (buf); - if (r_list_length (string_list) >= DART_STRING_SCAN_LIMIT) { + if (string_scan_full (&ss)) { break; } } @@ -648,12 +654,12 @@ RList *dart_pool_extract_strings(DartCtx *ctx) { if (size > 0 && size <= DART_SNAPSHOT_SCAN_MAX) { ut8 *buf = (ut8 *)malloc ((size_t)size); if (buf && read_mem (ctx, 0, buf, (int)size)) { - scan_string_buffer (buf, 0, size, string_list, seen_addrs, &ref_counter); + scan_string_buffer (buf, 0, size, &ss); } free (buf); } } - ht_up_free (seen_addrs); + ht_up_free (ss.seen_addrs); r_list_sort (string_list, (RListComparator)string_info_addr_cmp); return string_list; } @@ -832,36 +838,62 @@ static void dump_string_text(RStrBuf *sb, const DartStringInfo *si, int fmt, boo } } +static bool string_matches(const DartCtx *ctx, const RRegex *rx, const DartStringInfo *si) { + if (!si || !si->value) { + return false; + } + if (ctx->str_minlen > 0 && si->length < (ut32)ctx->str_minlen) { + return false; + } + if (ctx->str_maxlen > 0 && si->length > (ut32)ctx->str_maxlen) { + return false; + } + return !rx || r_regex_exec (rx, si->value, 0, NULL, 0) == 0; +} + static char *dump_strings_list(DartCtx *ctx, RList *strings, int fmt) { - const bool refs = ctx && ctx->dump_string_refs; + RRegex *rx = NULL; + if (R_STR_ISNOTEMPTY (ctx->str_filter)) { + rx = r_regex_new (ctx->str_filter, "e"); + if (!rx) { + R_LOG_ERROR ("Invalid string filter regex: %s", ctx->str_filter); + return NULL; + } + } + const bool refs = ctx->dump_string_refs; + const bool quiet = ctx->quiet; + PJ *pj = NULL; + RStrBuf *sb = NULL; if (fmt == 'j') { - if (!strings || r_list_length (strings) == 0) { - return strdup ("[]"); - } - PJ *pj = pj_new (); + pj = pj_new (); pj_a (pj); - RListIter *it; - DartStringInfo *si; - r_list_foreach (strings, it, si) { - if (si) { - dump_string_json (pj, si, refs); - } - } - pj_end (pj); - return pj_drain (pj); + } else { + sb = r_strbuf_new (fmt == 'r' && !quiet? "# Dart Strings\n": ""); } - if (!strings) { - return strdup ("# No strings found\n"); - } - const bool quiet = ctx && ctx->quiet; - RStrBuf *sb = r_strbuf_new (fmt == 'r' && !quiet? "# Dart Strings\n": ""); + ut64 count = 0; RListIter *it; DartStringInfo *si; r_list_foreach (strings, it, si) { - dump_string_text (sb, si, fmt, quiet, refs); + if (ctx->str_limit && count >= ctx->str_limit) { + break; + } + if (!string_matches (ctx, rx, si)) { + continue; + } + if (pj) { + dump_string_json (pj, si, refs); + } else { + dump_string_text (sb, si, fmt, quiet, refs); + } + count++; + } + r_regex_free (rx); + if (pj) { + pj_end (pj); + return pj_drain (pj); } if (fmt == 'r' && !quiet) { - r_strbuf_appendf (sb, "# Total: %d strings\n", r_list_length (strings)); + r_strbuf_appendf (sb, "# Total: %" PFMT64u " strings\n", count); } return r_strbuf_drain (sb); } @@ -874,8 +906,12 @@ char *dart_pool_dump_strings(DartCtx *ctx, int fmt) { } char *dart_pool_dump_strings_fuzzy(DartCtx *ctx, int fmt) { + // stop carving early only when every scanned string is going to be printed + const bool filtered = ctx->str_minlen > 0 || ctx->str_maxlen > 0 || R_STR_ISNOTEMPTY (ctx->str_filter); + ctx->str_scan_limit = filtered? 0: ctx->str_limit; DartRecoveryModel model = { 0 }; dart_recovery_model_load (ctx, &model, DART_RECOVERY_STRINGS | DART_RECOVERY_CLASSES | DART_RECOVERY_STRING_REFS); + ctx->str_scan_limit = 0; char *out = dump_strings_list (ctx, model.strings, fmt); dart_recovery_model_fini (&model); return out; diff --git a/src/r2/core_flutter.c b/src/r2/core_flutter.c index eecaf2e..b22e0b0 100644 --- a/src/r2/core_flutter.c +++ b/src/r2/core_flutter.c @@ -12,6 +12,10 @@ #define R2FLUTTER_CFG_MAPFILE "r2flutter.mapfile" #define R2FLUTTER_CFG_NAMEPOOL "r2flutter.namepool" #define R2FLUTTER_CFG_PROFILE "r2flutter.profile" +#define R2FLUTTER_CFG_STR_LIMIT "r2flutter.str.limit" +#define R2FLUTTER_CFG_STR_MINLEN "r2flutter.str.minlen" +#define R2FLUTTER_CFG_STR_MAXLEN "r2flutter.str.maxlen" +#define R2FLUTTER_CFG_STR_FILTER "r2flutter.str.filter" typedef struct { char action; @@ -36,6 +40,14 @@ static bool r2flutter_core_init(RCorePluginSession *cps) { r_config_node_desc (node, "Enable heuristic name-pool fallback resolution"); node = r_config_set (cfg, R2FLUTTER_CFG_PROFILE, ""); r_config_node_desc (node, "Override Dart snapshot profile by 32-byte hash or Dart version"); + node = r_config_set_i (cfg, R2FLUTTER_CFG_STR_LIMIT, 0); + r_config_node_desc (node, "Maximum number of strings to print (0 = unlimited)"); + node = r_config_set_i (cfg, R2FLUTTER_CFG_STR_MINLEN, 0); + r_config_node_desc (node, "Skip printing strings shorter than this length"); + node = r_config_set_i (cfg, R2FLUTTER_CFG_STR_MAXLEN, 0); + r_config_node_desc (node, "Skip printing strings longer than this length (0 = unlimited)"); + node = r_config_set (cfg, R2FLUTTER_CFG_STR_FILTER, ""); + r_config_node_desc (node, "Only print strings matching this extended regex"); r_config_lock (cfg, true); return true; } @@ -49,6 +61,10 @@ static bool r2flutter_core_fini(RCorePluginSession *cps) { r_config_rm (cfg, R2FLUTTER_CFG_MAPFILE); r_config_rm (cfg, R2FLUTTER_CFG_NAMEPOOL); r_config_rm (cfg, R2FLUTTER_CFG_PROFILE); + r_config_rm (cfg, R2FLUTTER_CFG_STR_LIMIT); + r_config_rm (cfg, R2FLUTTER_CFG_STR_MINLEN); + r_config_rm (cfg, R2FLUTTER_CFG_STR_MAXLEN); + r_config_rm (cfg, R2FLUTTER_CFG_STR_FILTER); r_config_lock (cfg, true); #endif return true; @@ -57,6 +73,10 @@ static bool r2flutter_core_fini(RCorePluginSession *cps) { static void r2flutter_apply_config(RCore *core, DartCtx *dctx) { dctx->obf_map_path = r_config_get (core->config, R2FLUTTER_CFG_MAPFILE); dctx->use_name_pool = r_config_get_b (core->config, R2FLUTTER_CFG_NAMEPOOL); + dctx->str_limit = r_config_get_i (core->config, R2FLUTTER_CFG_STR_LIMIT); + dctx->str_minlen = (int)r_config_get_i (core->config, R2FLUTTER_CFG_STR_MINLEN); + dctx->str_maxlen = (int)r_config_get_i (core->config, R2FLUTTER_CFG_STR_MAXLEN); + dctx->str_filter = r_config_get (core->config, R2FLUTTER_CFG_STR_FILTER); const char *profile = r_config_get (core->config, R2FLUTTER_CFG_PROFILE); if (R_STR_ISNOTEMPTY (profile) && !dart_ctx_set_profile_override (dctx, profile)) { R_LOG_WARN ("Ignoring unsupported Dart snapshot profile override: %s", profile); diff --git a/src/tool/main.c b/src/tool/main.c index 17eb160..9e8655d 100644 --- a/src/tool/main.c +++ b/src/tool/main.c @@ -169,6 +169,7 @@ int main(int argc, char **argv) { break; case 'l': dctx.dump_fns_limit = atoi (opt.arg); + dctx.str_limit = r_num_get (NULL, opt.arg); break; case 'n': dctx.use_name_pool = true; diff --git a/test/db/cmd/strings-config-mafia b/test/db/cmd/strings-config-mafia new file mode 100644 index 0000000..a721112 --- /dev/null +++ b/test/db/cmd/strings-config-mafia @@ -0,0 +1,41 @@ +NAME=r2-strings-config-mafia +FILE=bins/android/mafia/libapp.so +CMDS=< +Handle +MonomorphicSmiableCall + +-- +http://www.w3.org/XML/1998/namespace +http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd +https://www.youtube.com/watch?v= + +-- +0x0004a5e8 42 :lib "_createBuiltInForegroundPainters@401245603" +0x0004b7d4 41 :lib "package:qr_flutter/src/qr_image_view.dart" +0x0004bab3 42 :lib "expected-closing-tag-but-got-right-bracket" + +-- +[{"ref":12,"len":8,"value":"abstract","category":"lib","two_byte":false,"canonical":true,"addr":2307},{"ref":209,"len":8,"value":"absolute","category":"lib","two_byte":false,"canonical":true,"addr":5339}] +EOF +RUN