Skip to content

Commit 4159d8e

Browse files
committed
Refine the output of izx command
1 parent 2760a7d commit 4159d8e

File tree

2 files changed

+77
-10
lines changed

2 files changed

+77
-10
lines changed

librz/core/cbin.c

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2686,7 +2686,7 @@ RZ_API bool rz_core_bin_segments_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBin
26862686
return true;
26872687
}
26882688

2689-
static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector /*<RzBinString *>*/ *vec) {
2689+
static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector /*<RzBinString *>*/ *vec, bool print_xref) {
26902690
bool b64str = rz_config_get_i(core->config, "bin.b64str");
26912691
int va = (core->io->va || core->bin->is_debugger) ? VA_TRUE : VA_FALSE;
26922692
RzBinObject *obj = rz_bin_cur_object(core->bin);
@@ -2696,7 +2696,11 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
26962696
RzBinSection *section;
26972697

26982698
rz_cmd_state_output_array_start(state);
2699-
rz_cmd_state_output_set_columnsf(state, "nXXnnsss", "nth", "paddr", "vaddr", "len", "size", "section", "type", "string");
2699+
if (print_xref) {
2700+
rz_cmd_state_output_set_columnsf(state, "XXsnnssss", "paddr", "vaddr", "flag", "len", "size", "section", "type", "xref-from", "string");
2701+
} else {
2702+
rz_cmd_state_output_set_columnsf(state, "nXXnnsss", "nth", "paddr", "vaddr", "len", "size", "section", "type", "string");
2703+
}
27002704

27012705
RzBinString b64 = { 0 };
27022706
rz_pvector_foreach (vec, iter) {
@@ -2705,6 +2709,40 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
27052709
char quiet_val[20];
27062710
ut64 paddr, vaddr;
27072711
paddr = string->paddr;
2712+
2713+
char *xref_address_str = NULL;
2714+
char *flag_name_str = NULL;
2715+
if (print_xref) {
2716+
// search xrefs to string
2717+
RzList *xrefs = rz_analysis_xrefs_get_to(core->analysis, paddr);
2718+
RzAnalysisXRef *xref;
2719+
RzListIter *xrefIter;
2720+
RzStrBuf *xref_addresses = rz_strbuf_new("");
2721+
rz_list_foreach (xrefs, xrefIter, xref) {
2722+
char addr_str[32];
2723+
snprintf(addr_str, sizeof(addr_str), "0x%08" PFMT64x, xref->from);
2724+
if (rz_strbuf_length(xref_addresses) > 0) {
2725+
rz_strbuf_append(xref_addresses, ",");
2726+
}
2727+
rz_strbuf_append(xref_addresses, addr_str);
2728+
}
2729+
rz_list_free(xrefs);
2730+
xref_address_str = rz_strbuf_drain(xref_addresses);
2731+
2732+
// search possible flag
2733+
const RzList *flags = rz_flag_get_list(core->flags, paddr);
2734+
RzFlagItem *flag;
2735+
RzListIter *flagIter;
2736+
RzStrBuf *flag_names = rz_strbuf_new("");
2737+
rz_list_foreach (flags, flagIter, flag) {
2738+
if (rz_strbuf_length(flag_names) > 0) {
2739+
rz_strbuf_append(flag_names, ",");
2740+
}
2741+
rz_strbuf_append(flag_names, flag->name);
2742+
}
2743+
flag_name_str = rz_strbuf_drain(flag_names);
2744+
}
2745+
27082746
vaddr = obj ? rva(obj, paddr, string->vaddr, va) : paddr;
27092747
if (!rz_bin_string_filter(core->bin, string->string, vaddr)) {
27102748
continue;
@@ -2742,12 +2780,18 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
27422780
pj_o(state->d.pj);
27432781
pj_kn(state->d.pj, "vaddr", vaddr);
27442782
pj_kn(state->d.pj, "paddr", paddr);
2745-
pj_kn(state->d.pj, "ordinal", string->ordinal);
2783+
if (!print_xref) {
2784+
pj_kn(state->d.pj, "ordinal", string->ordinal);
2785+
}
27462786
pj_kn(state->d.pj, "size", string->size);
27472787
pj_kn(state->d.pj, "length", string->length);
27482788
pj_ks(state->d.pj, "section", section_name);
27492789
pj_ks(state->d.pj, "type", type_string);
27502790
// data itself may be encoded so use pj_ks
2791+
if (print_xref) {
2792+
pj_ks(state->d.pj, "flag", flag_name_str);
2793+
pj_ks(state->d.pj, "xref-from", xref_address_str);
2794+
}
27512795
pj_ks(state->d.pj, "string", string->string);
27522796

27532797
switch (string->type) {
@@ -2836,9 +2880,15 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
28362880
break;
28372881
}
28382882
char *bufstr = rz_strbuf_drain(buf);
2839-
rz_table_add_rowf(state->d.t, "nXXddsss", (ut64)string->ordinal, paddr, vaddr,
2840-
(int)string->length, (int)string->size, section_name,
2841-
type_string, bufstr);
2883+
if (print_xref) {
2884+
rz_table_add_rowf(state->d.t, "XXsnnssss", paddr, vaddr, flag_name_str,
2885+
(int)string->length, (int)string->size, section_name,
2886+
type_string, xref_address_str, bufstr);
2887+
} else {
2888+
rz_table_add_rowf(state->d.t, "nXXddsss", (ut64)string->ordinal, paddr, vaddr,
2889+
(int)string->length, (int)string->size, section_name,
2890+
type_string, bufstr);
2891+
}
28422892
free(bufstr);
28432893
free(no_dbl_bslash_str);
28442894
break;
@@ -2860,6 +2910,8 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
28602910
break;
28612911
}
28622912
free(escaped_string);
2913+
free(flag_name_str);
2914+
free(xref_address_str);
28632915
}
28642916
RZ_FREE(b64.string);
28652917
rz_cmd_state_output_array_end(state);
@@ -2870,7 +2922,7 @@ RZ_API bool rz_core_bin_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinF
28702922
rz_return_val_if_fail(core && bf && state, false);
28712923

28722924
const RzPVector *vec = rz_bin_object_get_strings(bf->o);
2873-
return strings_print(core, state, vec);
2925+
return strings_print(core, state, vec, false);
28742926
}
28752927

28762928
/***
@@ -2941,7 +2993,7 @@ RZ_API bool rz_core_bin_whole_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL
29412993
if (!l) {
29422994
return false;
29432995
}
2944-
bool res = strings_print(core, state, l);
2996+
bool res = strings_print(core, state, l, false);
29452997
rz_pvector_free(l);
29462998
return res;
29472999
}
@@ -2965,7 +3017,7 @@ RZ_API bool rz_core_bin_xrefs_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL
29653017
void **iter;
29663018
rz_pvector_foreach (whole_strings, iter) {
29673019
RzBinString *string = *iter;
2968-
const RzList *list = rz_analysis_xrefs_get_to(core->analysis, string->paddr);
3020+
RzList *list = rz_analysis_xrefs_get_to(core->analysis, string->paddr);
29693021
const RzAnalysisXRef *xref;
29703022
const RzListIter *iterator;
29713023
rz_list_foreach (list, iterator, xref) {
@@ -2980,8 +3032,9 @@ RZ_API bool rz_core_bin_xrefs_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL
29803032
break;
29813033
}
29823034
}
3035+
rz_list_free(list);
29833036
}
2984-
bool res = strings_print(core, state, xrefs_strings);
3037+
bool res = strings_print(core, state, xrefs_strings, true);
29853038
rz_pvector_free(whole_strings);
29863039
rz_pvector_free(xrefs_strings);
29873040
return res;

test/db/cmd/cmd_i

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5139,3 +5139,17 @@ EXPECT=<<EOF
51395139
[{"vaddr":0,"paddr":0,"ordinal":0,"size":28,"length":27,"section":"","type":"ascii","string":"{} \" \\\" \\ \\\\ \n \\n # \\# $ \\$"}]
51405140
EOF
51415141
RUN
5142+
5143+
NAME=izx show strings with xrefs
5144+
FILE=bins/arm/elf/hello_world
5145+
CMDS=<<EOF
5146+
aaa
5147+
izx
5148+
EOF
5149+
EXPECT=<<EOF
5150+
paddr vaddr flag len size section type xref-from string
5151+
---------------------------------------------------------------------------------------------
5152+
0x00000574 0x00000574 str.Hello_world 12 13 .rodata ascii 0x00000512 Hello world!
5153+
0x00000494 0x00000494 sym.register_tm_clones 10 11 .text ascii 0x00000508 \bH\tKxD\tJ{D
5154+
EOF
5155+
RUN

0 commit comments

Comments
 (0)