Finally fix the brainfuck emulator

This commit is contained in:
pancake 2014-10-03 20:05:33 +02:00
parent b25af56871
commit a58789782d
6 changed files with 73 additions and 23 deletions

View File

@ -11,7 +11,6 @@ static int countChar (const ut8 *buf, int len, char ch) {
for (i=0; i<len; i++) {
if (buf[i] != ch)
break;
}
return i;
}
@ -40,13 +39,13 @@ static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
dst ++;
op->jump = dst;
r_strbuf_setf (&op->esil,
"pc,brk,=[1],brk,++=,"
"ptr,[1],!,?{,0x%"PFMT64x",pc,=,}", dst);
"pc,brk,=[1],brk,++=,"
"ptr,[1],!,?{,0x%"PFMT64x",pc,=,brk,--=,}", dst);
break;
}
}
p++;
i++;
i++;
}
}
// ?1[ptr],pc=${NEW_PC
@ -55,11 +54,15 @@ static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
// XXX This is wrong esil
r_strbuf_set (&op->esil, "brk,--=,brk,[1],pc,=");
break;
case '>': op->type = R_ANAL_OP_TYPE_ADD;
r_strbuf_set (&op->esil, "ptr,++=");
case '>':
op->type = R_ANAL_OP_TYPE_ADD;
op->size = countChar (buf, len, '>');
r_strbuf_setf (&op->esil, "%d,ptr,+=", op->size);
break;
case '<': op->type = R_ANAL_OP_TYPE_SUB;
r_strbuf_set (&op->esil, "ptr,--=");
case '<':
op->type = R_ANAL_OP_TYPE_SUB;
op->size = countChar (buf, len, '<');
r_strbuf_setf (&op->esil, "%d,ptr,-=", op->size);
break;
case '+':
op->size = countChar (buf, len, '+');
@ -114,7 +117,7 @@ struct r_anal_plugin_t r_anal_plugin_bf = {
.desc = "brainfuck code analysis plugin",
.license = "LGPL3",
.arch = R_SYS_ARCH_BF,
.bits = 32,
.bits = 8,
.init = NULL,
.fini = NULL,
.esil = R_TRUE,

View File

@ -1031,10 +1031,13 @@ static int esil_poke1(RAnalEsil *esil) {
int ret = 0;
ut64 num, addr;
ut8 num1;
eprintf ("POKE ONE!\n");
char *dst = r_anal_esil_pop (esil);
char *src = r_anal_esil_pop (esil);
if (src && r_anal_esil_get_parm (esil, src, &num)) {
eprintf ("POKE TWO!\n");
if (dst && r_anal_esil_get_parm (esil, dst, &addr)) {
eprintf ("PIKA THREE!\n");
if (r_anal_esil_get_parm_type (esil, src) != R_ANAL_ESIL_PARM_INTERNAL) {
esil_mem_read (esil, addr, &num1, 1);
esil->old = num1;
@ -2194,16 +2197,34 @@ static int runword (RAnalEsil *esil, const char *word) {
esil->parse_stop = 1; // INTERNAL ERROR
return 0;
}
#if NEWSHIT
// seems wrong :D
if (esil->skip) {
if (!strcmp (word, "}"))
if (!strcmp (word, "}{")) {
esil->skip = 0;
return 0;
return 1;
} else if (!strcmp (word, "}")) {
esil->skip = 0;
return 1;
}
} else {
if (!strcmp (word, "}{")) {
esil->skip = 1;
return 0;
return 1;
}
}
#else
if (esil->skip) {
if (!strcmp (word, "}"))
esil->skip = 0;
return 0;
} else {
if (!strcmp (word, "}{")) {
esil->skip = 1;
return 0;
}
}
#endif
if (iscommand (esil, word, &op)) {
// run action
if (op) {
@ -2320,7 +2341,6 @@ repeat:
case 2: goto repeat;
}
}
return 1;
}

View File

@ -68,11 +68,12 @@ eprintf ("f stack 0x200 0x5000\n");
eprintf ("o malloc://0x200 0x5000\n");
eprintf ("f data 0x1000 0x6000\n");
eprintf ("o malloc://0x1000 0x6000\n");
eprintf ("ar\n"); // init?
eprintf ("ar\n"); // hack to init
eprintf ("ar brk=stack\n");
eprintf ("ar scr=screen\n");
eprintf ("ar kbd=input\n");
eprintf ("ar ptr=data\n");
eprintf ("\"e cmd.vprompt=pxa 32@stack;pxa 32@screen;pxa 32@data\"\n");
eprintf ("s 0\n");
return ret;
}

View File

@ -922,7 +922,7 @@ void cmd_anal_reg(RCore *core, const char *str) {
static void esil_step(RCore *core, ut64 until_addr, const char *until_expr) {
// Stepping
int ret;
ut8 code[32];
ut8 code[256];
RAnalOp op;
const char *name = r_reg_get_name (core->anal->reg, r_reg_get_name_idx ("pc"));
ut64 addr = r_reg_getv (core->anal->reg, name);
@ -957,21 +957,35 @@ static void esil_step(RCore *core, ut64 until_addr, const char *until_expr) {
addr = r_reg_getv (core->anal->reg, name);
//eprintf ("PC=0x%llx\n", (ut64)addr);
}
r_io_read_at (core->io, addr, code, 32);
r_io_read_at (core->io, addr, code, sizeof (code));
r_asm_set_pc (core->assembler, addr);
ret = r_anal_op (core->anal, &op, addr, code, 32);
eprintf ("EMULATE %s\n", R_STRBUF_SAFEGET (&op.esil));
ret = r_anal_op (core->anal, &op, addr, code, sizeof (code));
#if 0
eprintf ("RET %d\n", ret);
eprintf ("ADDR 0x%llx\n", addr);
eprintf ("DATA %x %x %x %x\n", code[0], code[1], code[2], code[3]);
eprintf ("ESIL %s\n", op.esil);
eprintf ("EMULATE %s\n", R_STRBUF_SAFEGET (&op.esil));
sleep (1);
#endif
if (ret) {
//r_anal_esil_eval (core->anal, input+2);
RAnalEsil *esil = core->anal->esil;
r_anal_esil_set_offset (esil, addr);
r_anal_esil_parse (esil, R_STRBUF_SAFEGET (&op.esil));
if (core->anal->cur && core->anal->cur->esil_post_loop)
core->anal->cur->esil_post_loop(esil, &op);
core->anal->cur->esil_post_loop (esil, &op);
r_anal_esil_dumpstack (esil);
r_anal_esil_stack_free (esil);
}
}
ut64 newaddr = r_reg_getv (core->anal->reg, name);
ut64 follow = r_config_get_i (core->config, "dbg.follow");
if (follow>0) {
ut64 pc = r_debug_reg_get (core->dbg, "pc");
if ((pc<core->offset) || (pc > (core->offset+follow)))
r_core_cmd0 (core, "sr pc");
}
if (addr == newaddr) {
if (op.size<1)
op.size = 1; // avoid inverted stepping

View File

@ -838,6 +838,7 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("dir.types", "/usr/include", "Default path to look for cparse type files");
SETPREF("dir.projects", "~/"R2_HOMEDIR"/projects", "Default path for projects");
SETPREF("stack.bytes", "false", "Show bytes instead of values in stack");
SETPREF("stack.anotated", "false", "Show anotated hexdump in visual debug");
SETI("stack.size", 64, "Define size of anotated hexdump in visual debug");
SETI("stack.delta", 0, "Define a delta for the stack dump");

View File

@ -1452,18 +1452,29 @@ R_API int r_core_visual(RCore *core, const char *input) {
static char debugstr[512];
const char *cmdvhex = r_config_get (core->config, "cmd.stack");
const int pxa = r_config_get_i (core->config, "stack.anotated"); // stack.anotated
const int size = r_config_get_i (core->config, "stack.size"); // stack.size
const int delta = r_config_get_i (core->config, "stack.delta"); // stack.delta
const int size = r_config_get_i (core->config, "stack.size");
const int delta = r_config_get_i (core->config, "stack.delta");
const int bytes = r_config_get_i (core->config, "stack.bytes");
if (cmdvhex && *cmdvhex) {
snprintf (debugstr, sizeof(debugstr),
"f tmp;sr sp;%s;dr=;s-;"
"s tmp;f-tmp;pd $r", cmdvhex);
debugstr[sizeof(debugstr)-1]=0;
} else {
const char *pxw;
if (bytes) {
pxw = "px";
} else {
switch (core->assembler->bits) {
case 64: pxw = "pxq"; break;
case 32: pxw = "pxw"; break;
default: pxw = "px"; break;
}
}
snprintf (debugstr, sizeof(debugstr),
"f tmp;sr sp;%s %d@$$-%d;dr=;s-;"
"s tmp;f-tmp;pd $r",
pxa?"pxa":"pxw", size,
pxa?"pxa":pxw, size,
delta);
}
printfmt[2] = debugstr;