Add r2flutter.str options to configure string parsing limits

This commit is contained in:
pancake committed 2026-10-01 17:41:24 +02:00
1 parent 49f174f3cd
commit 05c0616b37
7 files changed
+195 -74

No files matched your search

+13
View File
@@ -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.
+5
View File
@@ -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:
+5
View File
@@ -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;
+110 -74
View File
@@ -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;
+20
View File
@@ -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);
+1
View File
@@ -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;
+41
View File
@@ -0,0 +1,41 @@
NAME=r2-strings-config-mafia
FILE=bins/android/mafia/libapp.so
CMDS=<<EOF
L ../src/r2/core_flutter.dylib
L ../src/r2/core_flutter.so
e r2flutter.str.limit=3
r2flutter -q -zz
?e --
e r2flutter.str.filter=^https?://
r2flutter -q -zz
?e --
e r2flutter.str.filter=
e r2flutter.str.minlen=41
e r2flutter.str.maxlen=42
r2flutter -zz
?e --
e r2flutter.str.minlen=0
e r2flutter.str.maxlen=0
e r2flutter.str.limit=2
e r2flutter.str.filter=^ab
r2flutter -j -zz
EOF
EXPECT=<<EOF
<optimized out>
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