Add bin.bf for brainfuck and use static ESIL struct

This commit is contained in:
pancake 2013-12-10 03:35:59 +01:00
parent 26807eec4d
commit c165361124
17 changed files with 208 additions and 70 deletions

View File

@ -180,3 +180,6 @@ License server overloaded (ETOOMANYCASH)
error: cannot yank negative sleep
If you're not satisfied by our product, we'll be happy to refund you.
Already up-to-date
How about a nice game of chess?
THE ONLY WINNING MOVE IS NOT TO PLAY.
SHALL WE PLAY A GAME?

View File

@ -14,10 +14,7 @@ R_API RAnalOp *r_anal_op_new() {
op->fail = -1;
op->ptr = -1;
op->val = -1;
if ((op->esil = r_strbuf_new ()) == NULL) {
r_anal_op_free (op);
return NULL;
}
r_strbuf_init (&op->esil);
op->next = NULL;
}
return op;
@ -34,8 +31,6 @@ R_API void r_anal_op_fini(RAnalOp *op) {
r_anal_value_free (op->src[1]);
r_anal_value_free (op->src[2]);
r_anal_value_free (op->dst);
if (op->esil != NULL)
r_strbuf_free (op->esil);
op->src[0] = NULL;
op->src[1] = NULL;
op->src[2] = NULL;
@ -70,11 +65,8 @@ R_API RAnalOp *r_anal_op_copy (RAnalOp *op) {
nop->src[1] = r_anal_value_copy (op->src[1]);
nop->src[2] = r_anal_value_copy (op->src[2]);
nop->dst = r_anal_value_copy (op->dst);
if ((nop->esil = r_strbuf_new ()) == NULL) {
r_anal_op_free (nop);
return NULL;
}
r_strbuf_set (nop->esil, r_strbuf_get (op->esil));
r_strbuf_init (&nop->esil);
r_strbuf_set (&nop->esil, r_strbuf_get (&op->esil));
return nop;
}
@ -185,7 +177,7 @@ R_API char *r_anal_optype_to_string(int t) {
}
R_API const char *r_anal_op_to_esil_string(RAnal *anal, RAnalOp *op) {
return op->esil;
return r_strbuf_get (&op->esil);
}
// TODO: use esil here?

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2011 - pancake<nopcode.org> */
/* radare2 - LGPL - Copyright 2011-2013 - pancake */
#include <string.h>
#include <r_types.h>
@ -7,31 +7,53 @@
#include <r_anal.h>
static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
ut64 dst = 0LL;
if (op == NULL)
return 1;
/* Ayeeee! What's inside op? Do we have an initialized RAnalOp? Are we going to have a leak here? :-( */
memset (op, 0, sizeof (RAnalOp)); /* We need to refactorize this. Something like r_anal_op_init would be more appropiate */
if ((op->esil = r_strbuf_new ()) == NULL)
return 1;
r_strbuf_init (op->esil);
r_strbuf_init (&op->esil);
op->size = 1;
switch (buf[0]) {
case '[': op->type = R_ANAL_OP_TYPE_CMP; break;
case '[': op->type = R_ANAL_OP_TYPE_CJMP;
op->fail = addr+1;
{
const ut8 *p = buf + 1;
int lev = 0, i = 1;
while (*p && i<len) {
if (*p == '[')
lev++;
if (*p == ']') {
lev--;
if (lev==-1) {
dst = addr + (size_t)(p-buf);
op->jump = dst;
r_strbuf_setf (&op->esil,
"if (!*ptr) pc=0x%"PFMT64x, dst);
break;
}
}
p++;
i++;
}
}
// ?1[ptr],pc=${NEW_PC
break;
case ']': op->type = R_ANAL_OP_TYPE_UJMP; break;
case '>': op->type = R_ANAL_OP_TYPE_ADD;
r_strbuf_set (op->esil, "ptr++");
r_strbuf_set (&op->esil, "ptr++");
break;
case '<': op->type = R_ANAL_OP_TYPE_SUB;
r_strbuf_set (op->esil, "ptr--");
r_strbuf_set (&op->esil, "ptr--");
break;
case '+': op->type = R_ANAL_OP_TYPE_ADD;
r_strbuf_set (op->esil, "*ptr++");
r_strbuf_set (&op->esil, "*ptr++");
break;
case '-': op->type = R_ANAL_OP_TYPE_SUB;
r_strbuf_set (op->esil, "*ptr--");
r_strbuf_set (&op->esil, "*ptr--");
break;
case '.': op->type = R_ANAL_OP_TYPE_STORE;
r_strbuf_set (op->esil, "=*ptr");
r_strbuf_set (&op->esil, "=*ptr");
break;
case ',': op->type = R_ANAL_OP_TYPE_LOAD; break;
case 0x00:

View File

@ -18,9 +18,7 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
op->type = R_ANAL_OP_TYPE_UNK;
op->size = oplen;
op->delay = 4;
if ((op->esil = r_strbuf_new ()) == NULL)
return oplen;
r_strbuf_init (op->esil);
r_strbuf_init (&op->esil);
//r_mem_copyendian ((ut8*)&opcode, b, 4, !anal->big_endian);
memcpy (&opcode, b, 4);
@ -141,13 +139,13 @@ static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
case 2: // j
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = address;
r_strbuf_setf (op->esil, "pc=0x%08x", address);
r_strbuf_setf (&op->esil, "pc=0x%08x", address);
break;
case 3: // jal
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = address;
op->fail = addr+8;
r_strbuf_setf (op->esil, "lr=pc+4,pc=0x%08x", address);
r_strbuf_setf (&op->esil, "lr=pc+4,pc=0x%08x", address);
break;
}
family = 'J';

View File

@ -155,9 +155,7 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
UDis86Esil *handler;
UDis86OPInfo info = {0, anal->bits, (1LL << anal->bits) - 1, regsz, 0, pc, sp, bp};
memset (op, '\0', sizeof (RAnalOp));
if ((op->esil = r_strbuf_new ()) == NULL)
return -1;
r_strbuf_init (op->esil);
r_strbuf_init (&op->esil);
op->addr = addr;
op->jump = op->fail = -1;
op->ptr = op->val = -1;

View File

@ -2,7 +2,7 @@
#define _UDIS86_ESIL_H
/* This may be useful for other architectures */
#define esilprintf(op, fmt, arg...) r_strbuf_setf (op->esil, fmt, ##arg)
#define esilprintf(op, fmt, arg...) r_strbuf_setf (&op->esil, fmt, ##arg)
#define UDIS86_ESIL_ARGUMENTS const UDis86OPInfo *info, RAnalOp *op, const char *dst, const char *src, const char *src2

View File

@ -179,22 +179,20 @@ static void set_bin_items(RBin *bin, RBinPlugin *cp) {
R_API int r_bin_io_load(RBin *bin, RIO *io, RIODesc *desc, int dummy) {
int rawstr = 0;
ut8* buf_bytes;
RBuffer *bin_buf = NULL;
ut64 start, end,
sz = -1,
offset = 0;
ut8* buf_bytes;
if (!io || !io->plugin || !io->plugin->read || !io->plugin->lseek) {
if (!io || !io->plugin || !io->plugin->read || !io->plugin->lseek)
return R_FALSE;
} else if (!desc || !desc->fd) {
if (!desc || !desc->fd)
return R_FALSE;
}
buf_bytes = NULL;
end = io->plugin->lseek(io, desc, 0, SEEK_END);
start = io->plugin->lseek(io, desc, 0, SEEK_SET);
end = io->plugin->lseek (io, desc, 0, SEEK_END);
start = io->plugin->lseek (io, desc, 0, SEEK_SET);
sz = -1;
offset = 0;
@ -203,22 +201,19 @@ R_API int r_bin_io_load(RBin *bin, RIO *io, RIODesc *desc, int dummy) {
sz = end - start;
buf_bytes = malloc(sz);
if (!buf_bytes || !io->plugin->read(io, desc, buf_bytes, sz)) {
free(buf_bytes);
if (!buf_bytes || !io->plugin->read (io, desc, buf_bytes, sz)) {
free (buf_bytes);
return R_FALSE;
}
memcpy(&rawstr, buf_bytes, 4);
memcpy (&rawstr, buf_bytes, 4);
bin->cur.file = strdup (desc->name);
bin->cur.buf = r_buf_new();
bin->cur.buf = r_buf_new ();
bin->cur.rawstr = rawstr;
if (bin->cur.buf) {
r_buf_set_bytes(bin->cur.buf, buf_bytes, sz);
}
if (buf_bytes) free(buf_bytes);
if (bin->cur.buf)
r_buf_set_bytes (bin->cur.buf, buf_bytes, sz);
free (buf_bytes);
// Here is the pertinent code from r_bin_init
// we can't call r_bin_init, because it will
@ -262,11 +257,10 @@ R_API int r_bin_io_load(RBin *bin, RIO *io, RIODesc *desc, int dummy) {
if (a->curplugin && a->curplugin->minstrlen)
bin->minstrlen = a->curplugin->minstrlen;
if (a->curplugin && a->curplugin->load ) {
if ( a->curplugin->load(a) )
set_bin_items(bin, a->curplugin);
else
if (a->curplugin && a->curplugin->load) {
if (! a->curplugin->load (a) )
return R_FALSE;
set_bin_items (bin, a->curplugin);
}
}
@ -365,7 +359,6 @@ static int r_bin_extract(RBin *bin, int idx) {
return R_TRUE;
}
#define R_NEW_COPY(x,y,z) x=malloc(sizeof(y));memcpy (x,z,sizeof(y))
R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
RListIter *it;
RBinPlugin *plugin;
@ -375,7 +368,8 @@ R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
if (!strcmp (plugin->name, foo->name))
return R_FALSE;
}
R_NEW_COPY (plugin, RBinPlugin, foo);
plugin = R_NEW0 (RBinPlugin);
memcpy (plugin, foo, sizeof (RBinPlugin));
r_list_append (bin->plugins, plugin);
return R_TRUE;
}

10
libr/bin/p/bf.mk Normal file
View File

@ -0,0 +1,10 @@
OBJ_BF=bin_bf.o
STATIC_OBJ+=${OBJ_BF}
TARGET_BF=bin_bf.${EXT_SO}
ALL_TARGETS+=${TARGET_BF}
${TARGET_BF}: ${OBJ_BF}
${CC} $(call libname,bin_bf) -shared ${CFLAGS} \
-o ${TARGET_BF} ${OBJ_BF} $(LDFLAGS)

122
libr/bin/p/bin_bf.c Normal file
View File

@ -0,0 +1,122 @@
/* radare - LGPL - Copyright 2013 - pancake */
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_bin.h>
static int check(RBinArch *arch);
static int load(RBinArch *arch) {
if (check (arch))
return R_TRUE;
return R_FALSE;
}
static int destroy(RBinArch *arch) {
return R_TRUE;
}
static ut64 baddr(RBinArch *arch) {
return 0;
}
static RList *strings(RBinArch *arch) {
return NULL;
}
static RBinInfo* info(RBinArch *arch) {
RBinInfo *ret = NULL;
if (!(ret = R_NEW (RBinInfo)))
return NULL;
memset (ret, '\0', sizeof (RBinInfo));
ret->lang = NULL;
strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS-1);
strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS-1);
strncpy (ret->type, "brainfuck", sizeof (ret->type)-1); // asm.arch
strncpy (ret->bclass, "1.0", sizeof (ret->bclass)-1);
strncpy (ret->rclass, "program", sizeof (ret->rclass)-1); // file.type
strncpy (ret->os, "any", sizeof (ret->os)-1);
strncpy (ret->subsystem, "unknown", sizeof (ret->subsystem)-1);
strncpy (ret->machine, "brainfuck", sizeof (ret->machine)-1);
strcpy (ret->arch, "bf");
ret->has_va = 1;
ret->bits = 16;
ret->big_endian = 0;
ret->dbg_info = 0;
return ret;
}
static int check(RBinArch *arch) {
int i, is_bf = 0;
if (arch->buf) {
int max = R_MIN (16, arch->buf->length);
char *p = arch->buf->buf;
is_bf = 1;
for (i=0; i<max; i++) {
switch (p[i]) {
case '+':
case '-':
case '>':
case '<':
case '[':
case ']':
case ',':
case '.':
case ' ':
case '\n':
case '\r':
break;
default:
is_bf = 0;
}
}
}
return is_bf;
}
static RList* entries(RBinArch *arch) {
RList *ret;
RBinAddr *ptr = NULL;
if (!(ret = r_list_new ()))
return NULL;
ret->free = free;
if (!(ptr = R_NEW (RBinAddr)))
return ret;
memset (ptr, '\0', sizeof (RBinAddr));
ptr->offset = ptr->rva = 0;
r_list_append (ret, ptr);
return ret;
}
struct r_bin_plugin_t r_bin_plugin_bf = {
.name = "bf",
.desc = "brainfuck",
.init = NULL,
.fini = NULL,
.load = &load,
.destroy = &destroy,
.check = &check,
.baddr = &baddr,
.binsym = NULL,
.entries = entries,
.sections = NULL,
.symbols = NULL,
.imports = NULL,
.strings = &strings,
.info = &info,
.fields = NULL,
.libs = NULL,
.relocs = NULL,
.meta = NULL,
.write = NULL,
.demangle_type = NULL
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN,
.data = &r_bin_plugin_bf
};
#endif

View File

@ -201,8 +201,8 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops) {
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
if (*R_STRBUF_SAFEGET (op.esil))
r_cons_printf ("esil: %s\n", R_STRBUF_SAFEGET (op.esil));
if (*R_STRBUF_SAFEGET (&op.esil))
r_cons_printf ("esil: %s\n", R_STRBUF_SAFEGET (&op.esil));
r_cons_printf ("eob: %d\n", op.eob);
if (hint && hint->jump != UT64_MAX)

View File

@ -416,7 +416,7 @@ static int pdi(RCore *core, int l, int len, int ilen) {
if (decode) {
opstr = (tmpopstr)? tmpopstr: strdup (asmop.buf_asm);
} else if (esil) {
opstr = strdup (R_STRBUF_SAFEGET (analop.esil));
opstr = strdup (R_STRBUF_SAFEGET (&analop.esil));
} else opstr = strdup (asmop.buf_asm);
r_cons_printf ("%s\n", opstr);
free (opstr);

View File

@ -601,10 +601,7 @@ toro:
if (!lastfail)
r_anal_op (core->anal, &analop, at, buf+idx, (int)(len-idx));
if (ret<1) {
if (analop.esil != NULL)
r_strbuf_free (analop.esil);
if ((analop.esil = r_strbuf_new ()) != NULL)
r_strbuf_init (analop.esil);
r_strbuf_init (&analop.esil);
analop.type = R_ANAL_OP_TYPE_ILL;
}
if (hint) {
@ -1039,9 +1036,9 @@ toro:
}
}
if (use_esil) {
if (*R_STRBUF_SAFEGET (analop.esil)) {
if (*R_STRBUF_SAFEGET (&analop.esil)) {
free (opstr);
opstr = strdup (R_STRBUF_SAFEGET (analop.esil));
opstr = strdup (R_STRBUF_SAFEGET (&analop.esil));
} else {
char *p = malloc (strlen (opstr)+3); /* What's up '\0' ? */
strcpy (p, ": ");
@ -1421,8 +1418,8 @@ R_API int r_core_print_disasm_instructions (RCore *core, int len, int l) {
} else {
if (esil) {
r_anal_op (core->anal, &analop, at, buf+i, core->blocksize-i);
if (*R_STRBUF_SAFEGET (analop.esil))
opstr = strdup (R_STRBUF_SAFEGET (analop.esil));
if (*R_STRBUF_SAFEGET (&analop.esil))
opstr = strdup (R_STRBUF_SAFEGET (&analop.esil));
} else
if (decode) {
r_anal_op (core->anal, &analop, at, buf+i, core->blocksize-i);

View File

@ -32,8 +32,8 @@ memset (buf, 0, sizeof (buf));
eprintf ("READ 0x%08"PFMT64x" %02x %02x %02x\n", pc, buf[0], buf[1], buf[2]);
oplen = r_anal_op (dbg->anal, &op, pc, buf, sizeof (buf));
if (oplen>0) {
if (*R_STRBUF_SAFEGET (op.esil)) {
eprintf ("ESIL: %s\n", R_STRBUF_SAFEGET (op.esil));
if (*R_STRBUF_SAFEGET (&op.esil)) {
eprintf ("ESIL: %s\n", R_STRBUF_SAFEGET (&op.esil));
}
}
eprintf ("TODO: ESIL STEP\n");

View File

@ -571,10 +571,10 @@ value->val
ut64 val; /* reference to value */ /* XXX signed? */
st64 stackptr; /* stack pointer */
int refptr;
RStrBuf *esil;
RAnalValue *src[3];
RAnalValue *dst;
struct r_anal_op_t *next; // XXX deprecate
RStrBuf esil;
} RAnalOp;
#define R_ANAL_COND_SINGLE(x) (!x->arg[1] || x->arg[0]==x->arg[1])

View File

@ -355,6 +355,7 @@ extern RBinPlugin r_bin_plugin_pe;
extern RBinPlugin r_bin_plugin_mz;
extern RBinPlugin r_bin_plugin_pe64;
extern RBinPlugin r_bin_plugin_bios;
extern RBinPlugin r_bin_plugin_bf;
extern RBinPlugin r_bin_plugin_te;
extern RBinPlugin r_bin_plugin_mach0;
extern RBinPlugin r_bin_plugin_mach064;

View File

@ -127,7 +127,7 @@ typedef void (*PrintfCallback)(const char *str, ...);
#define R_NEW(x) (x*)malloc(sizeof(x))
#define R_NEW0(x) (x*)calloc(1,sizeof(x))
// TODO: Make R_NEW_COPY be 1 arg, not two
#define R_NEW_COPY(x,y) x=(y*)malloc(sizeof(y));memcpy(x,y,sizeof(y))
#define R_NEW_COPY(x,y) x=(void*)malloc(sizeof(y));memcpy(x,y,sizeof(y))
#define IS_PRINTABLE(x) (x>=' '&&x<='~')
#define IS_WHITESPACE(x) (x==' '||x=='\t')
#define R_MEM_ALIGN(x) ((void *)(size_t)(((ut64)(size_t)x) & 0xfffffffffffff000LL))

View File

@ -54,6 +54,7 @@ anal.sparc
anal.ebc
bin.any
bin.bios
bin.bf
bin.fs
bin.elf
bin.elf64
@ -67,6 +68,7 @@ bin.pe64
bin.te
bin.mach0
bin.mach064
bin.ningb
bin_xtr.fatmach0
bin_xtr.dyldcache
bp.arm
@ -123,6 +125,5 @@ parse.mips_pseudo
parse.dalvik_pseudo
parse.x86_pseudo"
SHARED="
bin.ningb
asm.psosvm
io.shm"