Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,9 @@ crash-*
corpus*
libr/anal/d/types-windows.sdb.txt
libr/bin/d/dll/*.c

# Personal work files
.personal_files/
TESTING_*.md
*:Zone.Identifier
test/db/cmd/*.backup
19 changes: 12 additions & 7 deletions libr/core/cbin.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ R_API bool r_core_bin_set_cur(RCore *core, RBinFile *binfile) {
return true;
}

static void _print_strings(RCore *core, RList *list, PJ *pj, int mode, int va) {
static void _print_strings(RCore *core, RList *list, PJ *pj, int mode, int va, int str_type_filter) {
RTable *table = r_core_table_new (core, "strings");
if (!table) {
return;
Expand Down Expand Up @@ -374,6 +374,10 @@ static void _print_strings(RCore *core, RList *list, PJ *pj, int mode, int va) {
const char *section_name, *type_string;
ut64 paddr = string->paddr;
ut64 vaddr = rva (core->bin, paddr, string->vaddr, va);
// Apply string type filter if specified
if (str_type_filter != 0 && string->type != str_type_filter) {
continue;
}
if (!r_bin_string_filter (bin, string->string, vaddr)) {
continue;
}
Expand Down Expand Up @@ -572,7 +576,7 @@ static void _print_strings(RCore *core, RList *list, PJ *pj, int mode, int va) {
R_CRITICAL_LEAVE (core);
}

static bool bin_raw_strings(RCore *core, PJ *pj, int mode, int va) {
static bool bin_raw_strings(RCore *core, PJ *pj, int mode, int va, int str_type_filter) {
RBinFile *bf = r_bin_cur (core->bin);
bool new_bf = false;
if (bf && strstr (bf->file, "malloc://")) {
Expand Down Expand Up @@ -613,7 +617,7 @@ static bool bin_raw_strings(RCore *core, PJ *pj, int mode, int va) {
va = false;
}
RList *l = r_bin_raw_strings (bf, 0);
_print_strings (core, l, pj, mode, va);
_print_strings (core, l, pj, mode, va, str_type_filter);
r_list_free (l);
if (new_bf) {
r_buf_free (bf->buf);
Expand All @@ -624,7 +628,7 @@ static bool bin_raw_strings(RCore *core, PJ *pj, int mode, int va) {
return true;
}

static bool bin_strings(RCore *core, PJ *pj, int mode, int va) {
static bool bin_strings(RCore *core, PJ *pj, int mode, int va, int str_type_filter) {
RBinFile *binfile = r_bin_cur (core->bin);
RBinPlugin *plugin = r_bin_file_cur_plugin (binfile);
int rawstr = r_config_get_i (core->config, "bin.str.raw");
Expand All @@ -646,7 +650,7 @@ static bool bin_strings(RCore *core, PJ *pj, int mode, int va) {
}
RList *list = r_bin_get_strings (core->bin);
if (list) {
_print_strings (core, list, pj, mode, va);
_print_strings (core, list, pj, mode, va, str_type_filter);
return true;
}
return false;
Expand Down Expand Up @@ -5045,6 +5049,7 @@ static bool bin_signature(RCore *core, PJ *pj, int mode) {
R_API bool r_core_bin_info(RCore *core, int action, PJ *pj, int mode, int va, RCoreBinFilter *filter, const char *chksum) {
R_RETURN_VAL_IF_FAIL (core, false);
const char *name = (filter && filter->name)? filter->name : NULL;
int str_type_filter = (filter && filter->str_type)? filter->str_type : 0;
bool ret = true;
ut64 at = UT64_MAX, loadaddr = r_bin_get_laddr (core->bin);
if (filter && filter->addr) {
Expand All @@ -5053,9 +5058,9 @@ R_API bool r_core_bin_info(RCore *core, int action, PJ *pj, int mode, int va, RC
// use our internal values for va
va = va ? VA_TRUE : VA_FALSE;
if ((action & R_CORE_BIN_ACC_RAW_STRINGS)) {
ret &= bin_raw_strings (core, pj, mode, va);
ret &= bin_raw_strings (core, pj, mode, va, str_type_filter);
} else if ((action & R_CORE_BIN_ACC_STRINGS)) {
ret &= bin_strings (core, pj, mode, va);
ret &= bin_strings (core, pj, mode, va, str_type_filter);
}
if ((action & R_CORE_BIN_ACC_INFO)) {
ret &= bin_info (core, pj, mode, loadaddr);
Expand Down
85 changes: 78 additions & 7 deletions libr/core/cmd_info.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,17 @@ static RCoreHelpMessage help_msg_ic = {
};

static RCoreHelpMessage help_msg_iz = {
"Usage: iz", "[][jq*]", "List strings",
"Usage: iz", "[auwW:charset][zjq*]", "List strings with optional type/charset filter",
"iz", "", "strings in data sections (in JSON/Base64)",
"iza", "", "show only ascii strings",
"izu", "", "show only utf8/unicode strings",
"izw", "", "show only wide (utf16) strings",
"izW", "", "show only wide32 (utf32) strings",
"iz:", "charset", "show only strings with specific charset (ascii, utf8, wide, wide32, base64)",
"iz,", "[:help]", "perform a table query on strings listing",
"iz-", " [addr]", "purge string via bin.str.purge",
"iz*", "", "print flags and comments r2 commands for all the strings",
"izz", "", "search for Strings in the whole binary",
"izz", "[auwW:charset]", "search for Strings in the whole binary (with optional type filter)",
"izz*", "", "same as iz* but exposing the strings of the whole binary",
"izzz", "", "dump Strings from whole binary to r2 shell (for huge files)",
NULL
Expand Down Expand Up @@ -1386,8 +1391,42 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v
}
}

// Helper to parse string type filter from command argument
static int parse_str_type_filter(const char ch, const char *name) {
if (ch) {
switch (ch) {
case 'a': return R_STRING_TYPE_ASCII;
case 'u': return R_STRING_TYPE_UTF8;
case 'w': return R_STRING_TYPE_WIDE;
case 'W': return R_STRING_TYPE_WIDE32;
case 'b': return R_STRING_TYPE_BASE64;
}
}
if (name) {
if (!strcmp (name, "ascii")) {
return R_STRING_TYPE_ASCII;
}
if (!strcmp (name, "utf8") || !strcmp (name, "unicode")) {
return R_STRING_TYPE_UTF8;
}
if (!strcmp (name, "wide") || !strcmp (name, "utf16")) {
return R_STRING_TYPE_WIDE;
}
if (!strcmp (name, "wide32") || !strcmp (name, "utf32")) {
return R_STRING_TYPE_WIDE32;
}
if (!strcmp (name, "base64")) {
return R_STRING_TYPE_BASE64;
}
}
return 0; // no filter
}

static void cmd_iz(RCore *core, PJ *pj, int mode, int is_array, bool va, const char *input) {
bool rdump = false;
int str_type_filter = 0;
RCoreBinFilter filter = {0};

if (input[1] == '-') { // "iz-"
char *strpurge = core->bin->strpurge;
ut64 addr = core->addr;
Expand All @@ -1408,6 +1447,20 @@ static void cmd_iz(RCore *core, PJ *pj, int mode, int is_array, bool va, const c
addr);
core->tmpseek = old_tmpseek;
} else if (input[1] == 'z') { // "izz"
// Check for type filter after izz
if (input[2] == 'a' || input[2] == 'u' || input[2] == 'w' || input[2] == 'W' || input[2] == 'b') {
str_type_filter = parse_str_type_filter (input[2], NULL);
input++;
} else if (input[2] == ':') { // "izz:charset"
const char *charset = input + 3;
str_type_filter = parse_str_type_filter (0, charset);
// Skip to end or next modifier
while (*input && *input != '*' && *input != 'j' && *input != 'q') {
input++;
}
input--; // Will be incremented in switch
}

switch (input[2]) {
case 'z':// "izzz"
rdump = true;
Expand Down Expand Up @@ -1440,11 +1493,27 @@ static void cmd_iz(RCore *core, PJ *pj, int mode, int is_array, bool va, const c
r_list_free (res);
}
} else {
RBININFO ("strings", R_CORE_BIN_ACC_RAW_STRINGS, NULL, 0);
filter.str_type = str_type_filter;
r_core_bin_info (core, R_CORE_BIN_ACC_RAW_STRINGS, pj, mode, va, &filter, NULL);
}
} else {
// "iz"
bool validcmd = true;

// Check for type filter after iz
if (input[1] == 'a' || input[1] == 'u' || input[1] == 'w' || input[1] == 'W' || input[1] == 'b') {
str_type_filter = parse_str_type_filter (input[1], NULL);
input++;
} else if (input[1] == ':') { // "iz:charset"
const char *charset = input + 2;
str_type_filter = parse_str_type_filter (0, charset);
// Skip to end or next modifier
while (*input && *input != ',' && *input != '*' && *input != 'j' && *input != 'q' && *input != ' ') {
input++;
}
input--; // Will be incremented below
}

switch (input[1]) {
case ',': // "iz,"
R_FREE (core->table_query);
Expand All @@ -1466,19 +1535,21 @@ static void cmd_iz(RCore *core, PJ *pj, int mode, int is_array, bool va, const c
input++;
break;
default:
// invalid subcommand handler?
// Could be end of filter, check if valid
if (str_type_filter) {
validcmd = true;
}
break;
}
if (validcmd) {
RList *bfiles = r_core_bin_files (core);
RListIter *iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
filter.str_type = str_type_filter;
r_list_foreach (bfiles, iter, bf) {
core->bin->cur = bf;
RBinObject *bo = r_bin_cur_object (core->bin);
RBININFO ("strings", R_CORE_BIN_ACC_STRINGS, NULL,
(bo && bo->strings)? r_list_length (bo->strings): 0);
r_core_bin_info (core, R_CORE_BIN_ACC_STRINGS, pj, mode, va, &filter, NULL);
}
core->bin->cur = cur;
r_list_free (bfiles);
Expand Down
1 change: 1 addition & 0 deletions libr/include/r_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ R_API void r_core_recover_vars(RCore *core, RAnalFunction *fcn, bool argonly);
typedef struct r_core_bin_filter_t {
ut64 addr;
const char *name;
int str_type; // filter strings by type (0 = no filter, 'a' = ascii, 'u' = utf8, 'w' = wide, 'W' = wide32, 'b' = base64)
} RCoreBinFilter;

R_API bool r_core_bin_info(RCore *core, int action, PJ *pj, int mode, int va, RCoreBinFilter *filter, const char *chksum);
Expand Down
Loading