mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-26 09:06:02 +00:00
Initial implementatil of asm.tailsub (#11696)
This commit is contained in:
parent
883abe417f
commit
47297f6d0a
@ -346,6 +346,13 @@ static int cb_asmvarsubmin(void *user, void *data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_asmtailsub(void *user, void *data) {
|
||||
RCore *core = (RCore *) user;
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
core->parser->tailsub = node->i_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_scrlast(void *user, void *data) {
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
r_cons_singleton ()->context->lastEnabled = node->i_value;
|
||||
@ -2486,6 +2493,7 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETPREF ("asm.lines.wide", "false", "Put a space between lines");
|
||||
SETICB ("asm.lines.width", 7, &cb_asmlineswidth, "Number of columns for program flow arrows");
|
||||
SETICB ("asm.var.submin", 0x100, &cb_asmvarsubmin, "Minimum value to substitute in instructions (asm.var.sub)");
|
||||
SETCB ("asm.tailsub", "false", &cb_asmtailsub, "Replace addresses with prefix .. syntax");
|
||||
SETPREF ("asm.middle", "false", "Allow disassembling jumps in the middle of an instruction");
|
||||
SETPREF ("asm.noisy", "true", "Show comments considered noisy but possibly useful");
|
||||
SETPREF ("asm.offset", "true", "Show offsets at disassembly");
|
||||
|
@ -1442,9 +1442,11 @@ static void core_anal_bytes(RCore *core, const ut8 *buf, int len, int nops, int
|
||||
}
|
||||
// 0x33->sym.xx
|
||||
char *p = strdup (strsub);
|
||||
r_parse_filter (core->parser, core->flags, p,
|
||||
strsub, sizeof (strsub), be);
|
||||
free (p);
|
||||
if (p) {
|
||||
r_parse_filter (core->parser, addr, core->flags, p,
|
||||
strsub, sizeof (strsub), be);
|
||||
free (p);
|
||||
}
|
||||
r_cons_printf ("\"disasm\":\"%s\",", strsub);
|
||||
}
|
||||
r_cons_printf ("\"mnemonic\":\"%s\",", mnem);
|
||||
@ -5541,7 +5543,7 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
|
||||
r_parse_varsub (core->parser, fcn, ref->addr, asmop.size,
|
||||
str, str, sizeof (str));
|
||||
}
|
||||
r_parse_filter (core->parser, core->flags,
|
||||
r_parse_filter (core->parser, ref->addr, core->flags,
|
||||
r_asm_op_get_asm (&asmop), str, sizeof (str), core->print->big_endian);
|
||||
r_cons_printf ("{\"from\":%" PFMT64u ",\"type\":\"%s\",\"opcode\":\"%s\"",
|
||||
ref->addr, r_anal_xrefs_type_tostring (ref->type), str);
|
||||
@ -5608,7 +5610,7 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
|
||||
r_parse_varsub (core->parser, fcn, ref->addr, asmop.size,
|
||||
ba, ba, sizeof (asmop.buf_asm));
|
||||
}
|
||||
r_parse_filter (core->parser, core->flags,
|
||||
r_parse_filter (core->parser, ref->addr, core->flags,
|
||||
ba, str, sizeof (str), core->print->big_endian);
|
||||
r_asm_op_set_asm (&asmop, ba);
|
||||
free (ba);
|
||||
@ -5687,8 +5689,7 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
|
||||
r_io_read_at (core->io, ref->at, buf, 12);
|
||||
r_asm_set_pc (core->assembler, ref->at);
|
||||
r_asm_disassemble (core->assembler, &asmop, buf, 12);
|
||||
r_parse_filter (core->parser, core->flags,
|
||||
r_asm_op_get_asm (&asmop),
|
||||
r_parse_filter (core->parser, ref->at, core->flags, r_asm_op_get_asm (&asmop),
|
||||
str, sizeof (str), core->print->big_endian);
|
||||
if (has_color) {
|
||||
buf_asm = r_print_colorize_opcode (core->print, str,
|
||||
|
@ -1824,7 +1824,7 @@ static void do_ref_search(RCore *core, ut64 addr,ut64 from, ut64 to, struct sear
|
||||
r_asm_set_pc (core->assembler, ref->addr);
|
||||
r_asm_disassemble (core->assembler, &asmop, buf, size);
|
||||
fcn = r_anal_get_fcn_in (core->anal, ref->addr, 0);
|
||||
r_parse_filter (core->parser, core->flags, r_strbuf_get (&asmop.buf_asm),
|
||||
r_parse_filter (core->parser, ref->addr, core->flags, r_strbuf_get (&asmop.buf_asm),
|
||||
str, sizeof (str), core->print->big_endian);
|
||||
comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ref->addr);
|
||||
char *buf_fcn = comment
|
||||
@ -2090,7 +2090,7 @@ static void do_asm_search(RCore *core, struct search_parameters *param, const ch
|
||||
char tmp[128] = {
|
||||
0
|
||||
};
|
||||
r_parse_filter (core->parser, core->flags, hit->code, tmp, sizeof (tmp),
|
||||
r_parse_filter (core->parser, hit->addr, core->flags, hit->code, tmp, sizeof (tmp),
|
||||
core->print->big_endian);
|
||||
r_cons_printf ("0x%08"PFMT64x " # %i: %s\n",
|
||||
hit->addr, hit->len, tmp);
|
||||
@ -2102,7 +2102,9 @@ static void do_asm_search(RCore *core, struct search_parameters *param, const ch
|
||||
}
|
||||
if (searchflags) {
|
||||
const char *flagname = sdb_fmt ("%s%d_%d", searchprefix, kwidx, count);
|
||||
r_flag_set (core->flags, flagname, hit->addr, hit->len);
|
||||
if (flagname) {
|
||||
r_flag_set (core->flags, flagname, hit->addr, hit->len);
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -980,7 +980,7 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) {
|
||||
core->parser->relsub_addr = (int)killme;
|
||||
}
|
||||
}
|
||||
r_parse_filter (core->parser, core->flags, asm_str,
|
||||
r_parse_filter (core->parser, ds->vat, core->flags, asm_str,
|
||||
ds->str, sizeof (ds->str), core->print->big_endian);
|
||||
core->parser->flagspace = ofs;
|
||||
free (ds->opstr);
|
||||
@ -5161,7 +5161,7 @@ R_API int r_core_print_disasm_instructions(RCore *core, int nb_bytes, int nb_opc
|
||||
}
|
||||
core->parser->hint = ds->hint;
|
||||
ds->hint = NULL;
|
||||
r_parse_filter (core->parser, core->flags, r_asm_op_get_asm (&ds->asmop),
|
||||
r_parse_filter (core->parser, ds->vat, core->flags, r_asm_op_get_asm (&ds->asmop),
|
||||
ds->str, sizeof (ds->str), core->print->big_endian);
|
||||
ds->opstr = strdup (ds->str);
|
||||
asm_str = colorize_asm_string (core, ds, true);
|
||||
@ -5364,7 +5364,7 @@ R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int nb_byte
|
||||
core->parser->relsub_addr = killme;
|
||||
}
|
||||
}
|
||||
r_parse_filter (core->parser, core->flags, r_asm_op_get_asm (&asmop), str,
|
||||
r_parse_filter (core->parser, ds->vat, core->flags, r_asm_op_get_asm (&asmop), str,
|
||||
sizeof (str), core->print->big_endian);
|
||||
|
||||
r_cons_printf (j > 0 ? ",{" : "{");
|
||||
@ -5542,7 +5542,7 @@ R_API int r_core_print_disasm_all(RCore *core, ut64 addr, int l, int len, int mo
|
||||
count ++;
|
||||
switch (mode) {
|
||||
case 'i':
|
||||
r_parse_filter (core->parser, core->flags, r_asm_op_get_asm (&asmop),
|
||||
r_parse_filter (core->parser, ds->vat, core->flags, r_asm_op_get_asm (&asmop),
|
||||
str, sizeof (str), core->print->big_endian);
|
||||
if (scr_color) {
|
||||
RAnalOp aop;
|
||||
@ -5815,7 +5815,7 @@ toro:
|
||||
}
|
||||
if (filter) {
|
||||
core->parser->hint = r_anal_hint_get (core->anal, at);
|
||||
r_parse_filter (core->parser, core->flags,
|
||||
r_parse_filter (core->parser, at, core->flags,
|
||||
asm_str, opstr, sizeof (opstr) - 1, core->print->big_endian);
|
||||
asm_str = (char *)&opstr;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2017 - pancake, nibble */
|
||||
/* radare - LGPL - Copyright 2009-2018 - pancake, nibble */
|
||||
|
||||
#ifndef R2_PARSE_H
|
||||
#define R2_PARSE_H
|
||||
@ -24,6 +24,7 @@ typedef struct r_parse_t {
|
||||
int notin_flagspace;
|
||||
bool pseudo;
|
||||
bool relsub; // replace rip relative expressions in instruction
|
||||
bool tailsub; // replace any immediate relative to current address with .. prefix syntax
|
||||
bool localvar_only; // if true use only the local variable name (e.g. [local_10h] instead of [ebp + local10h])
|
||||
int relsub_addr;
|
||||
int minval;
|
||||
@ -43,7 +44,7 @@ typedef struct r_parse_plugin_t {
|
||||
int (*fini)(void *user);
|
||||
int (*parse)(RParse *p, const char *data, char *str);
|
||||
int (*assemble)(RParse *p, char *data, char *str);
|
||||
int (*filter)(RParse *p, RFlag *f, char *data, char *str, int len, bool big_endian);
|
||||
int (*filter)(RParse *p, ut64 addr, RFlag *f, char *data, char *str, int len, bool big_endian);
|
||||
bool (*varsub)(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len);
|
||||
int (*replace)(int argc, const char *argv[], char *newstr);
|
||||
} RParsePlugin;
|
||||
@ -57,7 +58,7 @@ R_API int r_parse_list(RParse *p);
|
||||
R_API int r_parse_use(RParse *p, const char *name);
|
||||
R_API int r_parse_parse(RParse *p, const char *data, char *str);
|
||||
R_API int r_parse_assemble(RParse *p, char *data, char *str);
|
||||
R_API int r_parse_filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_endian);
|
||||
R_API int r_parse_filter(RParse *p, ut64 addr, RFlag *f, char *data, char *str, int len, bool big_endian);
|
||||
R_API bool r_parse_varsub(RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len);
|
||||
R_API char *r_parse_c_string(RAnal *anal, const char *code);
|
||||
R_API char *r_parse_c_file(RAnal *anal, const char *path);
|
||||
|
@ -64,6 +64,7 @@ R_API ut64 r_num_get_input_value(RNum *num, const char *input_value);
|
||||
R_API const char *r_num_get_name(RNum *num, ut64 n);
|
||||
R_API char* r_num_as_string(RNum *___, ut64 n, bool printable_only);
|
||||
R_API ut64 r_num_tail(RNum *num, ut64 addr, const char *hex);
|
||||
R_API ut64 r_num_tail_base(RNum *num, ut64 addr, ut64 off);
|
||||
R_API void r_num_minmax_swap(ut64 *a, ut64 *b);
|
||||
R_API void r_num_minmax_swap_i(int *a, int *b); // XXX this can be a cpp macro :??
|
||||
R_API ut64 r_num_math(RNum *num, const char *str);
|
||||
|
@ -1,16 +1,16 @@
|
||||
#ifndef R_STR_UTIL_H
|
||||
#define R_STR_UTIL_H
|
||||
|
||||
#define IS_NULLSTR(x) (!x||!*x)
|
||||
#define IS_WHITECHAR(x) ((x)==' '||(x)=='\t'||(x)=='\n'||(x)=='\r')
|
||||
#define IS_SEPARATOR(x) ((x)==' '||(x)=='\t'||(x)=='\n'||(x)=='\r'||(x)==' '|| \
|
||||
(x)==','||(x)==';'||(x)==':'||(x)=='['||(x)==']'|| \
|
||||
(x)=='('||(x)==')'||(x)=='{'||(x)=='}')
|
||||
#define IS_HEXCHAR(x) ((x>='0'&&x<='9') || (x>='a'&&x<='f') || (x>='A'&&x<='F'))
|
||||
#define IS_PRINTABLE(x) (x>=' '&&x<='~')
|
||||
#define IS_DIGIT(x) (x>='0'&&x<='9')
|
||||
#define IS_NULLSTR(x) (!(x) || !*(x))
|
||||
#define IS_WHITECHAR(x) ((x) == ' ' || (x)=='\t' || (x) == '\n' || (x) == '\r')
|
||||
#define IS_SEPARATOR(x) ((x) == ' ' || (x)=='\t' || (x) == '\n' || (x) == '\r' || (x) == ' '|| \
|
||||
(x) == ',' || (x) == ';' || (x) == ':' || (x) == '[' || (x) == ']' || \
|
||||
(x) == '(' || (x) == ')' || (x) == '{' || (x) == '}')
|
||||
#define IS_HEXCHAR(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
|
||||
#define IS_PRINTABLE(x) ((x) >=' ' && (x) <= '~')
|
||||
#define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')
|
||||
#define IS_OCTAL(x) ((x) >= '0' && (x) <= '7')
|
||||
#define IS_WHITESPACE(x) ((x)==' '||(x)=='\t')
|
||||
#define IS_WHITESPACE(x) ((x) == ' ' || (x) == '\t')
|
||||
#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
|
||||
|
||||
|
@ -20,6 +20,8 @@ CFLAGS+=-DCORELIB
|
||||
STATIC_OBJS=$(subst ..,p/..,$(subst parse_,p/parse_,$(STATIC_OBJ)))
|
||||
OBJS=parse.o code.o ${STATIC_OBJS}
|
||||
|
||||
pre:
|
||||
|
||||
bins:
|
||||
# @cd t && ${MAKE} all
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
/* radare - LGPL - Copyright 2015-2016 - pancake */
|
||||
/* radare - LGPL - Copyright 2015-2018 - pancake */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <r_lib.h>
|
||||
#include <r_util.h>
|
||||
#include <r_flag.h>
|
||||
|
@ -27,6 +27,7 @@ R_API RParse *r_parse_new() {
|
||||
p->flagspace = -1;
|
||||
p->pseudo = false;
|
||||
p->relsub = false;
|
||||
p->tailsub = false;
|
||||
p->minval = 0x100;
|
||||
p->localvar_only = false;
|
||||
for (i = 0; parse_static_plugins[i]; i++) {
|
||||
@ -181,7 +182,22 @@ static char *findNextNumber(char *op) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_endian) {
|
||||
static char *findEnd(const char *s) {
|
||||
while (*s == 'x' || IS_HEXCHAR (*s)) {
|
||||
s++;
|
||||
// also skip ansi escape codes here :?
|
||||
}
|
||||
return strdup (s);
|
||||
}
|
||||
|
||||
static void insert(char *dst, const char *src) {
|
||||
char *endNum = findEnd (dst);
|
||||
strcpy (dst, src);
|
||||
strcpy (dst + strlen (src), endNum);
|
||||
free (endNum);
|
||||
}
|
||||
|
||||
static int filter(RParse *p, ut64 addr, RFlag *f, char *data, char *str, int len, bool big_endian) {
|
||||
char *ptr = data, *ptr2, *ptr_backup;
|
||||
RAnalFunction *fcn;
|
||||
RFlagItem *flag;
|
||||
@ -202,11 +218,13 @@ static int filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_
|
||||
#if FILTER_DWORD
|
||||
ptr2 = strstr (ptr, "dword ");
|
||||
if (ptr2) {
|
||||
memmove (ptr2, ptr2 + 6, strlen (ptr2 + 6) + 1);
|
||||
char *src = ptr2 + 6;
|
||||
memmove (ptr2, src, strlen (src) + 1);
|
||||
}
|
||||
ptr2 = strstr (ptr, "qword ");
|
||||
if (ptr2) {
|
||||
memmove (ptr2, ptr2 + 6, strlen (ptr2 + 6) + 1);
|
||||
char *src = ptr2 + 6;
|
||||
memmove (ptr2, src, strlen (src) + 1);
|
||||
}
|
||||
#endif
|
||||
ptr2 = NULL;
|
||||
@ -301,7 +319,7 @@ static int filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_
|
||||
banned = true;
|
||||
}
|
||||
}
|
||||
if (p->relsub_addr && !banned) { // && strstr (str, " + ")) {
|
||||
if (p->relsub_addr && !banned) {
|
||||
int flag_len = strlen (flag->name);
|
||||
char *ptr_end = str + strlen (data) + flag_len - 1;
|
||||
char *ptr_right = ptr_end + 1, *ptr_left, *ptr_esc;
|
||||
@ -342,14 +360,12 @@ static int filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_
|
||||
if (copied_len < 1) {
|
||||
break;
|
||||
}
|
||||
char *dptr_left;
|
||||
char *dptr_end;
|
||||
memmove (ptr_left, ptr_esc, copied_len);
|
||||
dptr_left = strcpy (ptr_left + copied_len,
|
||||
char *dptr_left = strcpy (ptr_left + copied_len,
|
||||
(ansi_found && ptr_right - ptr_end + 1 >= 4) ? Color_RESET : "");
|
||||
int dlen = strlen (dptr_left);
|
||||
dptr_left += dlen;
|
||||
dptr_end = ptr_right + 1;
|
||||
char *dptr_end = ptr_right + 1;
|
||||
while (*dptr_end) {
|
||||
dptr_end++;
|
||||
}
|
||||
@ -362,6 +378,20 @@ static int filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (p->tailsub) { // && off > UT32_MAX && addr > UT32_MAX) {
|
||||
if (off != UT64_MAX) {
|
||||
if (off == addr) {
|
||||
insert (ptr, "$$");
|
||||
} else {
|
||||
ut64 tail = r_num_tail_base (NULL, addr, off);
|
||||
if (tail != UT64_MAX) {
|
||||
char str[128];
|
||||
snprintf (str, sizeof (str), "..%"PFMT64x, tail);
|
||||
insert (ptr, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p->hint) {
|
||||
@ -540,10 +570,10 @@ R_API char *r_parse_immtrim (char *opstr) {
|
||||
return opstr;
|
||||
}
|
||||
|
||||
R_API int r_parse_filter(RParse *p, RFlag *f, char *data, char *str, int len, bool big_endian) {
|
||||
filter (p, f, data, str, len, big_endian);
|
||||
R_API int r_parse_filter(RParse *p, ut64 addr, RFlag *f, char *data, char *str, int len, bool big_endian) {
|
||||
filter (p, addr, f, data, str, len, big_endian);
|
||||
if (p->cur && p->cur->filter) {
|
||||
return p->cur->filter (p, f, data, str, len, big_endian);
|
||||
return p->cur->filter (p, addr, f, data, str, len, big_endian);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -668,6 +668,28 @@ static bool isHexDigit (const char _ch) {
|
||||
return (ch >= 'a' && ch <= 'f');
|
||||
}
|
||||
|
||||
static int nth (ut64 n, int i) {
|
||||
int sz = (sizeof (n) << 1) - 1;
|
||||
int s = (sz - i) * 4;
|
||||
return (n >> s) & 0xf;
|
||||
}
|
||||
|
||||
R_API ut64 r_num_tail_base(RNum *num, ut64 addr, ut64 off) {
|
||||
int i;
|
||||
bool ready = false;
|
||||
ut64 res = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
ut64 o = nth (off, i);
|
||||
if (!ready && nth (addr, i) == o) {
|
||||
continue;
|
||||
}
|
||||
ready = true;
|
||||
ut8 pos = (15 - i) * 4;
|
||||
res |= (o << pos);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
R_API ut64 r_num_tail(RNum *num, ut64 addr, const char *hex) {
|
||||
ut64 mask = 0LL;
|
||||
ut64 n = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user