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:
pancake 2012-11-13 00:53:52 +01:00
parent 1cd860aab6
commit 8e1dbb443a
14 changed files with 118 additions and 70 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -111,7 +111,6 @@ R_API int r_hex_str2bin(const char *in, ut8 *out) {
out[len] = c;
len = -len;
}
return (int)len;
}

View File

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

View File

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