mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-01 17:40:34 +00:00
Finally fix the brainfuck emulator
This commit is contained in:
parent
b25af56871
commit
a58789782d
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user