Initial implementatil of asm.tailsub (#11696)

This commit is contained in:
radare 2018-09-30 11:41:19 -04:00 committed by GitHub
parent 883abe417f
commit 47297f6d0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 106 additions and 40 deletions

View File

@ -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");

View File

@ -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,

View File

@ -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++;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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')

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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;