Add RAnalOp.prefix and handle it from x86.udis, Colorize 'ao'

This commit is contained in:
pancake 2014-10-17 01:15:17 +02:00
parent 1c4c0cdb68
commit cc8566b671
3 changed files with 80 additions and 18 deletions

View File

@ -73,6 +73,18 @@ static int getarg(char *src, struct ud *u, st64 mask, int idx, int regsz) {
src[0] = 0;
if (!mask) mask = UT64_MAX;
#if 0
u->pfx_seg = 0;
u->pfx_opr = 0;
u->pfx_adr = 0;
u->pfx_lock = 0;
u->pfx_repne = 0;
u->pfx_rep = 0;
u->pfx_repe = 0;
u->pfx_rex = 0;
u->pfx_str = 0;
#endif
switch (op->type) {
case UD_OP_PTR:
case UD_OP_CONST:
@ -206,6 +218,11 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
}
handler->callback (&info, op, dst, src, str);
}
op->prefix = 0;
if (u.pfx_rep) op->prefix |= R_ANAL_OP_PREFIX_REP;
if (u.pfx_repe) op->prefix |= R_ANAL_OP_PREFIX_REPE;
if (u.pfx_repne) op->prefix |= R_ANAL_OP_PREFIX_REPNE;
if (u.pfx_lock) op->prefix |= R_ANAL_OP_PREFIX_LOCK;
switch (u.mnemonic) {
case UD_Iinvalid:
oplen = op->size = -1;

View File

@ -216,9 +216,12 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops, i
RAnalOp op;
ut64 addr;
RAnalHint *hint;
if (fmt=='j') {
int use_color = core->print->flags & R_PRINT_FLAGS_COLOR;
const char *color = "";
if (use_color)
color = core->cons->pal.label;
if (fmt=='j')
r_cons_printf ("[");
}
for (i=idx=ret=0; idx<len && (!nops|| (nops&&i<nops)); i++, idx+=ret) {
addr = core->offset+idx;
// TODO: use more anal hints
@ -237,6 +240,7 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops, i
r_cons_printf ("{\"opcode\": \"%s\",", asmop.buf_asm);
if (hint && hint->opcode)
r_cons_printf ("\"ophint\": \"%s\",", hint->opcode);
r_cons_printf ("\"prefix\": %"PFMT64d",", op.prefix);
r_cons_printf ("\"addr\": %"PFMT64d",", core->offset+idx);
r_cons_printf ("\"bytes\": \"");
for (j=0; j<size; j++)
@ -269,11 +273,19 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops, i
(op.type &R_ANAL_OP_TYPE_COND)?1: op.cond);
r_cons_printf ("\"family\":%d}", op.family);
} else {
r_cons_printf ("opcode: %s\n", asmop.buf_asm);
if (hint && hint->opcode)
r_cons_printf ("ophint: %s\n", hint->opcode);
r_cons_printf ("addr: 0x%08"PFMT64x"\n", core->offset+idx);
r_cons_printf ("bytes: ");
#define printline(k,fmt,arg) {\
if (use_color) r_cons_printf ("%s%s: "Color_RESET, color, k); \
else r_cons_printf ("%s: ", k); \
if (fmt) r_cons_printf (fmt, arg); \
}
printline ("opcode", "%s\n", asmop.buf_asm);
if (hint) {
if (hint->opcode)
printline ("ophint", "%s\n", hint->opcode);
printline ("addr", "0x%08"PFMT64x"\n", (hint->addr+idx));
}
printline ("prefix", "%"PFMT64d"\n", op.prefix);
printline ("bytes", NULL, 0);
for (j=0; j<size; j++)
r_cons_printf ("%02x", buf[j]);
r_cons_newline ();
@ -281,25 +293,23 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops, i
r_cons_printf ("val: 0x%08"PFMT64x"\n", op.val);
if (op.ptr != UT64_MAX)
r_cons_printf ("ptr: 0x%08"PFMT64x"\n", op.ptr);
r_cons_printf ("size: %d\n", size);
r_cons_printf ("type: %d (%s)\n", (int)(op.type & 0xffff),
r_anal_optype_to_string (op.type)); // TODO: string
printline ("size", "%d\n", size);
printline ("type","%s\n", r_anal_optype_to_string (op.type));
if (*R_STRBUF_SAFEGET (&op.esil))
r_cons_printf ("esil: %s\n", R_STRBUF_SAFEGET (&op.esil));
printline ("esil", "%s\n", R_STRBUF_SAFEGET (&op.esil));
if (hint && hint->jump != UT64_MAX)
op.jump = hint->jump;
if (op.jump != UT64_MAX)
r_cons_printf ("jump: 0x%08"PFMT64x"\n", op.jump);
printline ("jump","0x%08"PFMT64x"\n", op.jump);
if (hint && hint->fail != UT64_MAX)
op.fail = hint->fail;
if (op.fail != UT64_MAX)
r_cons_printf ("fail: 0x%08"PFMT64x"\n", op.fail);
r_cons_printf ("stack: %s\n", r_anal_stackop_tostring (op.stackop));
r_cons_printf ("cond: %d\n",
(op.type &R_ANAL_OP_TYPE_COND)?1: op.cond);
r_cons_printf ("family: %d\n", op.family);
printline ("stack","%s\n", r_anal_stackop_tostring (op.stackop));
printline ("cond","%d\n", (op.type &R_ANAL_OP_TYPE_COND)?1: op.cond);
printline ("family","%d\n", op.family);
}
//r_cons_printf ("false: 0x%08"PFMT64x"\n", core->offset+idx);
//free (hint);

View File

@ -339,9 +339,43 @@ enum {
R_ANAL_OP_FAMILY_LAST
};
#if 0
On x86 acording to Wikipedia
Prefix group 1
0xF0: LOCK prefix
0xF2: REPNE/REPNZ prefix
0xF3: REP or REPE/REPZ prefix
Prefix group 2
0x2E: CS segment override
0x36: SS segment override
0x3E: DS segment override
0x26: ES segment override
0x64: FS segment override
0x65: GS segment override
0x2E: Branch not taken (hinting)
0x3E: Branch taken
Prefix group 3
0x66: Operand-size override prefix
Prefix group 4
0x67: Address-size override prefix
#endif
typedef enum {
R_ANAL_OP_PREFIX_COND = 1,
R_ANAL_OP_PREFIX_REP = 1<<1,
R_ANAL_OP_PREFIX_REPE = 1<<2,
R_ANAL_OP_PREFIX_REPNE = 1<<3,
R_ANAL_OP_PREFIX_LOCK = 1<<4,
R_ANAL_OP_PREFIX_LIKELY = 1<<5,
R_ANAL_OP_PREFIX_UNLIKELY = 1<<6
/* TODO: add segment override typemods? */
} RAnalOpPrefix;
// XXX: this definition is plain wrong. use enum or empower bits
typedef enum {
R_ANAL_OP_TYPE_COND = 0x80000000,
R_ANAL_OP_TYPE_COND = 0x80000000, // TODO must be moved to prefix?
//TODO: MOVE TO PREFIX .. it is used by anal_ex.. must be updated
R_ANAL_OP_TYPE_REP = 0x40000000, /* repeats next instruction N times */
R_ANAL_OP_TYPE_NULL = 0,
R_ANAL_OP_TYPE_JMP = 1, /* mandatory jump */
@ -562,7 +596,8 @@ typedef struct r_anal_op_t {
char *mnemonic; /* mnemonic */
ut64 addr; /* address */
ut64 type; /* type of opcode */
ut64 type2;
ut64 prefix; /* type of opcode prefix (rep,lock,..) */
ut64 type2; // used by java
int stackop; /* operation on stack? */
int cond; /* condition type */
int size; /* size in bytes of opcode */