mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 05:40:10 +00:00
Better support for IO ports on asm.pseudo and analysis
* Analyze IO opcodes on x86 * Fix 0x0x in olly disasm * Fix segfault in objc mangling * Support for writing nibbles with 'wx' * If optype is IO, use 'ports' flagspace * Add support for flagspaces in RParse * Use RList in RParse instead of list.h * asm.pseudo handles for in/out x86 opcodes * Random code cleanup * Fix udis86 64bit disasm bug
This commit is contained in:
parent
1cd860aab6
commit
8e1dbb443a
@ -831,6 +831,18 @@ static int x86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (io.id) {
|
||||
case X86IM_IO_ID_OUT_IM:
|
||||
case X86IM_IO_ID_OUT_RG:
|
||||
case X86IM_IO_ID_OUTSX:
|
||||
op->type = R_ANAL_OP_TYPE_IO;
|
||||
break;
|
||||
case X86IM_IO_ID_IN_IM:
|
||||
case X86IM_IO_ID_IN_RG:
|
||||
case X86IM_IO_ID_INSX:
|
||||
op->type = R_ANAL_OP_TYPE_IO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == X86IM_STATUS_SUCCESS) {
|
||||
if (io.len > len)
|
||||
|
@ -640,7 +640,7 @@ static void DecodeRJ(ulong offsize,ulong nextip) {
|
||||
else
|
||||
i=0;
|
||||
if (symbolic==0 || i==0)
|
||||
nresult+=sprintf(da->result+nresult,"0x"LFMT08,addr);
|
||||
nresult+=sprintf(da->result+nresult,LFMT08,addr);
|
||||
else
|
||||
nresult+=sprintf(da->result+nresult,"%.*s",TEXTLEN-nresult-25,s);
|
||||
if (symbolic==0 && i!=0 && da->comment[0]=='\0')
|
||||
|
@ -156,7 +156,7 @@
|
||||
#define ulong unsigned int
|
||||
#define slong int
|
||||
#define LFMT "%d"
|
||||
#define LFMT08 "0x%08X"
|
||||
#define LFMT08 "0x%08x"
|
||||
//typedef unsigned char uchar; // Unsigned character (byte)
|
||||
//typedef unsigned short ushort; // Unsigned short
|
||||
//typedef unsigned int uint; // Unsigned integer
|
||||
|
@ -7,7 +7,11 @@ R_API int r_bin_lang_objc(RBin *bin) {
|
||||
RBinSymbol *sym;
|
||||
int hasobjc = R_FALSE;
|
||||
char *dsym;
|
||||
const char *ft = bin->cur.o->info->rclass;
|
||||
const char *ft;
|
||||
|
||||
if (!bin || !bin->cur.o || !bin->cur.o->info)
|
||||
return 0;
|
||||
ft = bin->cur.o->info->rclass;
|
||||
|
||||
if (!ft || (!strstr (ft, "mach") && !strstr (ft, "elf")))
|
||||
return 0;
|
||||
|
@ -190,10 +190,18 @@ static int cmd_write(void *data, const char *input) {
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
int len = strlen (input);
|
||||
int b, len = strlen (input);
|
||||
ut8 *buf = malloc (len+1);
|
||||
len = r_hex_str2bin (input+1, buf);
|
||||
if (len != -1) {
|
||||
if (len != 0) {
|
||||
int last_is_nibble;
|
||||
if (len<0) {
|
||||
last_is_nibble = R_TRUE;
|
||||
len = -len+1;
|
||||
} else last_is_nibble = R_FALSE;
|
||||
b = core->block[len]&0xf;
|
||||
b |= (buf[len]&0xf0);
|
||||
buf[len] = b;
|
||||
r_core_write_at (core, core->offset, buf, len);
|
||||
WSEEK (core, len);
|
||||
r_core_block_read (core, 0);
|
||||
|
@ -545,18 +545,32 @@ else
|
||||
char *tmpopstr = r_anal_op_to_string (core->anal, &analop);
|
||||
// TODO: Use data from code analysis..not raw analop here
|
||||
// if we want to get more information
|
||||
opstr = (tmpopstr)? tmpopstr: strdup (asmop.buf_asm);
|
||||
opstr = tmpopstr? tmpopstr: strdup (asmop.buf_asm);
|
||||
} else if (pseudo) {
|
||||
r_parse_parse (core->parser, asmop.buf_asm, str);
|
||||
opstr = str;
|
||||
} else if (filter) {
|
||||
r_parse_filter (core->parser, core->flags, asmop.buf_asm, str, sizeof (str));
|
||||
int ofs = core->parser->flagspace;
|
||||
switch (analop.type) {
|
||||
case R_ANAL_OP_TYPE_IO:
|
||||
core->parser->flagspace = r_flag_space_get (
|
||||
core->flags, "ports");
|
||||
break;
|
||||
default:
|
||||
core->parser->flagspace = -1;
|
||||
break;
|
||||
}
|
||||
r_parse_filter (core->parser, core->flags,
|
||||
asmop.buf_asm, str, sizeof (str));
|
||||
core->parser->flagspace = ofs;
|
||||
opstr = str;
|
||||
} else opstr = asmop.buf_asm;
|
||||
if (varsub) {
|
||||
RAnalFunction *f = r_anal_fcn_find (core->anal, at, R_ANAL_FCN_TYPE_NULL);
|
||||
RAnalFunction *f = r_anal_fcn_find (core->anal,
|
||||
at, R_ANAL_FCN_TYPE_NULL);
|
||||
if (f) {
|
||||
r_parse_varsub (core->parser, f, opstr, strsub, sizeof (strsub));
|
||||
r_parse_varsub (core->parser, f,
|
||||
opstr, strsub, sizeof (strsub));
|
||||
if (decode) free (opstr);
|
||||
opstr = strsub;
|
||||
}
|
||||
@ -575,7 +589,8 @@ else
|
||||
while (len--)
|
||||
r_cons_strcat (" ");
|
||||
if (show_color)
|
||||
r_cons_printf (Color_TURQOISE" ; %s"Color_RESET"%s", sl, pre);
|
||||
r_cons_printf (Color_TURQOISE
|
||||
" ; %s"Color_RESET"%s", sl, pre);
|
||||
else r_cons_printf (" ; %s\n%s", sl, pre);
|
||||
free (osl);
|
||||
osl = sl;
|
||||
@ -590,9 +605,8 @@ else
|
||||
ret -= middle;
|
||||
r_cons_printf (" ; *middle* %d", ret);
|
||||
}
|
||||
if (asmop.payload != 0) {
|
||||
if (asmop.payload != 0)
|
||||
r_cons_printf ("\n; .. payload of %d bytes", asmop.payload);
|
||||
}
|
||||
if (core->assembler->syntax != R_ASM_SYNTAX_INTEL) {
|
||||
RAsmOp ao; /* disassemble for the vm .. */
|
||||
int os = core->assembler->syntax;
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* radare - LGPL - Copyright 2008-2011 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2008-2012 - pancake */
|
||||
|
||||
#include <r_flags.h>
|
||||
|
||||
R_API int r_flag_space_get(struct r_flag_t *f, const char *name) {
|
||||
R_API int r_flag_space_get(RFlag *f, const char *name) {
|
||||
int i;
|
||||
for (i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
for (i=0; i<R_FLAG_SPACES_MAX; i++) {
|
||||
if (f->spaces[i] != NULL)
|
||||
if (!strcmp (name, f->spaces[i]))
|
||||
return i;
|
||||
|
@ -357,6 +357,7 @@ enum {
|
||||
R_ANAL_OP_FAMILY_LAST
|
||||
};
|
||||
|
||||
// XXX: this definition is plain wrong. use enum or empower bits
|
||||
enum {
|
||||
R_ANAL_OP_TYPE_NULL = 0x0,
|
||||
R_ANAL_OP_TYPE_JMP = 0x1, /* mandatory jump */
|
||||
@ -378,6 +379,7 @@ enum {
|
||||
R_ANAL_OP_TYPE_CMP = 0x10000, /* copmpare something */
|
||||
R_ANAL_OP_TYPE_ADD = 0x20000,
|
||||
R_ANAL_OP_TYPE_SUB = 0x40000,
|
||||
R_ANAL_OP_TYPE_IO = 0x80000,
|
||||
R_ANAL_OP_TYPE_MUL = 0x100000,
|
||||
R_ANAL_OP_TYPE_DIV = 0x200000,
|
||||
R_ANAL_OP_TYPE_SHR = 0x400000,
|
||||
|
@ -13,8 +13,9 @@
|
||||
|
||||
typedef struct r_parse_t {
|
||||
void *user;
|
||||
int flagspace;
|
||||
struct r_parse_plugin_t *cur;
|
||||
struct list_head parsers;
|
||||
RList *parsers;
|
||||
} RParse;
|
||||
|
||||
typedef struct r_parse_plugin_t {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2012 nibble */
|
||||
/* radare - LGPL - Copyright 2009-2012 - nibble, pancake */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -16,6 +16,8 @@ static int replace(int argc, const char *argv[], char *newstr) {
|
||||
char *op;
|
||||
char *str;
|
||||
} ops[] = {
|
||||
{ "in", "1 = io[2]"},
|
||||
{ "out", "io[1] = 2"},
|
||||
{ "cmp", "cmp 1, 2"},
|
||||
{ "test", "cmp 1, 2"},
|
||||
{ "lea", "1 = 2"},
|
||||
@ -63,16 +65,12 @@ static int replace(int argc, const char *argv[], char *newstr) {
|
||||
strcat (newstr, (i == 0 || i== argc - 1)?" ":",");
|
||||
}
|
||||
}
|
||||
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
static int parse(RParse *p, const char *data, char *str) {
|
||||
char w0[64], w1[64], w2[64], w3[64];
|
||||
int i, len = strlen (data);
|
||||
char w0[64];
|
||||
char w1[64];
|
||||
char w2[64];
|
||||
char w3[64];
|
||||
char *buf, *ptr, *optr;
|
||||
|
||||
// malloc can be slow here :?
|
||||
@ -81,10 +79,7 @@ static int parse(RParse *p, const char *data, char *str) {
|
||||
memcpy (buf, data, len+1);
|
||||
|
||||
if (*buf) {
|
||||
w0[0]='\0';
|
||||
w1[0]='\0';
|
||||
w2[0]='\0';
|
||||
w3[0]='\0';
|
||||
*w0 = *w1 = *w2 = *w3 = '\0';
|
||||
ptr = strchr (buf, ' ');
|
||||
if (ptr == NULL)
|
||||
ptr = strchr (buf, '\t');
|
||||
@ -94,14 +89,14 @@ static int parse(RParse *p, const char *data, char *str) {
|
||||
strcpy (w0, buf);
|
||||
strcpy (w1, ptr);
|
||||
|
||||
optr=ptr;
|
||||
optr = ptr;
|
||||
ptr = strchr (ptr, ',');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
for (++ptr; *ptr==' '; ptr++);
|
||||
strcpy (w1, optr);
|
||||
strcpy (w2, ptr);
|
||||
optr=ptr;
|
||||
optr = ptr;
|
||||
ptr = strchr (ptr, ',');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
@ -137,22 +132,26 @@ static int assemble(RParse *p, char *data, char *str) {
|
||||
}
|
||||
|
||||
static int filter(RParse *p, RFlag *f, char *data, char *str, int len) {
|
||||
char *ptr = data, *ptr2;
|
||||
RListIter *iter;
|
||||
RFlagItem *flag;
|
||||
char *ptr, *ptr2;
|
||||
ut64 off;
|
||||
ptr = data;
|
||||
|
||||
while ((ptr = strstr (ptr, "0x"))) {
|
||||
for (ptr2 = ptr; *ptr2 && !isseparator (*ptr2); ptr2++);
|
||||
off = r_num_math (NULL, ptr);
|
||||
if(!off){
|
||||
ptr=ptr2;
|
||||
ptr = ptr2;
|
||||
continue;
|
||||
}
|
||||
// XXX. tooslow
|
||||
r_list_foreach (f->flags, iter, flag) {
|
||||
if (flag->offset == off && strchr (flag->name, '.')) {
|
||||
if (p->flagspace && !(p->flagspace & flag->space))
|
||||
continue;
|
||||
*ptr = 0;
|
||||
snprintf (str, len, "%s%s%s", data, flag->name, ptr2!=ptr? ptr2: "");
|
||||
snprintf (str, len, "%s%s%s", data, flag->name,
|
||||
ptr2!=ptr? ptr2: "");
|
||||
return R_TRUE;
|
||||
}
|
||||
}
|
||||
@ -163,16 +162,17 @@ static int filter(RParse *p, RFlag *f, char *data, char *str, int len) {
|
||||
}
|
||||
|
||||
static int varsub(RParse *p, RAnalFunction *f, char *data, char *str, int len) {
|
||||
char *ptr, *ptr2;
|
||||
int i;
|
||||
|
||||
char *ptr, *ptr2;
|
||||
strncpy (str, data, len);
|
||||
for (i = 0; i < R_ANAL_VARSUBS; i++)
|
||||
if (f->varsubs[i].pat[0] != '\0' && f->varsubs[i].sub[0] != '\0' &&
|
||||
if (f->varsubs[i].pat[0] != '\0' && \
|
||||
f->varsubs[i].sub[0] != '\0' && \
|
||||
(ptr = strstr (data, f->varsubs[i].pat))) {
|
||||
*ptr = '\0';
|
||||
ptr2 = ptr + strlen (f->varsubs[i].pat);
|
||||
snprintf (str, len, "%s%s%s", data, f->varsubs[i].sub, ptr2);
|
||||
snprintf (str, len, "%s%s%s", data,
|
||||
f->varsubs[i].sub, ptr2);
|
||||
}
|
||||
return R_TRUE;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2011 nibble<.ds@gmail.com>, pancake<@nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2009-2012 - nibble, pancake */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -16,44 +16,34 @@ R_API RParse *r_parse_new() {
|
||||
RParse *p = R_NEW (RParse);
|
||||
if (!p) return NULL;
|
||||
p->user = NULL;
|
||||
INIT_LIST_HEAD (&p->parsers);
|
||||
for (i=0; parse_static_plugins[i];i++) {
|
||||
p->parsers = r_list_new ();
|
||||
p->parsers->free = NULL; // memleak
|
||||
p->flagspace = 0;
|
||||
for (i=0; parse_static_plugins[i]; i++) {
|
||||
static_plugin = R_NEW (RParsePlugin);
|
||||
memcpy (static_plugin, parse_static_plugins[i], sizeof (RParsePlugin));
|
||||
memcpy (static_plugin, parse_static_plugins[i],
|
||||
sizeof (RParsePlugin));
|
||||
r_parse_add (p, static_plugin);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
R_API void r_parse_free(RParse *p) {
|
||||
r_list_free (p->parsers);
|
||||
free (p);
|
||||
}
|
||||
|
||||
R_API void r_parse_set_user_ptr(RParse *p, void *user) {
|
||||
p->user = user;
|
||||
}
|
||||
|
||||
R_API int r_parse_add(RParse *p, RParsePlugin *foo) {
|
||||
if (foo->init)
|
||||
foo->init (p->user);
|
||||
list_add_tail (&(foo->list), &(p->parsers));
|
||||
r_list_append (p->parsers, foo);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
// DEPRECATE. only for debug
|
||||
R_API int r_parse_list(RParse *p) {
|
||||
struct list_head *pos;
|
||||
list_for_each_prev (pos, &p->parsers) {
|
||||
RParsePlugin *h = list_entry (pos, RParsePlugin, list);
|
||||
printf ("parse %10s %s\n", h->name, h->desc);
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_parse_use(RParse *p, const char *name) {
|
||||
struct list_head *pos;
|
||||
list_for_each_prev (pos, &p->parsers) {
|
||||
RParsePlugin *h = list_entry (pos, RParsePlugin, list);
|
||||
RListIter *iter;
|
||||
RParsePlugin *h;
|
||||
r_list_foreach (p->parsers, iter, h) {
|
||||
if (!strcmp (h->name, name)) {
|
||||
p->cur = h;
|
||||
return R_TRUE;
|
||||
@ -63,8 +53,8 @@ R_API int r_parse_use(RParse *p, const char *name) {
|
||||
}
|
||||
|
||||
R_API int r_parse_assemble(RParse *p, char *data, char *str) {
|
||||
int ret = R_FALSE;
|
||||
char *in = strdup (str);
|
||||
int ret = R_FALSE;
|
||||
char *s, *o;
|
||||
|
||||
data[0]='\0';
|
||||
@ -105,3 +95,23 @@ R_API int r_parse_varsub(RParse *p, RAnalFunction *f, char *data, char *str, int
|
||||
return p->cur->varsub (p, f, data, str, len);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
/* setters */
|
||||
R_API void r_parse_set_user_ptr(RParse *p, void *user) {
|
||||
p->user = user;
|
||||
}
|
||||
|
||||
R_API void r_parse_set_flagspace(RParse *p, int fs) {
|
||||
p->flagspace = fs;
|
||||
}
|
||||
|
||||
/* TODO: DEPRECATE */
|
||||
R_API int r_parse_list(RParse *p) {
|
||||
RListIter *iter;
|
||||
RParsePlugin *h;
|
||||
r_list_foreach (p->parsers, iter, h) {
|
||||
printf ("parse %10s %s\n", h->name, h->desc);
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,6 @@ R_API int r_hex_str2bin(const char *in, ut8 *out) {
|
||||
out[len] = c;
|
||||
len = -len;
|
||||
}
|
||||
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
|
@ -115,10 +115,10 @@ gen_operand(struct ud* u, struct ud_operand* op)
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
|
||||
break;
|
||||
case 16:
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sword ) & 0xffff );
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sword )); // & 0xffff );
|
||||
break;
|
||||
case 32:
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sdword ) & 0xfffffffful );
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sdword )); // & 0xfffffffful );
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
|
@ -127,13 +127,11 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
|
||||
/* push sign-extends to operand size */
|
||||
sext_size = u->opr_mode;
|
||||
}
|
||||
if ( sext_size < 64 )
|
||||
sext_mask = ( 1ull << sext_size ) - 1;
|
||||
mkasm( u, "0x" FMT64 "x", imm & sext_mask );
|
||||
|
||||
if ( sext_size < 64 )
|
||||
sext_mask = ( 1ull << sext_size ) - 1;
|
||||
mkasm( u, "0x" FMT64 "x", imm & sext_mask );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case UD_OP_JIMM:
|
||||
if (syn_cast) opr_cast(u, op);
|
||||
@ -142,10 +140,10 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
|
||||
break;
|
||||
case 16:
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sword ) & 0xffff );
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sword )); // & 0xffff );
|
||||
break;
|
||||
case 32:
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sdword ) & 0xfffffffful );
|
||||
mkasm(u, "0x" FMT64 "x", ( u->pc + op->lval.sdword )); // & 0xfffffffful );
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user