diff --git a/libr/asm/parse.c b/libr/asm/parse.c index a0e9804cc031b..460dedaadb102 100644 --- a/libr/asm/parse.c +++ b/libr/asm/parse.c @@ -79,3 +79,142 @@ R_API char *r_asm_parse_patch(RAsm *a, RAnalOp *aop, const char *op) { } return NULL; } + +// TODO: R2_600 - finish reimplementing libr/core/disasm.c: ds_sub_jumps +R_API char *r_asm_parse_subjmp(RAsm *a, RAnalOp *aop, const char *op) { + R_RETURN_VAL_IF_FAIL (a, false); + const char* arch = R_UNWRAP3 (a, config, arch); + const bool x86 = arch && r_str_startswith (arch, "x86"); + const char *name = NULL; + const char *kw = ""; + ut64 addr = aop->jump; + int optype = aop->type & R_ANAL_OP_TYPE_MASK; + switch (optype) { + case R_ANAL_OP_TYPE_LEA: + if (x86) { + // let the pseudo plugin trim the '[]' + return NULL; + } + // for ARM adrp, section is better than adrp, segment + break; + case R_ANAL_OP_TYPE_JMP: + case R_ANAL_OP_TYPE_CJMP: + case R_ANAL_OP_TYPE_MOV: + case R_ANAL_OP_TYPE_MJMP: + break; + case R_ANAL_OP_TYPE_PUSH: + addr = aop->val; + if (addr < 10) { + // ignore push 0 + return NULL; + } + break; + case R_ANAL_OP_TYPE_CALL: + case R_ANAL_OP_TYPE_UJMP: + case R_ANAL_OP_TYPE_UCALL: + break; + default: + return NULL; + } +#if 0 + RFlag *f = ds->core->flags; + RAnal *anal = ds->core->anal; + RBinReloc *rel = NULL; + RBinObject *bo = r_bin_cur_object (ds->core->bin); + if (bo && !bo->is_reloc_patched) { + rel = r_core_getreloc (ds->core, ds->analop.addr, ds->analop.size); + } + if (!rel) { + rel = r_core_getreloc (ds->core, addr, ds->analop.size); + if (!rel) { + // some jmp 0 are actually relocs, so we can just ignore it + if (!addr || addr == UT64_MAX) { + rel = r_core_getreloc (ds->core, ds->analop.ptr, ds->analop.size); + if (rel) { + addr = ds->analop.ptr; + } + } + } + } + if (addr == UT64_MAX) { + if (rel) { + addr = 0; + } else { + addr = ds->analop.ptr; + } + } + RAnalFunction *fcn = r_anal_get_function_at (anal, addr); + if (fcn) { + name = fcn->name; + } else { + if (rel) { + if (rel && rel->import && rel->import->name) { + name = r_bin_name_tostring (rel->import->name); + } else if (rel && rel->symbol && rel->symbol->name) { + name = r_bin_name_tostring (rel->symbol->name); + } + if (addr) { // && *name == '.') { + RFlagItem *flag = r_core_flag_get_by_spaces (f, false, addr); + if (flag) { + if (!r_str_startswith (flag->name, "section")) { + name = flag->name; + if (f->realnames && flag->realname) { + name = flag->realname; + } + } + } + } + } else { + RFlagItem *flag = r_core_flag_get_by_spaces (f, false, addr); + if (flag) { + // R2R db/anal/jmptbl + // adrp x0, segment.DATA //instead-of// adrp x0, section.20.__DATA.__objc_const + if (!r_str_startswith (flag->name, "section")) { + name = flag->name; + if (f->realnames && flag->realname) { + name = flag->realname; + } + } + } + } + } + if (name) { + char *nptr; + ut64 numval; + char *hstr = strdup (str); + char *ptr = hstr; + const int bits = ds->core->rasm->config->bits; + const int seggrn = ds->core->rasm->config->seggrn; + while ((nptr = _find_next_number (ptr))) { + ptr = nptr; + char* colon = strchr (ptr, ':'); + if (x86 && bits == 16 && colon) { + *colon = '\0'; + ut64 seg = r_num_get (NULL, ptr); + ut64 off = r_num_get (NULL, colon + 1); + *colon = ':'; + numval = (seg << seggrn) + off; + } else { + numval = r_num_get (NULL, ptr); + } + if (numval == addr) { + while ((*nptr && !IS_SEPARATOR (*nptr) && *nptr != 0x1b) || (x86 && bits == 16 && colon && *nptr == ':')) { + nptr++; + } + char *kwname = r_str_newf ("%s%s", kw, name); + if (kwname) { + char* numstr = r_str_ndup (ptr, nptr - ptr); + if (numstr) { + hstr = r_str_replace (hstr, numstr, kwname, 0); + free (numstr); + } + free (kwname); + } + break; + } + } + return hstr; + } +#endif + return NULL; +} diff --git a/libr/core/disasm.c b/libr/core/disasm.c index 2bd2deb3e9e0b..97146e9cf450f 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -6250,42 +6250,6 @@ static char *_find_next_number(char *op) { return NULL; } -#if 0 -static bool set_jump_realname(RDisasmState *ds, ut64 addr, const char **kw, const char **name) { -return true; - RFlag *f = ds->core->flags; - if (!f) { - return false; - } - if (!ds->asm_demangle && !f->realnames) { - // nothing to do, neither demangled nor regular realnames should be shown - return false; - } - RFlagItem *flag_sym = r_flag_get_by_spaces (f, true, addr, R_FLAGS_FS_SYMBOLS, NULL); - if (!flag_sym || !flag_sym->realname) { - // nothing to replace - return false; - } - if (!flag_sym->demangled && !f->realnames) { - // realname is not demangled and we don't want to show non-demangled realnames - return false; - } - *name = flag_sym->realname; - RFlagItem *flag_mthd = r_flag_get_by_spaces (f, false, addr, R_FLAGS_FS_CLASSES, NULL); - if (!f->realnames) { -#if 1 - // for asm.flags.real, we don't want these prefixes - if (flag_mthd && flag_mthd->name && r_str_startswith (flag_mthd->name, "method.")) { - *kw = "method,"; - } else { - *kw = "sym,"; - } -#endif - } - return true; -} -#endif - // R2_600 - TODO: this should be moved into r_parse static char *ds_sub_jumps(RDisasmState *ds, const char *str) { RAnal *anal = ds->core->anal; @@ -6298,7 +6262,6 @@ static char *ds_sub_jumps(RDisasmState *ds, const char *str) { return NULL; } ut64 addr = ds->analop.jump; -#if 1 int optype = ds->analop.type & R_ANAL_OP_TYPE_MASK; switch (optype) { case R_ANAL_OP_TYPE_LEA: @@ -6324,11 +6287,9 @@ static char *ds_sub_jumps(RDisasmState *ds, const char *str) { case R_ANAL_OP_TYPE_UJMP: case R_ANAL_OP_TYPE_UCALL: break; - // return NULL; default: return NULL; } -#endif RBinReloc *rel = NULL; RBinObject *bo = r_bin_cur_object (ds->core->bin); if (bo && !bo->is_reloc_patched) { @@ -6355,9 +6316,7 @@ static char *ds_sub_jumps(RDisasmState *ds, const char *str) { } RAnalFunction *fcn = r_anal_get_function_at (anal, addr); if (fcn) { - // if (!set_jump_realname (ds, addr, &kw, &name)) { - name = fcn->name; - // } + name = fcn->name; } else { if (rel) { if (rel && rel->import && rel->import->name) { @@ -6377,20 +6336,17 @@ static char *ds_sub_jumps(RDisasmState *ds, const char *str) { } } } else { - - // if (!set_jump_realname (ds, addr, &kw, &name)) { - RFlagItem *flag = r_core_flag_get_by_spaces (f, false, addr); - if (flag) { - // R2R db/anal/jmptbl - // adrp x0, segment.DATA //instead-of// adrp x0, section.20.__DATA.__objc_const - if (!r_str_startswith (flag->name, "section")) { - name = flag->name; - if (f->realnames && flag->realname) { - name = flag->realname; - } + RFlagItem *flag = r_core_flag_get_by_spaces (f, false, addr); + if (flag) { + // R2R db/anal/jmptbl + // adrp x0, segment.DATA //instead-of// adrp x0, section.20.__DATA.__objc_const + if (!r_str_startswith (flag->name, "section")) { + name = flag->name; + if (f->realnames && flag->realname) { + name = flag->realname; } } - // } + } } } if (name) { diff --git a/libr/include/r_asm.h b/libr/include/r_asm.h index e2dc0851eab07..0e07c8d6626e8 100644 --- a/libr/include/r_asm.h +++ b/libr/include/r_asm.h @@ -114,7 +114,7 @@ R_API char *r_asm_parse_filter(RAsm *a, ut64 addr, RFlag *f, RAnalHint *hint, co R_API char *r_asm_parse_subvar(RAsm *a, RAnalFunction *f, ut64 addr, int oplen, const char *data); R_API char *r_asm_parse_immtrim(RAsm *a, const char *opstr); R_API char *r_asm_parse_patch(RAsm *a, RAnalOp *aop, const char *newop); - +R_API char *r_asm_parse_subjmp(RAsm *a, RAnalOp *aop, const char *op); /* asm.c */ R_API RAsm *r_asm_new(void);