Mark bytes as data and show as such in disassembly if referenced as DATA (#6307)

This commit is contained in:
bubblepipe 2026-05-09 22:29:10 +07:00 committed by GitHub
parent a8429853d0
commit 48d9f725fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 216 additions and 0 deletions

View file

@ -3989,6 +3989,131 @@ static void analysis_global_vars_from_symbols(RzCore *core) {
}
}
static int cmp_ut64s(const void *a, const void *b, RZ_UNUSED void *user) {
ut64 va = *(const ut64 *)a;
ut64 vb = *(const ut64 *)b;
return (va > vb) - (va < vb);
}
// rz_vector_upper_bound comparator: x is a raw ut64 key, y is a pointer to a ut64 element
#define CMP_UT64_VAL(x, y) ((int)((x) > *(const ut64 *)(y)) - (int)((x) < *(const ut64 *)(y)))
static bool collect_ht_keys_cb(void *user, const ut64 k, const void *v) {
RzVector *vec = user;
ut64 key = k;
rz_vector_push(vec, &key);
return true;
}
static void analysis_mark_xrefs_as_data(RzCore *core) {
int bits = rz_asm_get_bits(core->rasm);
ut64 ptr_size = bits == 64 ? 8 : 4;
RzList *all_xrefs = rz_analysis_xrefs_list(core->analysis);
if (!all_xrefs) {
return;
}
// collect every target address that has at least one CODE/CALL xref
RzSetU *code_call_targets = rz_set_u_new();
if (!code_call_targets) {
rz_list_free(all_xrefs);
return;
}
RzListIter *iter;
RzAnalysisXRef *xref;
rz_list_foreach (all_xrefs, iter, xref) {
if (xref->type == RZ_ANALYSIS_XREF_TYPE_CODE ||
xref->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
rz_set_u_add(code_call_targets, xref->to);
}
}
// collect unique DATA/STRING targets outside functions
RzSetU *data_targets = rz_set_u_new();
if (!data_targets) {
rz_set_u_free(code_call_targets);
rz_list_free(all_xrefs);
return;
}
rz_list_foreach (all_xrefs, iter, xref) {
if (xref->type != RZ_ANALYSIS_XREF_TYPE_DATA &&
xref->type != RZ_ANALYSIS_XREF_TYPE_STRING) {
continue;
}
ut64 target = xref->to;
if (rz_set_u_contains(code_call_targets, target)) {
continue;
}
// only consider xrefs that originate from inside an analyzed function
if (!rz_analysis_get_fcn_in(core->analysis, xref->from, 0)) {
continue;
}
RzBinObject *bo = rz_bin_cur_object(core->bin);
RzBinSection *sec = bo ? rz_bin_get_section_at(bo, target, true) : NULL;
if (sec && (sec->perm & RZ_PERM_X)) {
continue;
}
// skip if already annotated by any other analysis
if (rz_meta_get_at(core->analysis, target, RZ_META_TYPE_ANY, NULL)) {
continue;
}
if (rz_analysis_get_fcn_in(core->analysis, target, -1)) {
continue;
}
rz_set_u_add(data_targets, target);
}
rz_list_free(all_xrefs);
rz_set_u_free(code_call_targets);
if (!rz_set_u_size(data_targets)) {
rz_set_u_free(data_targets);
return;
}
// convert set to sorted vector
RzVector *data_addrs = rz_vector_new(sizeof(ut64), NULL, NULL);
if (!data_addrs) {
rz_set_u_free(data_targets);
return;
}
ht_up_foreach(data_targets, collect_ht_keys_cb, data_addrs);
rz_set_u_free(data_targets);
rz_vector_sort(data_addrs, cmp_ut64s, false, NULL);
// sorted vector of function start addresses
RzVector *fcn_starts = rz_vector_new(sizeof(ut64), NULL, NULL);
if (fcn_starts) {
RzList *fcns = rz_analysis_function_list(core->analysis);
RzAnalysisFunction *fcn;
rz_list_foreach (fcns, iter, fcn) {
rz_vector_push(fcn_starts, &fcn->addr);
}
rz_vector_sort(fcn_starts, cmp_ut64s, false, NULL);
}
// mark each target up to the nearest of: next data target, next function, or ptr_size
size_t n = rz_vector_len(data_addrs);
for (size_t i = 0; i < n; i++) {
ut64 target = *(ut64 *)rz_vector_index_ptr(data_addrs, i);
ut64 next_data = (i + 1 < n) ? *(ut64 *)rz_vector_index_ptr(data_addrs, i + 1) : UT64_MAX;
ut64 next_fcn = UT64_MAX;
if (fcn_starts) {
size_t fi;
rz_vector_upper_bound(fcn_starts, target, fi, CMP_UT64_VAL);
if (fi < rz_vector_len(fcn_starts)) {
next_fcn = *(ut64 *)rz_vector_index_ptr(fcn_starts, fi);
}
}
ut64 upper = RZ_MIN(next_data, next_fcn);
ut64 size = (upper != UT64_MAX) ? upper - target : ptr_size;
rz_meta_set(core->analysis, RZ_META_TYPE_DATA, target, size, NULL);
}
rz_vector_free(data_addrs);
rz_vector_free(fcn_starts);
}
/**
* Runs all the steps of the deep analysis.
*
@ -4178,6 +4303,15 @@ RZ_API bool rz_core_analysis_everything(RzCore *core, bool experimental, char *d
rz_core_task_yield(&core->tasks);
}
notify = "Mark data-referenced bytes outside functions";
rz_core_notify_begin(core, "%s", notify);
analysis_mark_xrefs_as_data(core);
rz_core_notify_done(core, "%s", notify);
rz_core_task_yield(&core->tasks);
if (rz_cons_is_breaked()) {
return false;
}
if (experimental) {
if (!didAap) {
notify = "Finding function preludes";

View file

@ -354,3 +354,26 @@ EXPECT=<<EOF
0x00000008 tst x1, 0x3f ; '?'
EOF
RUN
NAME=data xrefs outside functions marked as data
FILE=bins/elf/libarm64.so
CMDS=<<EOF
aaa
s 0xe080
pd 1
s 0xe09c
pd 1
EOF
EXPECT=<<EOF
; DATA XREFS from fcn.00005b80 @ 0x5bb0, 0x5bec
0x0000e080 hex length=15 delta=0
0x0000e080 787b ffff 587b ffff 887b ffff 4c7b ff x{..X{...{..L{.
; DATA XREFS from sym.Java_o__003dc_e @ 0xaa64, 0xaaa8
0x0000e09c hex length=36 delta=0
0x0000e09c 18ca ffff f8c9 ffff 48ca ffff ecc9 ffff ........H.......
0x0000e0ac 64ca ffff 28ca ffff c8ca ffff 0000 0000 d...(...........
0x0000e0bc 0000 0000 ....
EOF
RUN

View file

@ -1700,4 +1700,33 @@ type: and
- type: "reg"
esil: at,sp,&=
EOF
RUN
NAME=data xrefs outside functions marked as data
FILE=bins/elf/analysis/mipsbe-ip
CMDS=<<EOF
aaa
s 0x4350f8 # this address is found in `pdf @ sym.rtnl_rttable_n2a`
pd 1
EOF
EXPECT=<<EOF
; XREFS(69)
;-- data.004350f8:
0x004350f8 hex length=256 delta=40
0x004350f8 0043 0000 0043 5420 0043 396c 0042 0000 .C...CT .C9l.B..
0x00435108 0040 0000 0000 0000 0000 0000 0000 0000 .@..............
0x00435118 0000 0000 0041 ec80 0041 ec70 0041 1608 .....A...A.p.A..
0x00435128 0040 da54 0041 88d4 0041 ec60 0043 5430 .@.T.A...A.`.CT0
0x00435138 0041 c174 0041 d118 0041 ec50 0000 0000 .A.t.A...A.P....
0x00435148 0000 0000 0000 0000 0041 ec40 0041 9908 .........A.@.A..
0x00435158 0041 ec30 0041 b97c 0041 12c4 0041 b1e0 .A.0.A.|.A...A..
0x00435168 0040 d844 0041 ec20 0041 ab98 0041 ec10 .@.D.A. .A...A..
0x00435178 0041 bec4 0041 d4e4 0041 a588 0041 ec00 .A...A...A...A..
0x00435188 0041 9c50 0041 ebf0 0041 ab50 0041 ebe0 .A.P.A...A.P.A..
0x00435198 0041 ebd0 0043 5464 0041 ebc0 0041 ebb0 .A...CTd.A...A..
0x004351a8 0041 8830 0041 b2b4 0041 eba0 0041 a5a8 .A.0.A...A...A..
0x004351b8 0041 b054 0041 eb90 0041 b760 0041 dc20 .A.T.A...A.`.A.
0x004351c8 0041 eb80 0041 de40 .A...A.@
.dword 0x00430000
EOF
RUN

View file

@ -4971,3 +4971,33 @@ Gadget size: 4
EOF
RUN
NAME=data xrefs outside functions marked as data
FILE=bins/elf/analysis/guess-number-riscv64
CMDS=<<EOF
aaa
s 0x22000
pd 1
EOF
EXPECT=<<EOF
; XREFS(112)
0x00022000 hex length=256 delta=0
0x00022000 24ae 0100 24ae 0100 b8a6 0100 0000 0000 $...$...........
0x00022010 2020 2020 2020 2020 2020 2020 2020 2020
0x00022020 3030 3030 3030 3030 3030 3030 3030 3030 0000000000000000
0x00022030 fcc9 0100 7ccb 0100 7ccb 0100 10ca 0100 ....|...|.......
0x00022040 7ccb 0100 7ccb 0100 7ccb 0100 7ccb 0100 |...|...|...|...
0x00022050 7ccb 0100 7ccb 0100 9cc5 0100 50c8 0100 |...|.......P...
0x00022060 7ccb 0100 b4c5 0100 38cb 0100 7ccb 0100 |.......8...|...
0x00022070 60c8 0100 6cc8 0100 6cc8 0100 6cc8 0100 `...l...l...l...
0x00022080 6cc8 0100 6cc8 0100 6cc8 0100 6cc8 0100 l...l...l...l...
0x00022090 6cc8 0100 6cc8 0100 7ccb 0100 7ccb 0100 l...l...|...|...
0x000220a0 7ccb 0100 7ccb 0100 7ccb 0100 7ccb 0100 |...|...|...|...
0x000220b0 7ccb 0100 7ccb 0100 7ccb 0100 7ccb 0100 |...|...|...|...
0x000220c0 98c8 0100 7ccb 0100 7ccb 0100 7ccb 0100 ....|...|...|...
0x000220d0 7ccb 0100 7ccb 0100 7ccb 0100 7ccb 0100 |...|...|...|...
0x000220e0 7ccb 0100 7ccb 0100 7ccb 0100 fcc8 0100 |...|...|.......
0x000220f0 7ccb 0100 7ccb 0100 7ccb 0100 7ccb 0100 |...|...|...|...
EOF
RUN