Improve ARM/AArch64 DATA xrefs analysis (#6506)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
parent
323e707114
commit
f91ef729bf
4 changed files with 72 additions and 9 deletions
|
|
@ -4010,6 +4010,43 @@ static bool addr_in_exec_section(RzBinObject *bo, ut64 addr) {
|
|||
return sec && (sec->perm & RZ_PERM_X);
|
||||
}
|
||||
|
||||
static bool addr_in_exec_segment(RzBinObject *bo, ut64 addr) {
|
||||
RzBinSection *seg = rz_bin_get_segment_at(bo, addr, true);
|
||||
return seg && (seg->perm & RZ_PERM_X);
|
||||
}
|
||||
|
||||
/** \brief How a DATA xref's instruction relates to its target address. */
|
||||
typedef enum {
|
||||
XREF_REF_OTHER = 0, ///< address computation, control flow, etc. — handled as before
|
||||
XREF_REF_MEM_ACCESS, ///< load/store of the target: an unambiguous data access
|
||||
XREF_REF_COINCIDENTAL_IMM, ///< immediate equals the target with no data access (e.g. `sub sp, sp, 0x810`)
|
||||
} XrefRefKind;
|
||||
|
||||
/** \brief Classify how the instruction at \p from references \p target. */
|
||||
static XrefRefKind xref_ref_kind(RzCore *core, ut64 from, ut64 target) {
|
||||
RzAnalysisOp *op = rz_core_analysis_op(core, from, RZ_ANALYSIS_OP_MASK_VAL);
|
||||
if (!op) {
|
||||
return XREF_REF_OTHER;
|
||||
}
|
||||
XrefRefKind kind = XREF_REF_OTHER;
|
||||
switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
|
||||
case RZ_ANALYSIS_OP_TYPE_LOAD:
|
||||
case RZ_ANALYSIS_OP_TYPE_STORE:
|
||||
kind = XREF_REF_MEM_ACCESS;
|
||||
break;
|
||||
case RZ_ANALYSIS_OP_TYPE_MOV:
|
||||
case RZ_ANALYSIS_OP_TYPE_LEA:
|
||||
break; // address into a register: leave to the heuristic below
|
||||
default:
|
||||
if (op->val == target) {
|
||||
kind = XREF_REF_COINCIDENTAL_IMM;
|
||||
}
|
||||
break;
|
||||
}
|
||||
rz_analysis_op_free(op);
|
||||
return kind;
|
||||
}
|
||||
|
||||
static void analysis_mark_xrefs_as_data(RzCore *core) {
|
||||
int bits = rz_asm_get_bits(core->rasm);
|
||||
ut64 ptr_size = bits == 64 ? 8 : 4;
|
||||
|
|
@ -4075,6 +4112,14 @@ static void analysis_mark_xrefs_as_data(RzCore *core) {
|
|||
if (!bo) {
|
||||
continue;
|
||||
}
|
||||
// Only executable-region targets need classifying: reject constants that merely
|
||||
// equal a code address (e.g. `sub sp, sp, 0x810`), while skipping the decode for
|
||||
// the common data-section case.
|
||||
bool in_exec_segment = addr_in_exec_segment(bo, target);
|
||||
XrefRefKind ref_kind = in_exec_segment ? xref_ref_kind(core, xref->from, target) : XREF_REF_OTHER;
|
||||
if (ref_kind == XREF_REF_COINCIDENTAL_IMM) {
|
||||
continue;
|
||||
}
|
||||
bool target_in_exec = addr_in_exec_section(bo, target);
|
||||
if (target_in_exec) {
|
||||
ut8 buf[8] = { 0 };
|
||||
|
|
@ -4093,14 +4138,13 @@ static void analysis_mark_xrefs_as_data(RzCore *core) {
|
|||
// stored value is a code pointer — skip
|
||||
continue;
|
||||
}
|
||||
if (!val_sec) {
|
||||
// address do not refer to a section in ELF
|
||||
// A load/store marks the target directly, covering whole literal pools
|
||||
// regardless of distance (e.g. K64F sym.poweroff entries at 0x11d4/0x11d8).
|
||||
// Other refs keep the conservative heuristic: accept only padding right
|
||||
// after the referencing function.
|
||||
if (ref_kind != XREF_REF_MEM_ACCESS && !val_sec) {
|
||||
ut64 fcn_end = fcn_from->addr + rz_analysis_function_linear_size(fcn_from);
|
||||
if (target < fcn_end) {
|
||||
continue;
|
||||
}
|
||||
// not padding
|
||||
if (target - fcn_end >= ptr_size) {
|
||||
if (target < fcn_end || target - fcn_end >= ptr_size) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2305,6 +2305,8 @@ s 0x4e0
|
|||
pd 1
|
||||
s 0xd50
|
||||
pd 1
|
||||
s 0x11d0
|
||||
pd 3
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
; DATA XREF from dbg.sched_run @ 0x490
|
||||
|
|
@ -2313,5 +2315,14 @@ EXPECT=<<EOF
|
|||
; DATA XREF from dbg.bit_clear8 @ 0xd34
|
||||
;-- data.00000d50:
|
||||
0x00000d50 .dword 0x01ffffe0
|
||||
; DATA XREF from sym.poweroff @ 0x1192
|
||||
;-- data.000011d0:
|
||||
0x000011d0 .dword 0x00002744 ; spi_config ; obj.spi_config
|
||||
; DATA XREF from sym.poweroff @ 0x11a0
|
||||
;-- data.000011d4:
|
||||
0x000011d4 .dword 0x4002d000
|
||||
; DATA XREFS from sym.poweroff @ 0x11b6, 0x11c6
|
||||
;-- data.000011d8:
|
||||
0x000011d8 .dword 0x40047000
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -363,6 +363,9 @@ s 0xe080
|
|||
pd 1
|
||||
s 0xe09c
|
||||
pd 1
|
||||
e asm.xrefs=false
|
||||
e asm.comments=false
|
||||
pd 3 @ 0x810
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
; DATA XREFS from fcn.00005b80 @ 0x5bb0, 0x5bec
|
||||
|
|
@ -375,5 +378,8 @@ EXPECT=<<EOF
|
|||
0x0000e0ac 64ca ffff 28ca ffff c8ca ffff 0000 0000 d...(...........
|
||||
0x0000e0bc 0000 0000 ....
|
||||
|
||||
0x00000810 ret
|
||||
0x00000814 ldr x8, [x0]
|
||||
0x00000818 add x9, x8, 1
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -11,13 +11,15 @@ EXPECT=<<EOF
|
|||
0x0000043a 0000 (null)
|
||||
; STRING XREFS from entry0 @ 0x40c, 0x410
|
||||
;-- data.00000434:
|
||||
0x00000434 lsrs r4, r1, 0xf
|
||||
0x00000436 movs r1, r0
|
||||
0x00000434 .dword 0x00010bcc
|
||||
; DATA XREF from entry0 @ 0x414
|
||||
;-- data.00000438:
|
||||
0x00000438 .dword 0x00000020
|
||||
; DATA XREF from entry0 @ 0x420
|
||||
;-- data.0000043c:
|
||||
0x0000043c .dword 0x00000030
|
||||
; DATA XREF from entry0 @ 0x426
|
||||
;-- data.00000440:
|
||||
0x00000440 .dword 0x00000034
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue