bf: allow loops of any size

* bf: allow loops of any size
* Consider unbalanced '[' insn as trap insn
* Using callback instead of directly linking to resize_read_buf func
This commit is contained in:
Khairul Azhar Kasmiran 2018-02-19 21:27:05 +08:00 committed by radare
parent e3b9ae9113
commit d356d16a8e
3 changed files with 36 additions and 2 deletions

View File

@ -21,6 +21,7 @@ static int getid (char ch) {
return cidx? cidx - keys + 1: 0;
}
#define BUFSIZE_INC 32
static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
ut64 dst = 0LL;
if (!op) {
@ -33,6 +34,10 @@ static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
op->id = getid (buf[0]);
switch (buf[0]) {
case '[':
buf = (const ut8 *)strdup ((char *)buf);
if (!buf) {
break;
}
op->type = R_ANAL_OP_TYPE_CJMP;
op->fail = addr+1;
{
@ -51,13 +56,28 @@ static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
r_strbuf_setf (&op->esil,
"$$,brk,=[1],brk,++=,"
"ptr,[1],!,?{,0x%"PFMT64x",pc,=,brk,--=,}", dst);
break;
goto beach;
}
}
if (*p == 0x00 || *p == 0xff) {
op->type = R_ANAL_OP_TYPE_TRAP;
goto beach;
}
if (i == len - 1 && anal->esil->cb.resize_read_buf) {
const ut8 *new_buf = anal->esil->cb.resize_read_buf (anal, len + 1 + BUFSIZE_INC);
if (new_buf) {
free ((ut8 *)buf);
buf = new_buf;
p = buf + i;
len += BUFSIZE_INC;
}
}
p++;
i++;
}
}
beach:
free ((ut8 *)buf);
break;
case ']': op->type = R_ANAL_OP_TYPE_UJMP;
// XXX This is wrong esil

View File

@ -3089,11 +3089,23 @@ static ut64 initializeEsil(RCore *core) {
return addr;
}
static const ut8 *resize_read_buf(RAnal *anal, int new_len) {
RCore *core = anal->user;
ut8 *buf = calloc (new_len, 1);
if (!buf) {
return NULL;
}
const char *name = r_reg_get_name (anal->reg, R_REG_NAME_PC);
ut64 addr = r_reg_getv (anal->reg, name);
(void)r_io_read_at (core->io, addr, buf, new_len);
return buf;
}
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr) {
#define return_tail(x) { tail_return_value = x; goto tail_return; }
int tail_return_value = 0;
int ret;
ut8 code[48];
ut8 code[32];
RAnalOp op = {0};
RAnalEsil *esil = core->anal->esil;
const char *name = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
@ -3110,6 +3122,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
return 0;
}
r_anal_esil_setup (esil, core->anal, romem, stats, noNULL); // setup io
esil->cb.resize_read_buf = resize_read_buf;
core->anal->esil = esil;
esil->verbose = verbose;
{

View File

@ -1015,6 +1015,7 @@ typedef struct r_anal_esil_callbacks_t {
int (*reg_read)(ESIL *esil, const char *name, ut64 *res, int *size);
RAnalEsilHookRegWriteCB hook_reg_write;
int (*reg_write)(ESIL *esil, const char *name, ut64 val);
const ut8 *(*resize_read_buf)(RAnal *anal, int new_len);
} RAnalEsilCallbacks;
typedef struct r_anal_esil_t {