Add mips pseudocode, anal.hasnext, fix anal bugs

Better mips analysis
Implemented mips pseudocode plugin
Change asm.parser in asm.arch callback
This commit is contained in:
pancake 2012-08-31 11:45:06 +02:00
parent 48ea6840f5
commit 5c236fa0e3
26 changed files with 443 additions and 145 deletions

6
TODO
View File

@ -5,6 +5,12 @@
------8<-------------------8<--------------------8<-----------------8<----------
0.9.2
- 'Vdu' onnly undefines a basic block. not the whole function!
- it does not unflags the address if loc.
- search for CALL instructions in text segment.
- analyze the destination address of each call destination
====[[ 0.9.4 ]]====
* Integrate dwarf parser with disassembler and debugger
* Analysis: assume there's a function at the end of each function

View File

@ -52,7 +52,7 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
bb->addr = addr;
len -= 16; // XXX: hack to avoid segfault by x86im
while (idx < len) {
if (!(op = r_anal_op_new ())) {
if (!(op = r_anal_op_new ())) { // TODO: too slow object construction
eprintf ("Error: new (op)\n");
return R_ANAL_RET_ERROR;
}

View File

@ -1,5 +1,4 @@
/* radare - LGPL - Copyright 2010-2012 */
/* nibble<.ds@gmail.com> + pancake<nopcode.org> */
/* radare - LGPL - Copyright 2010-2012 - nibble, pancake */
#include <r_anal.h>
#include <r_util.h>
@ -60,13 +59,11 @@ R_API void r_anal_fcn_free(void *_fcn) {
R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 addr, int type) {
RAnalRef *ref;
if (!fcn || !anal)
if (!fcn || !anal || !(ref = r_anal_ref_new ()))
return R_FALSE;
if (!(ref = r_anal_ref_new ()))
return R_FALSE;
ref->type = type;
ref->at = at;
ref->addr = addr;
ref->type = type;
// TODO: ensure we are not dupping xrefs
r_list_append (fcn->refs, ref);
return R_TRUE;
@ -93,10 +90,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
int oplen, idx = 0;
if (fcn->addr == -1)
fcn->addr = addr;
//fcn->size = 0;
fcn->type = (reftype==R_ANAL_REF_TYPE_CODE)?
R_ANAL_FCN_TYPE_LOC: R_ANAL_FCN_TYPE_FCN;
len -= 16; // XXX: hack to avoid buffer overflow by reading >64 bytes..
if (len>16)
len -= 16; // XXX: hack to avoid buffer overflow by reading >64 bytes..
while (idx < len) {
r_anal_op_fini (&op);
@ -106,7 +103,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
}
if ((oplen = r_anal_op (anal, &op, addr+idx, buf+idx, len-idx)) < 1) {
if (idx == 0) {
// eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
r_anal_op_fini (&op);
return R_ANAL_RET_END;
} else break;
@ -119,6 +116,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
case R_ANAL_STACK_INCSTACK:
fcn->stack += op.value;
break;
// TODO: use fcn->stack to know our stackframe
case R_ANAL_STACK_SET:
if (op.ref > 0) {
varname = r_str_dup_printf ("arg_%x", op.ref);
@ -131,6 +129,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
}
free (varname);
break;
// TODO: use fcn->stack to know our stackframe
case R_ANAL_STACK_GET:
if (op.ref > 0) {
varname = r_str_dup_printf ("arg_%x", op.ref);
@ -147,6 +146,11 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
switch (op.type) {
case R_ANAL_OP_TYPE_JMP:
case R_ANAL_OP_TYPE_CJMP:
#if 0
// do not add xrefs for cjmps?
r_anal_op_fini (&op);
break;
#endif
case R_ANAL_OP_TYPE_CALL:
if (!r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump,
op.type == R_ANAL_OP_TYPE_CALL?
@ -310,6 +314,7 @@ R_API int r_anal_fcn_split_bb(RAnalFunction *fcn, RAnalBlock *bb, ut64 addr) {
bb->jump = bbi->jump;
bb->fail = bbi->fail;
bb->conditional = bbi->conditional;
bbi->size = addr - bbi->addr;
bbi->jump = addr;
bbi->fail = -1;

View File

@ -44,7 +44,7 @@ R_API void r_anal_op_free(void *_op) {
}
R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
if (anal && op && anal->cur && anal->cur->op)
if (len>0 && anal && op && anal->cur && anal->cur->op)
return anal->cur->op (anal, op, addr, data, len);
return R_FALSE;
}

View File

@ -9,7 +9,7 @@
static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
unsigned int opcode;
char buf[10];
int reg, optype, oplen = (anal->bits==16)?2:4;
int family, reg, optype, oplen = (anal->bits==16)?2:4;
if (op == NULL)
return oplen;
@ -17,6 +17,7 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
memset (op, 0, sizeof (RAnalOp));
op->type = R_ANAL_OP_TYPE_UNK;
op->length = oplen;
op->delay = 4;
//r_mem_copyendian ((ut8*)&opcode, b, 4, !anal->big_endian);
memcpy (&opcode, b, 4);
@ -74,6 +75,8 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
op->type = R_ANAL_OP_TYPE_SWI;
break;
case 13: // break
op->type = R_ANAL_OP_TYPE_TRAP;
break;
case 16: // mfhi
case 18: // mflo
@ -85,14 +88,25 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
case 26: // div
case 27: // divu
op->type = R_ANAL_OP_TYPE_DIV;
break;
case 32: // add
case 33: // addu
op->type = R_ANAL_OP_TYPE_ADD;
break;
case 34: // sub
case 35: // subu
op->type = R_ANAL_OP_TYPE_SUB;
break;
case 36: // and
op->type = R_ANAL_OP_TYPE_AND;
break;
case 37: // or
op->type = R_ANAL_OP_TYPE_OR;
break;
case 38: // xor
op->type = R_ANAL_OP_TYPE_XOR;
break;
case 39: // nor
case 42: // slt
case 43: // sltu
@ -102,7 +116,7 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
// eprintf ("%llx %d\n", addr, optype);
break;
}
optype = 'R';
family = 'R';
} else
if ((optype & 0x3e) == 2) {
#if 0
@ -113,12 +127,18 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
(b[0]>>2) ((b[0]&3)<<24)+(b[1]<<16)+(b[2]<<8)+b[3]
#endif
int address = ((b[0]&3)<<24)+(b[1]<<16)+(b[2]<<8)+b[3];
optype = 'J';
switch (optype) {
case 2: // j
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = address;
break;
case 3: // jal
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = address;
op->fail = addr+8;
break;
}
family = 'J';
} else
if ((optype & 0x10) == 0x1c) {
#if 0
@ -139,7 +159,7 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
int fs = (b[2]>>3);
int fd = (b[2]&7)+(b[3]>>6);
int fun = (b[3]&63);
optype = 'C';
family = 'C';
switch (fun) {
case 0: // mtc1
break;
@ -172,13 +192,12 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
switch (optype) {
case 1: if (rt) { /* bgez */ } else { /* bltz */ }
case 4: // beq
case 5: // bne
case 5: // bne // also bnez
case 6: // blez
case 7: // bgtz
// XXX: use imm here
op->type = R_ANAL_OP_TYPE_JMP;
//reg = (((opcode&0x00ff0000)>>16) + ((opcode&0xff000000)>>24));
op->jump = addr+(imm<<2)+4; //(reg<<2) + 4;
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = addr+(imm<<2)+4;
op->fail = addr+8;
break;
case 8: // addi
@ -201,7 +220,7 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
case 57: // swc1
break;
}
optype = 'I';
family = 'I';
}
#if 0
@ -311,98 +330,6 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
mul.s fd, fs, ft 000010 10000
sub.s fd, fs, ft 000001 10000
#endif
//eprintf ("--> %x %02x %02x\n", opcode, opcode &0xff , opcode &0x3f);
switch (opcode & 0x3f) {
// J-Type
case 2: // j
// branch to register
//XXX TODO
op->type = R_ANAL_OP_TYPE_UJMP;
break;
// R-Type
case 1: // bltz
// 04100001 bltzal zero,0x2aaa8cb4
case 4: // beq // bal
case 5: // bne
case 6: // blez
case 7: // bgtz
case 16: //beqz
case 20: //bnel
op->type = R_ANAL_OP_TYPE_CJMP;
reg = (((opcode&0x00ff0000)>>16) + ((opcode&0xff000000)>>24));
op->jump = addr+(reg<<2) + 4;
op->fail = addr+8;
// calculate jump
break;
case 0x24: // jalx
case 0x34: // jalx
op->type = R_ANAL_OP_TYPE_UJMP;
break;
case 3: // jalr
op->type = R_ANAL_OP_TYPE_UCALL;
switch (opcode) {
case 0x03e00008:
case 0x0800e003: // jr ra
op->type = R_ANAL_OP_TYPE_RET;
break;
}
break;
case 9: // jalr
reg = opcode>>24;
if (reg<10) {
op->type = R_ANAL_OP_TYPE_UCALL;
snprintf (buf, sizeof (buf), "t%d", reg); // XXX must be rN...!regs* should be synced here
op->jump = 1234;//flag_get_addr(buf);
op->fail = addr+8;
}
break;
case 8: // jr
op->type = R_ANAL_OP_TYPE_RET;
break;
case 12:
op->type = R_ANAL_OP_TYPE_SWI;
break;
case 13:
op->type = R_ANAL_OP_TYPE_TRAP;
break;
default:
switch (opcode) {
case 0:
op->type = R_ANAL_OP_TYPE_NOP;
break;
case 32: // add
case 33: // addu
op->type = R_ANAL_OP_TYPE_ADD;
break;
case 34: // sub
case 35: // subu
op->type = R_ANAL_OP_TYPE_SUB;
break;
case 0x03e00008:
case 0x0800e003: // jr ra
op->type = R_ANAL_OP_TYPE_RET;
break;
case 0x0000000d: // case 26:
case 0x0d000000: // break
op->type = R_ANAL_OP_TYPE_TRAP;
break;
default:
//switch((opcode<<24)&0xff) { //b[3]) { // TODO handle endian ?
switch ((b[3])) {
case 0xc:
op->type = R_ANAL_OP_TYPE_SWI;
break;
case 0x9:
case 0x8:
op->type = R_ANAL_OP_TYPE_UJMP;
break;
case 0x21:
op->type = R_ANAL_OP_TYPE_PUSH; // XXX move
break;
}
}
}
return op->length;
}

View File

@ -95,7 +95,7 @@ static inline int r_asm_pseudo_int64(RAsm *a, RAsmOp *op, char *input) {
static inline int r_asm_pseudo_byte(RAsmOp *op, char *input) {
int i, len = 0;
r_str_subchr (input, ',', ' ');
r_str_replace_char (input, ',', ' ');
len = r_str_word_count (input);
r_str_word_set0 (input);
for (i=0; i<len; i++) {

View File

@ -85,6 +85,10 @@ static int disassemble(struct r_asm_t *a, struct r_asm_op_t *op, const ut8 *buf,
return op->inst_len;
}
static int assemble(RAsm *a, RAsmOp *op, const char *str) {
return mips_assemble (str, a->pc, op->buf);
}
RAsmPlugin r_asm_plugin_mips = {
.name = "mips",
.arch = "mips",
@ -93,7 +97,7 @@ RAsmPlugin r_asm_plugin_mips = {
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,
.assemble = NULL,
.assemble = &assemble,
};
#ifndef CORELIB

View File

@ -3,6 +3,7 @@ OBJ_MIPS=asm_mips.o
OBJ_MIPS+=../arch/mips/gnu/mips-dis.o
OBJ_MIPS+=../arch/mips/gnu/mips16-opc.o
OBJ_MIPS+=../arch/mips/gnu/mips-opc.o
OBJ_MIPS+=../arch/mips/mipsasm.o
TARGET_MIPS=asm_mips.${EXT_SO}
ALL_TARGETS+=${TARGET_MIPS}

View File

@ -125,12 +125,21 @@ R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head) {
if (ret == R_ANAL_RET_DUP) { /* Dupped bb */
goto error;
} else if (ret == R_ANAL_RET_NEW) { /* New bb */
// XXX: use static buffer size of 512 or so
if (!(buf = malloc (core->blocksize)))
goto error;
do {
if ((buflen = r_io_read_at (core->io, at+bblen, buf, core->blocksize)) != core->blocksize)
#if 1
// check io error
if (r_io_read_at (core->io, at+bblen, buf, 4) != 4)
//core->blocksize)) != core->blocksize)
goto error;
#endif
r_core_read_at (core, at+bblen, buf, core->blocksize);
buflen = core->blocksize;
//eprintf ("Pre %llx %d\n", at, buflen);
bblen = r_anal_bb (core->anal, bb, at+bblen, buf, buflen, head);
//eprintf ("Pos %d\n", bblen);
if (bblen == R_ANAL_RET_ERROR ||
(bblen == R_ANAL_RET_END && bb->size < 1)) { /* Error analyzing bb */
goto error;
@ -150,13 +159,13 @@ R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head) {
} while (bblen != R_ANAL_RET_END);
}
free(buf);
free (buf);
return R_TRUE;
error:
r_list_unlink(fcn->bbs, bb);
r_anal_bb_free(bb);
free(buf);
r_list_unlink (fcn->bbs, bb);
r_anal_bb_free (bb);
free (buf);
return R_FALSE;
}
@ -182,8 +191,15 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
int buflen, fcnlen = 0;
RAnalFunction *fcn = NULL, *fcni;
RAnalRef *ref = NULL, *refi;
ut64 *next = NULL;
int i, nexti = 0;
ut8 *buf;
#define ANALBS 256
if (at>>63 == 1)
return R_FALSE;
if (at == UT64_MAX)
return R_FALSE;
if (depth < 0)
return R_FALSE;
#warning This must be optimized to use the fcnstore api
@ -211,14 +227,25 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
eprintf ("Error: new (fcn)\n");
return R_FALSE;
}
if (!(buf = malloc (core->blocksize))) {
if (!(buf = malloc (ANALBS))) { //core->blocksize))) {
eprintf ("Error: malloc (buf)\n");
goto error;
}
#define MAXNEXT 1032 // TODO: make it relocatable
if (r_config_get_i (core->config, "anal.hasnext")) {
next = R_NEWS0 (ut64, MAXNEXT);
}
//eprintf ("FUNC 0x%08"PFMT64x"\n", at+fcnlen);
do {
if ((buflen = r_io_read_at (core->io, at+fcnlen, buf, core->blocksize)) != core->blocksize)
// check io error
if ((buflen = r_io_read_at (core->io, at+fcnlen, buf, 4) != 4))
goto error;
// real read.
if (!r_core_read_at (core, at+fcnlen, buf, ANALBS))
goto error;
buflen = ANALBS;
if (r_cons_singleton ()->breaked)
break;
fcnlen = r_anal_fcn (core->anal, fcn, at+fcnlen, buf, buflen, reftype);
@ -246,6 +273,7 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
eprintf ("fun depth fail for 0x%08"PFMT64x"\n", fcn->addr);
} else fcn->depth = 256-fcn->depth;
r_list_sort (fcn->bbs, &cmpaddr);
/* New function: Add initial xref */
if (from != -1) {
if (!(ref = r_anal_ref_new ())) {
@ -259,6 +287,21 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
}
// XXX: this looks weird
r_anal_fcn_insert (core->anal, fcn);
#if 1
if (next && nexti<MAXNEXT) {
int i;
ut64 addr = fcn->addr + fcn->size;
for (i=0;i<nexti;i++)
if (next[i] == addr)
break;
if (i==nexti) {
// TODO: ensure next address is function after padding (nop or trap or wat)
eprintf ("FUNC 0x%08"PFMT64x" > 0x%08"PFMT64x"\r",
fcn->addr, fcn->addr + fcn->size);
next[nexti++] = fcn->addr + fcn->size;
}
}
#endif
//r_list_append (core->anal->fcns, fcn);
r_list_foreach (fcn->refs, iter, refi)
if (refi->addr != -1)
@ -268,18 +311,29 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
}
} while (fcnlen != R_ANAL_RET_END);
free (buf);
if (next) {
for (i=0; i<nexti; i++) {
if (!next[i]) continue;
r_core_anal_fcn (core, next[i], from, 0, depth-1);
}
free (next);
}
return R_TRUE;
error:
free (buf);
// ugly hack to free fcn
if (fcn) {
if (fcn->addr == UT64_MAX) {
if (fcn->size == 0 || fcn->addr == UT64_MAX) {
r_anal_fcn_free (fcn);
return R_FALSE;
}
// TODO: mark this function as not properly analyzed
eprintf ("Analysis of function at 0x%08"PFMT64x" has failed\n", fcn->addr);
eprintf ("Analysis of function 0x%08"PFMT64x
" has failed at 0x%08"PFMT64x"\n",
fcn->addr, fcn->addr+fcn->size);
if (!fcn->name) {
// XXX dupped code.
fcn->name = r_str_dup_printf ("%s.%08"PFMT64x,
@ -298,6 +352,15 @@ error:
r_anal_fcn_free (fcn);
#endif
}
if (next) {
if (nexti<MAXNEXT)
next[nexti++] = fcn->addr + fcn->size;
for (i=0; i<nexti; i++) {
if (!next[i]) continue;
r_core_anal_fcn (core, next[i], next[i], 0, depth-1);
}
free(next);
}
return R_FALSE;
}
@ -693,7 +756,7 @@ R_API int r_core_anal_all(RCore *core) {
r_list_foreach (list, iter, symbol) {
if (core->cons->breaked)
break;
if (!strncmp (symbol->type,"FUNC", 4))
if (!strncmp (symbol->type, "FUNC", 4))
r_core_anal_fcn (core, offset + va?baddr+symbol->rva:symbol->offset, -1,
R_ANAL_REF_TYPE_NULL, depth);
}

View File

@ -318,7 +318,7 @@ static int cmd_eval(void *data, const char *input) {
char *p;
const char *val = r_config_get (core->config, input+2);
p = r_core_editor (core, val);
r_str_subchr (p, '\n', ';');
r_str_replace_char (p, '\n', ';');
r_config_set (core->config, input+2, p);
} else eprintf ("Usage: ee varname\n");
break;

View File

@ -203,6 +203,8 @@ static int cmd_anal(void *data, const char *input) {
ut32 tbs = core->blocksize;
#if 1
switch (input[0]) {
case 'o':
if (input[0] && input[1]) {
l = (int) r_num_get (core->num, input+2);
if (l>0) len = l;
@ -211,6 +213,7 @@ static int cmd_anal(void *data, const char *input) {
len = l;
}
} else len = l = core->blocksize;
}
#endif
r_cons_break (NULL, NULL);

View File

@ -59,13 +59,19 @@ R_API int r_core_search_preludes(RCore *core) {
ret = r_core_search_prelude (core, from, to, kw, kwlen, NULL, 0);
free (kw);
} else
if (strstr (arch, "mips")) {
ret = r_core_search_prelude (core, from, to,
(const ut8 *)"\x27\xbd\x00", 3, NULL, 0);
} else
if (strstr (arch, "x86")) {
switch (bits) {
case 32:
ret = r_core_search_prelude (core, from, to, (const ut8 *)"\x55\x89\xe5", 3, NULL, 0);
ret = r_core_search_prelude (core, from, to,
(const ut8 *)"\x55\x89\xe5", 3, NULL, 0);
break;
case 64:
ret = r_core_search_prelude (core, from, to, (const ut8 *)"\x55\x48\x89\xe5", 3, NULL, 0);
ret = r_core_search_prelude (core, from, to,
(const ut8 *)"\x55\x48\x89\xe5", 3, NULL, 0);
//r_core_cmd0 (core, "./x 554989e5");
break;
default:

View File

@ -354,6 +354,12 @@ static int config_asmarch_callback(void *user, void *data) {
r_egg_setup (core->egg, node->value, core->anal->bits, 0, R_SYS_OS);
if (!r_asm_use (core->assembler, node->value))
eprintf ("asm.arch: cannot find (%s)\n", node->value);
{
char asmparser[32];
snprintf (asmparser, sizeof (asmparser), "%s.pseudo", node->value);
r_config_set (core->config, "asm.parser", asmparser);
}
if (!r_config_set (core->config, "anal.plugin", node->value)) {
char *p, *s = strdup (node->value);
p = strchr (s, '.');
@ -375,9 +381,9 @@ static int config_asmparser_callback(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
// XXX this is wrong? snprintf(buf, 127, "parse_%s", node->value),
r_parse_use (core->parser, node->value);
return r_parse_use (core->parser, node->value);
// TODO: control error and restore old value (return false?) show errormsg?
return R_TRUE;
//return R_TRUE;
}
static int config_asmbits_callback(void *user, void *data) {
@ -449,6 +455,8 @@ R_API int r_core_config_init(RCore *core) {
/* anal */
r_config_set (cfg, "anal.prelude", "");
r_config_desc (cfg, "anal.prelude", "Specify an hexpair to find preludes in code");
r_config_set (cfg, "anal.hasnext", "true");
r_config_desc (cfg, "anal.hasnext", "Continue analysis after each function");
r_config_set_i (cfg, "anal.depth", 50); // XXX: warn if depth is > 50 .. can be problematic
r_config_desc (cfg, "anal.depth", "Max depth at code analysis");
r_config_set_i (cfg, "anal.ptrdepth", 3);

View File

@ -534,8 +534,8 @@ R_API int r_core_block_size(RCore *core, int bsize) {
if (bsize<1)
bsize = 1;
else if (bsize>core->blocksize_max) {
eprintf ("blocksize is bigger than io.maxblk. dimmed to 0x%x\n",
core->blocksize_max);
eprintf ("blocksize is bigger than io.maxblk. dimmed to 0x%x > 0x%x\n",
bsize, core->blocksize_max);
bsize = core->blocksize_max;
} else ret = R_TRUE;
core->block = realloc (core->block, bsize+1);

View File

@ -179,5 +179,5 @@ R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
if (addr>=core->offset && addr<=core->offset+core->blocksize)
r_core_block_read (core, 0);
#endif
return (ret!=UT64_MAX);
return (ret==size); //UT64_MAX);
}

View File

@ -778,7 +778,7 @@ R_API void r_core_visual_title (RCore *core, int color) {
break;
case 1: // pd
case 2: // pd+dbg
r_core_block_size (core, core->cons->rows *4); // this is hacky
r_core_block_size (core, core->cons->rows *5); // this is hacky
break;
}

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
/* radare - LGPL - Copyright 2009-2012 - pancake, nibble */
#ifndef _INCLUDE_R_PARSE_H_
#define _INCLUDE_R_PARSE_H_
@ -45,6 +45,7 @@ R_API int r_parse_varsub(RParse *p, RAnalFunction *f, char *data, char *str, int
extern struct r_parse_plugin_t r_parse_plugin_dummy;
extern struct r_parse_plugin_t r_parse_plugin_att2intel;
extern struct r_parse_plugin_t r_parse_plugin_x86_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_mips_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_mreplace;
#endif

View File

@ -92,6 +92,7 @@ typedef void (*PrintfCallback)(const char *str, ...);
#define BITS2BYTES(x) ((x/8)+((x%8)?1:0))
#define ZERO_FILL(x) memset (x, 0, sizeof (x))
#define R_NEWS0(x,y) (x*)memset (malloc(sizeof(x)*y), 0, sizeof(x)*y);
#define R_NEWS(x,y) (x*)malloc(sizeof(x)*y)
#define R_NEW(x) (x*)malloc(sizeof(x))
#define R_NEW0(x) (x*)calloc(1,sizeof(x))

View File

@ -356,7 +356,7 @@ R_API char* r_str_replace(char *str, const char *key, const char *val, int g);
R_API void r_str_cpy(char *dst, const char *src);
R_API int r_str_bits (char *strout, const ut8 *buf, int len, const char *bitz);
R_API int r_str_rwx(const char *str);
R_API void r_str_subchr (char *s, int a, int b);
R_API void r_str_replace_char (char *s, int a, int b);
R_API const char *r_str_rwx_i(int rwx);
R_API void r_str_writef(int fd, const char *fmt, ...);
R_API char **r_str_argv(const char *str, int *_argc);

View File

@ -0,0 +1,8 @@
OBJ_MIPSPSEUDO+=parse_mips_pseudo.o
TARGET_MIPSPSEUDO=parse_mips_pseudo.${EXT_SO}
ALL_TARGETS+=${TARGET_MIPSPSEUDO}
STATIC_OBJ+=${OBJ_MIPSPSEUDO}
${TARGET_MIPSPSEUDO}: ${OBJ_MIPSPSEUDO}
${CC} $(call libname,parse_mips_pseudo) -L../../util -lr_util -shared ${CFLAGS} -o ${TARGET_MIPSPSEUDO} ${OBJ_MIPSPSEUDO}

View File

@ -91,11 +91,11 @@ static int parse(RParse *p, const char *data, char *str) {
strcpy (str, data);
return R_TRUE;
}
r_str_subchr (buf, '$', 0);
r_str_subchr (buf, '%', 0);
r_str_subchr (buf, '\t', ' ');
r_str_subchr (buf, '(', '[');
r_str_subchr (buf, ')', ']');
r_str_replace_char (buf, '$', 0);
r_str_replace_char (buf, '%', 0);
r_str_replace_char (buf, '\t', ' ');
r_str_replace_char (buf, '(', '[');
r_str_replace_char (buf, ')', ']');
ptr = strchr (buf, '[');
if (ptr) {
int n;

View File

@ -0,0 +1,263 @@
/* radare - LGPL - Copyright 2012 - pancake */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <r_lib.h>
#include <r_util.h>
#include <r_flags.h>
#include <r_anal.h>
#include <r_parse.h>
static int replace(int argc, const char *argv[], char *newstr) {
int i,j,k;
struct {
char *op;
char *str;
} ops[] = {
{ "li", "1 = 2"},
{ "lui", "1 = 2"},
{ "jr", "ret 1"},
{ "bne", "if (1 != 2) goto 3"},
{ "beq", "if (1 == 2) goto 3"},
{ "beqz", "if (!1) goto 2"},
{ "bnez", "if (1) goto 2"},
{ "begz", "if (1 >= 0) goto 2"},
{ "begzal", "if (1 >= 0) call 2"},
{ "bgtz", "if (1 > 0) goto 2"},
{ "bltz", "if (1 < 0) goto 2"},
{ "bltzal", "if (1 < 0) call 2"},
{ "negu", "1 = !2"},
{ "and", "1 = 2 & 3"},
{ "andi", "1 = 2 & 3"},
{ "ori", "1 = 2 | 3"},
{ "subu", "1 = 2 - 3"},
{ "xor", "1 = 2 ^ 3"},
{ "xori", "1 = 2 ^ 3"},
{ "addi", "1 = 2 + 3"},
{ "addiu", "1 = 2 + 3"},
{ "addu", "1 = 2 + 3"},
//{ "jal", "call 1"},
{ "bal", "call 1"},
{ "jalr", "call 1"},
{ "b", "goto 1"},
{ "move", "1 = 2"},
{ "sll", "1 = 2 << 3"},
{ "sllv", "1 = 2 << 3"},
{ "slr", "1 = 2 >> 3"}, // logic
{ "sra", "1 = 2 >> 3"}, // arithmetic
{ "slt", "1 = (2 < 3)"},
{ "slti", "1 = (2 < 3)"},
{ "sltiu", "1 = (2 < 3)"},
{ "sltu", "1 = unsigned (2 < 3)"},
{ "lb", "1 = byte [3 + 2]"},
{ "lw", "1 = [3 + 2]"},
{ "sb", "byte [3 + 2] = 1"},
{ "lbu", "1 = byte [3 + 2]"},
{ "sw", "[3 + 2] = 1"},
{ NULL }
};
for (i=0; ops[i].op != NULL; i++) {
if (!strcmp (ops[i].op, argv[0])) {
if (newstr != NULL) {
for (j=k=0;ops[i].str[j]!='\0';j++,k++) {
if (ops[i].str[j]>='1' && ops[i].str[j]<='9') {
const char *w = argv[ ops[i].str[j]-'0' ];
if (w != NULL) {
strcpy (newstr+k, w);
k += strlen(w)-1;
}
} else newstr[k] = ops[i].str[j];
}
newstr[k]='\0';
}
return R_TRUE;
}
}
/* TODO: this is slow */
if (newstr != NULL) {
newstr[0] = '\0';
for (i=0; i<argc; i++) {
strcat (newstr, argv[i]);
strcat (newstr, (i == 0 || i== argc - 1)?" ":", ");
}
}
return R_FALSE;
}
static int parse(RParse *p, const char *data, char *str) {
int i, len = strlen (data);
char w0[32];
char w1[32];
char w2[32];
char w3[32];
char w4[32];
char *buf, *ptr, *optr;
// malloc can be slow here :?
if ((buf = malloc (len+1)) == NULL)
return R_FALSE;
memcpy (buf, data, len+1);
if (!strcmp (data, "jr ra")) {
strcpy (str, "ret");
return R_TRUE;
}
r_str_replace_char (buf, '(', ',');
r_str_replace_char (buf, ')', ' ');
r_str_chop (buf);
if (*buf) {
w0[0]='\0';
w1[0]='\0';
w2[0]='\0';
w3[0]='\0';
w4[0]='\0';
ptr = strchr (buf, ' ');
if (ptr == NULL)
ptr = strchr (buf, '\t');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr==' '; ptr++);
strcpy (w0, buf);
strcpy (w1, ptr);
optr=ptr;
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr==' '; ptr++);
strcpy (w1, optr);
strcpy (w2, ptr);
optr=ptr;
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr==' '; ptr++);
strcpy (w2, optr);
strcpy (w3, ptr);
optr=ptr;
// bonus
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr==' '; ptr++);
strcpy (w3, optr);
strcpy (w4, ptr);
}
}
}
}
{
const char *wa[] = { w0, w1, w2, w3, w4 };
int nw = 0;
for (i=0; i<4; i++) {
if (wa[i][0] != '\0')
nw++;
}
replace (nw, wa, str);
{
char *p = strdup (str);
p = r_str_replace (p, "+ -", "- ", 0);
#if EXPERIMENTAL_ZERO
p = r_str_replace (p, "zero", "0", 0);
if (!memcmp (p, "0 = ", 4)) *p = 0; // nop
#endif
if (!strcmp (w1, w2)) {
char a[32], b[32];
#define REPLACE(x,y) \
sprintf (a, x, w1, w1); \
sprintf (b, y, w1); \
p = r_str_replace (p, a, b, 0);
// TODO: optimize
REPLACE ("%s = %s +", "%s +=");
REPLACE ("%s = %s -", "%s -=");
REPLACE ("%s = %s &", "%s &=");
REPLACE ("%s = %s |", "%s |=");
REPLACE ("%s = %s ^", "%s ^=");
REPLACE ("%s = %s >>", "%s >>=");
REPLACE ("%s = %s <<", "%s <<=");
}
strcpy (str, p);
free (p);
}
}
}
free (buf);
return R_TRUE;
}
static int assemble(RParse *p, char *data, char *str) {
char *ptr;
printf ("assembling '%s' to generate real asm code\n", str);
ptr = strchr (str, '=');
if (ptr) {
*ptr = '\0';
sprintf (data, "mov %s, %s", str, ptr+1);
} else strcpy (data, str);
return R_TRUE;
}
static int filter(RParse *p, RFlag *f, char *data, char *str, int len) {
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;
continue;
}
r_list_foreach (f->flags, iter, flag) {
if (flag->offset == off && strchr (flag->name, '.')) {
*ptr = 0;
snprintf (str, len, "%s%s%s", data, flag->name, ptr2!=ptr? ptr2: "");
return R_TRUE;
}
}
ptr = ptr2;
}
strncpy (str, data, len);
return R_FALSE;
}
static int varsub(RParse *p, RAnalFunction *f, char *data, char *str, int len) {
char *ptr, *ptr2;
int i;
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' &&
(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);
}
return R_TRUE;
}
struct r_parse_plugin_t r_parse_plugin_mips_pseudo = {
.name = "mips.pseudo",
.desc = "MIPS pseudo syntax",
.init = NULL,
.fini = NULL,
.parse = parse,
.assemble = &assemble,
.filter = &filter,
.varsub = &varsub,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_PARSE,
.data = &r_parse_plugin_mips_pseudo
};
#endif

View File

@ -101,6 +101,7 @@ static int parse(RParse *p, const char *data, char *str) {
for (++ptr; *ptr==' '; ptr++);
strcpy (w1, optr);
strcpy (w2, ptr);
optr=ptr;
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';

View File

@ -69,7 +69,7 @@ main () {
}
#endif
R_API void r_str_subchr (char *s, int a, int b) {
R_API void r_str_replace_char (char *s, int a, int b) {
char *o = s;
for (; *o; s++, o++) {
if (*o==a) {

View File

@ -22,9 +22,9 @@ R_API int r_vm_op_eval(struct r_vm_t *vm, const char *str) {
s = alloca(len);
memcpy (p, str, len);
memcpy (s, str, len);
r_str_subchr (s, ',', 0);
r_str_subchr (s, '\t', 0);
r_str_subchr (s, '#', 0);
r_str_replace_char (s, ',', 0);
r_str_replace_char (s, '\t', 0);
r_str_replace_char (s, '#', 0);
nargs = r_str_word_set0(s);
arg0 = r_str_word_get0(s, 0);

View File

@ -99,6 +99,7 @@ io.procpid
io.shm
parse.mreplace
parse.att2intel
parse.mips_pseudo
parse.x86_pseudo"
SHARED="
asm.csr