mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-01 17:40:34 +00:00
fix disassembling 'backwards'
(e.g. pd -5) producing wrong output fixes #5105
This commit is contained in:
parent
20bd6003ae
commit
7c3fb53a5e
@ -1017,11 +1017,19 @@ static int pdi(RCore *core, int nb_opcodes, int nb_bytes, int fmt) {
|
||||
}
|
||||
} else if (!nb_bytes) {
|
||||
if (nb_opcodes < 0) {
|
||||
ut64 start;
|
||||
/* Backward disassembly of `ilen` opcodes
|
||||
* - We compute the new starting offset
|
||||
* - Read at the new offset */
|
||||
nb_opcodes = -nb_opcodes;
|
||||
r_core_asm_bwdis_len (core, &nb_bytes, &core->offset, nb_opcodes);
|
||||
if (r_core_prevop_addr (core, core->offset, nb_opcodes, &start)) {
|
||||
// We have some anal_info.
|
||||
nb_bytes = core->offset - start;
|
||||
} else {
|
||||
// anal ignorance.
|
||||
r_core_asm_bwdis_len (core, &nb_bytes, &core->offset,
|
||||
nb_opcodes);
|
||||
}
|
||||
r_core_read_at (core, core->offset, core->block, nb_bytes);
|
||||
} else {
|
||||
// workaround for the `for` loop below
|
||||
@ -2755,6 +2763,7 @@ static int cmd_print(void *data, const char *input) {
|
||||
if (!processed_cmd) {
|
||||
ut64 addr = core->offset;
|
||||
ut8 *block = NULL;
|
||||
ut64 start;
|
||||
|
||||
if (bw_disassemble) {
|
||||
block = malloc (core->blocksize);
|
||||
@ -2769,7 +2778,13 @@ static int cmd_print(void *data, const char *input) {
|
||||
} else { //pd
|
||||
const int bs = core->blocksize;
|
||||
int instr_len;
|
||||
r_core_asm_bwdis_len (core, &instr_len, &addr, l);
|
||||
if (r_core_prevop_addr (core, core->offset, l, &start)) {
|
||||
// We have some anal_info.
|
||||
instr_len = core->offset - start;
|
||||
} else {
|
||||
// anal ignorance.
|
||||
r_core_asm_bwdis_len (core, &instr_len, &addr, l);
|
||||
}
|
||||
ut64 prevaddr = core->offset;
|
||||
r_core_seek(core, prevaddr - instr_len, true);
|
||||
block = realloc (block, R_MAX(instr_len, bs));
|
||||
|
@ -631,6 +631,30 @@ static ut64 prevop_addr (RCore *core, ut64 addr) {
|
||||
return target - 4;
|
||||
}
|
||||
|
||||
// Returns true if we can use analysis to find the previous operation address,
|
||||
// sets prev_addr to the value of the instruction numinstrs back.
|
||||
// If we can't use the anal, then set prev_addr to UT64_MAX and return false;
|
||||
R_API bool r_core_prevop_addr (RCore* core, ut64 start_addr, int numinstrs,
|
||||
ut64* prev_addr) {
|
||||
RAnalBlock* bb;
|
||||
int i;
|
||||
// Check that we're in a bb, otherwise this prevop stuff won't work.
|
||||
bb = r_anal_bb_from_offset (core->anal, start_addr);
|
||||
if (bb) {
|
||||
if (r_anal_bb_opaddr_at (bb, start_addr) != UT64_MAX) {
|
||||
// Do some anal looping.
|
||||
for (i = 0; i < numinstrs; ++i) {
|
||||
*prev_addr = prevop_addr (core, start_addr);
|
||||
start_addr = *prev_addr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Dang! not in a bb, return false and fallback to other methods.
|
||||
*prev_addr = UT64_MAX;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void reset_print_cur(RPrint *p) {
|
||||
p->cur = 0;
|
||||
p->ocur = -1;
|
||||
|
@ -227,6 +227,7 @@ R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size);
|
||||
R_API int r_core_is_valid_offset (RCore *core, ut64 offset);
|
||||
R_API int r_core_shift_block(RCore *core, ut64 addr, ut64 b_size, st64 dist);
|
||||
R_API void r_core_visual_prompt_input (RCore *core);
|
||||
R_API bool r_core_prevop_addr (RCore* core, ut64 start_addr, int numinstrs, ut64* prev_addr);
|
||||
R_API bool r_core_visual_hudstuff(RCore *core);
|
||||
R_API int r_core_visual_classes(RCore *core);
|
||||
R_API int r_core_visual_types(RCore *core);
|
||||
|
Loading…
Reference in New Issue
Block a user