From 5870b5df8509f3047b53bb034a3c87783fc69d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 15 Dec 2019 20:24:03 +0100 Subject: [PATCH] Fix Alignment Check in aae on bit change --- libr/core/canal.c | 7 +++++-- libr/core/cio.c | 44 ++++++++++++++++++++++++++++++------------- libr/core/core.c | 2 +- libr/core/disasm.c | 4 ++-- libr/include/r_core.h | 3 ++- test/new/db/anal/arm | 22 ++++++++++++++++++++++ 6 files changed, 63 insertions(+), 19 deletions(-) diff --git a/libr/core/canal.c b/libr/core/canal.c index b16d640e3d..facacb1d3f 100644 --- a/libr/core/canal.c +++ b/libr/core/canal.c @@ -1845,7 +1845,7 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept //update bits based on the core->offset otherwise we could have the //last value set and blow everything up - r_core_seek_archbits (core, at); + r_core_seek_arch_bits (core, at); if (core->io->va) { if (!r_io_is_valid_offset (core->io, at, !core->anal->opt.noncode)) { @@ -4870,7 +4870,6 @@ R_API void r_core_anal_esil(RCore *core, const char *str, const char *target) { arch = R2_ARCH_MIPS; } - int opalign = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_ALIGN); const char *sn = r_reg_get_name (core->anal->reg, R_REG_NAME_SN); if (!sn) { eprintf ("Warning: No SN reg alias for current architecture.\n"); @@ -4905,10 +4904,14 @@ repeat: r_list_free (list); } } + /* realign address if needed */ + r_core_seek_arch_bits (core, cur); + int opalign = core->anal->pcalign; if (opalign > 0) { cur -= (cur % opalign); } + r_anal_op_fini (&op); r_asm_set_pc (core->assembler, cur); if (!r_anal_op (core->anal, &op, cur, buf + i, iend - i, R_ANAL_OP_MASK_ESIL | R_ANAL_OP_MASK_VAL | R_ANAL_OP_MASK_HINT)) { diff --git a/libr/core/cio.c b/libr/core/cio.c index e68be9cf11..05601b68c5 100644 --- a/libr/core/cio.c +++ b/libr/core/cio.c @@ -333,23 +333,41 @@ static void __choose_bits_anal_hints(RCore *core, ut64 addr, int *bits) { } } -R_API void r_core_seek_archbits(RCore *core, ut64 addr) { +// Get address-specific bits and arch at a certain address. +// If there are no specific infos (i.e. asm.bits and asm.arch should apply), the bits and arch will be 0 or NULL respectively! +R_API void r_core_arch_bits_at(RCore *core, ut64 addr, R_OUT R_NULLABLE int *bits, R_OUT R_BORROW R_NULLABLE const char **arch) { + int bitsval = 0; + const char *archval = NULL; + RBinObject *o = r_bin_cur_object (core->bin); + RBinSection *s = o ? r_bin_get_section_at (o, addr, core->io->va) : NULL; + if (s) { + if (!core->fixedarch) { + archval = s->arch; + } + if (!core->fixedbits) { + bitsval = s->bits; + } + } + if (bits && !bitsval && !core->fixedbits) { + //if we found bits related with anal hints pick it up + __choose_bits_anal_hints (core, addr, &bitsval); + } + if (bits) { + *bits = bitsval; + } + if (arch) { + *arch = archval; + } +} + +R_API void r_core_seek_arch_bits(RCore *core, ut64 addr) { int bits = 0; const char *arch = NULL; - RBinObject *o = r_bin_cur_object (core->bin); - RBinSection *s = o? r_bin_get_section_at (o, addr, core->io->va): NULL; - if (s) { - arch = s->arch; - bits = s->bits; - } - if (!bits && !core->fixedbits) { - //if we found bits related with anal hints pick it up - __choose_bits_anal_hints (core, addr, &bits); - } - if (bits && !core->fixedbits) { + r_core_arch_bits_at (core, addr, &bits, &arch); + if (bits) { r_config_set_i (core->config, "asm.bits", bits); } - if (arch && !core->fixedarch) { + if (arch) { r_config_set (core->config, "asm.arch", arch); } } diff --git a/libr/core/core.c b/libr/core/core.c index f9492cfbcf..351b85e7bc 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -259,7 +259,7 @@ static char *getNameDelta(RCore *core, ut64 addr) { } static void archbits(RCore *core, ut64 addr) { - r_core_seek_archbits (core, addr); + r_core_seek_arch_bits (core, addr); } static int cfggeti(RCore *core, const char *k) { diff --git a/libr/core/disasm.c b/libr/core/disasm.c index aaf3a033cd..951f774651 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -5225,7 +5225,7 @@ toro: } } } - r_core_seek_archbits (core, ds->at); // slow but safe + r_core_seek_arch_bits (core, ds->at); // slow but safe ds->has_description = false; ds->hint = r_core_hint_begin (core, ds->hint, ds->at); ds->printed_str_addr = UT64_MAX; @@ -5710,7 +5710,7 @@ R_API int r_core_print_disasm_instructions(RCore *core, int nb_bytes, int nb_opc ds->at = core->offset + i; ds->vat = r_core_pava (core, ds->at); hasanal = false; - r_core_seek_archbits (core, ds->at); + r_core_seek_arch_bits (core, ds->at); if (r_cons_is_breaked ()) { break; } diff --git a/libr/include/r_core.h b/libr/include/r_core.h index 279892b93b..8654e30ec0 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -422,7 +422,8 @@ R_API int r_core_seek_base (RCore *core, const char *hex); R_API void r_core_seek_previous (RCore *core, const char *type); R_API void r_core_seek_next (RCore *core, const char *type); R_API int r_core_seek_align(RCore *core, ut64 align, int count); -R_API void r_core_seek_archbits (RCore *core, ut64 addr); +R_API void r_core_arch_bits_at(RCore *core, ut64 addr, R_OUT R_NULLABLE int *bits, R_OUT R_BORROW R_NULLABLE const char **arch); +R_API void r_core_seek_arch_bits(RCore *core, ut64 addr); R_API int r_core_block_read(RCore *core); R_API int r_core_block_size(RCore *core, int bsize); R_API int r_core_seek_size(RCore *core, ut64 addr, int bsize); diff --git a/test/new/db/anal/arm b/test/new/db/anal/arm index 93fe5a67f5..4d28d23022 100644 --- a/test/new/db/anal/arm +++ b/test/new/db/anal/arm @@ -925,3 +925,25 @@ cycles: 1 esil: 0,sp,+,0xffffffff,&,r7,= family: cpu RUN + +NAME=arm aae with bit switch +FILE=../bins/arm/elf/hello_world +EXPECT=<