@@ -2686,7 +2686,7 @@ RZ_API bool rz_core_bin_segments_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBin
2686
2686
return true;
2687
2687
}
2688
2688
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 ) {
2690
2690
bool b64str = rz_config_get_i (core -> config , "bin.b64str" );
2691
2691
int va = (core -> io -> va || core -> bin -> is_debugger ) ? VA_TRUE : VA_FALSE ;
2692
2692
RzBinObject * obj = rz_bin_cur_object (core -> bin );
@@ -2696,7 +2696,11 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
2696
2696
RzBinSection * section ;
2697
2697
2698
2698
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
+ }
2700
2704
2701
2705
RzBinString b64 = { 0 };
2702
2706
rz_pvector_foreach (vec , iter ) {
@@ -2705,6 +2709,40 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
2705
2709
char quiet_val [20 ];
2706
2710
ut64 paddr , vaddr ;
2707
2711
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
+
2708
2746
vaddr = obj ? rva (obj , paddr , string -> vaddr , va ) : paddr ;
2709
2747
if (!rz_bin_string_filter (core -> bin , string -> string , vaddr )) {
2710
2748
continue ;
@@ -2742,12 +2780,18 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
2742
2780
pj_o (state -> d .pj );
2743
2781
pj_kn (state -> d .pj , "vaddr" , vaddr );
2744
2782
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
+ }
2746
2786
pj_kn (state -> d .pj , "size" , string -> size );
2747
2787
pj_kn (state -> d .pj , "length" , string -> length );
2748
2788
pj_ks (state -> d .pj , "section" , section_name );
2749
2789
pj_ks (state -> d .pj , "type" , type_string );
2750
2790
// 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
+ }
2751
2795
pj_ks (state -> d .pj , "string" , string -> string );
2752
2796
2753
2797
switch (string -> type ) {
@@ -2836,9 +2880,15 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
2836
2880
break ;
2837
2881
}
2838
2882
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
+ }
2842
2892
free (bufstr );
2843
2893
free (no_dbl_bslash_str );
2844
2894
break ;
@@ -2860,6 +2910,8 @@ static bool strings_print(RzCore *core, RzCmdStateOutput *state, const RzPVector
2860
2910
break ;
2861
2911
}
2862
2912
free (escaped_string );
2913
+ free (flag_name_str );
2914
+ free (xref_address_str );
2863
2915
}
2864
2916
RZ_FREE (b64 .string );
2865
2917
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
2870
2922
rz_return_val_if_fail (core && bf && state , false);
2871
2923
2872
2924
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 );
2874
2926
}
2875
2927
2876
2928
/***
@@ -2941,7 +2993,7 @@ RZ_API bool rz_core_bin_whole_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL
2941
2993
if (!l ) {
2942
2994
return false;
2943
2995
}
2944
- bool res = strings_print (core , state , l );
2996
+ bool res = strings_print (core , state , l , false );
2945
2997
rz_pvector_free (l );
2946
2998
return res ;
2947
2999
}
@@ -2965,7 +3017,7 @@ RZ_API bool rz_core_bin_xrefs_strings_print(RZ_NONNULL RzCore *core, RZ_NONNULL
2965
3017
void * * iter ;
2966
3018
rz_pvector_foreach (whole_strings , iter ) {
2967
3019
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 );
2969
3021
const RzAnalysisXRef * xref ;
2970
3022
const RzListIter * iterator ;
2971
3023
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
2980
3032
break ;
2981
3033
}
2982
3034
}
3035
+ rz_list_free (list );
2983
3036
}
2984
- bool res = strings_print (core , state , xrefs_strings );
3037
+ bool res = strings_print (core , state , xrefs_strings , true );
2985
3038
rz_pvector_free (whole_strings );
2986
3039
rz_pvector_free (xrefs_strings );
2987
3040
return res ;
0 commit comments