Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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};

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty lines with a tab

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as reported by the lint script: ibr/core/cmd_info.inc.c:1429:
libr/core/cmd_info.inc.c:1463:
libr/core/cmd_info.inc.c:1502:
libr/core/cmd_info.inc.c:1516:

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