* More work on r_anal

- Basic Block analysis is working
This commit is contained in:
Nibble 2010-02-26 21:00:03 +01:00
parent f986ce8a31
commit a0c28f1394
7 changed files with 113 additions and 39 deletions

View File

@ -10,38 +10,49 @@ R_API RAnalysis *r_anal_new() {
return r_anal_init (MALLOC_STRUCT (struct r_anal_t));
}
R_API RAnalysisBB *r_anal_bb_new() {
return r_anal_bb_init (MALLOC_STRUCT (struct r_anal_bb_t));
}
R_API RAnalysisAop *r_anal_aop_new() {
return r_anal_aop_init (MALLOC_STRUCT (struct r_anal_aop_t));
}
R_API RList *r_anal_bb_list_new() {
RList *list = r_list_new ();
list->free = &r_anal_bb_list_free;
list->free = &r_anal_bb_free;
return list;
}
R_API RList *r_anal_aop_list_new() {
RList *list = r_list_new ();
list->free = &r_anal_aop_list_free;
list->free = &r_anal_aop_free;
return list;
}
R_API RAnalysis *r_anal_free(struct r_anal_t *a) {
/* TODO: Free a->anals here */
/* TODO: Free a->bbs here */
r_list_destroy (a->bbs);
free (a);
return NULL;
}
R_API void r_anal_bb_list_free(void *bbs) {
/* TODO */
R_API void r_anal_bb_free(void *bb) {
/*TODO*/
if (bb) {
r_list_destroy (((RAnalysisBB*)bb)->aops);
free (bb);
}
}
R_API void r_anal_aop_list_free(void *aops) {
/* TODO */
R_API void r_anal_aop_free(void *aop) {
if (aop)
free (aop);
}
R_API struct r_anal_t *r_anal_init(struct r_anal_t *anal) {
R_API RAnalysis *r_anal_init(struct r_anal_t *anal) {
if (anal) {
anal->user = NULL;
anal->ctx = NULL;
anal->cur = NULL;
memset (anal, 0, sizeof (RAnalysis));
anal->bbs = r_anal_bb_list_new();
r_anal_set_bits (anal, 32);
r_anal_set_big_endian (anal, R_FALSE);
@ -50,6 +61,26 @@ R_API struct r_anal_t *r_anal_init(struct r_anal_t *anal) {
return anal;
}
R_API RAnalysisBB *r_anal_bb_init(struct r_anal_bb_t *bb) {
if (bb) {
memset (bb, 0, sizeof (RAnalysisBB));
bb->addr = -1;
bb->jump = -1;
bb->fail = -1;
bb->aops = r_anal_aop_list_new();
}
return bb;
}
R_API RAnalysisAop *r_anal_aop_init(struct r_anal_aop_t *aop) {
if (aop) {
memset (aop, 0, sizeof (RAnalysisAop));
aop->jump = -1;
aop->fail = -1;
}
return aop;
}
R_API void r_anal_set_user_ptr(struct r_anal_t *anal, void *user) {
anal->user = user;
}
@ -106,37 +137,34 @@ R_API int r_anal_aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr,
return R_FALSE;
}
R_API int r_anal_bbs(struct r_anal_t *anal, ut64 addr, ut8 *buf, ut64 len) {
/* XXX No working*/
struct r_anal_bb_t *bb;
R_API int r_anal_bb(struct r_anal_t *anal, struct r_anal_bb_t *bb, ut64 addr, ut8 *buf, ut64 len) {
struct r_anal_aop_t *aop;
ut64 oplen;
int oplen, idx = 0;
if (!(bb = MALLOC_STRUCT(struct r_anal_bb_t))) {
eprintf ("Error: malloc (bb)\n");
return R_FALSE;
}
r_list_append (anal->bbs, bb);
bb->addr = addr;
for (;;) {
if (!(aop = MALLOC_STRUCT(struct r_anal_aop_t))) {
eprintf ("Error: malloc (aop)\n");
return R_FALSE;
while (idx < len) {
if (!(aop = r_anal_aop_new())) {
eprintf ("Error: new (aop)\n");
return 0;
}
if (!(oplen = r_anal_aop (anal, aop, addr, buf, len)))
if (!(oplen = r_anal_aop (anal, aop, addr+idx, buf+idx, len-idx))) {
free (aop);
break;
}
idx += oplen;
r_list_append (bb->aops, aop);
switch (aop->type) {
case R_ANAL_OP_TYPE_CJMP:
bb->fail = aop->fail;
r_anal_bbs (anal, bb->fail, buf, len);
eprintf ("FAIL: %08llx\n", bb->fail);
case R_ANAL_OP_TYPE_JMP:
bb->jump = aop->jump;
r_anal_bbs (anal, bb->jump, buf, len);
bb->size = addr + oplen - bb->addr;
eprintf ("JUMP: %08llx\n", bb->jump);
bb->size = idx;
break;
case R_ANAL_OP_TYPE_CALL:
break;
}
addr += oplen;
}
return R_TRUE;
return idx;
}

View File

@ -28,7 +28,7 @@
// XXX addr should be off_t for 64 love
static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void *data, int len) {
if (anal == NULL || aop == NULL || data == NULL)
return -1;
return 0;
ut8 *buf = (ut8*)data;
memset(aop, '\0', sizeof(struct r_anal_aop_t));

View File

@ -1,7 +1,7 @@
NAME=r_core
DEPS=r_config r_cons r_line r_io r_cmd r_util r_print r_flags r_asm r_lib r_macro r_debug r_hash r_bin r_lang r_io r_asm r_anal r_parse r_config r_macro r_print r_bp r_reg r_meta r_search
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o anal.o
CFLAGS+=-DLIBDIR=\"${PREFIX}/lib\"
CFLAGS+=-DPREFIX=\"${PREFIX}\"

32
libr/core/anal.c Normal file
View File

@ -0,0 +1,32 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
#include <r_types.h>
#include <r_list.h>
#include <r_core.h>
R_API int r_core_anal_bb (struct r_core_t *core, ut64 at) {
struct r_anal_bb_t *bb, *bbi;
ut8 *buf;
RListIter *iter = r_list_iterator (core->anal.bbs);
while (r_list_iter_next (iter)) {
bbi = r_list_iter_get (iter);
if (at >= bbi->addr && at < bbi->addr + bbi->size)
return R_FALSE;
}
if (!(buf = malloc (core->blocksize)))
return R_FALSE;
if (!(bb = r_anal_bb_new()))
return R_FALSE;
if (r_io_read_at (&core->io, at, buf, core->blocksize) == -1)
return R_FALSE;
r_list_append (core->anal.bbs, bb);
if (r_anal_bb (&core->anal, bb, at, buf, core->blocksize)) {
if (bb->fail != -1)
r_core_anal_bb (core, bb->fail);
if (bb->jump != -1)
r_core_anal_bb (core, bb->jump);
}
free (buf);
return R_TRUE;
}

View File

@ -1,4 +1,6 @@
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2010 */
/* nibble<.ds@gmail.com> */
/* pancake<nopcode.org> */
#include "r_core.h"
#include "r_flags.h"
@ -887,6 +889,8 @@ static int cmd_anal(void *data, const char *input) {
} else r_anal_list (&core->anal);
break;
case 'o':
r_cons_printf ("TODO\n");
#if 0
{
/* XXX hardcoded */
int ret, idx;
@ -898,9 +902,10 @@ static int cmd_anal(void *data, const char *input) {
ret = r_anal_aop(&core->anal, &aop,
core->offset+idx, buf + idx, (len-idx));
}
#endif
break;
case 'c':
r_cons_printf ("TODO\n");
r_core_anal_bb (core, core->offset);
break;
default:
r_cons_printf (

View File

@ -161,13 +161,17 @@ typedef struct r_anal_handle_t {
/* anal.c */
#ifdef R_API
R_API struct r_anal_t *r_anal_new();
R_API RAnalysis *r_anal_new();
R_API RAnalysisBB *r_anal_bb_new();
R_API RAnalysisAop *r_anal_aop_new();
R_API RList *r_anal_bb_list_new();
R_API RList *r_anal_aop_list_new();
R_API struct r_anal_t *r_anal_free(struct r_anal_t *r);
R_API void r_anal_bb_list_free(void *bbs);
R_API void r_anal_aop_list_free(void *aops);
R_API struct r_anal_t *r_anal_init(struct r_anal_t *anal);
R_API RAnalysis *r_anal_free(struct r_anal_t *r);
R_API void r_anal_bb_free(void *bb);
R_API void r_anal_aop_free(void *aop);
R_API RAnalysis *r_anal_init(struct r_anal_t *anal);
R_API RAnalysisBB *r_anal_bb_init(struct r_anal_bb_t *bb);
R_API RAnalysisAop *r_anal_aop_init(struct r_anal_aop_t *aop);
R_API void r_anal_set_user_ptr(struct r_anal_t *anal, void *user);
R_API int r_anal_add(struct r_anal_t *anal, struct r_anal_handle_t *foo);
R_API int r_anal_list(struct r_anal_t *anal);
@ -177,6 +181,8 @@ R_API int r_anal_set_big_endian(struct r_anal_t *anal, int boolean);
R_API int r_anal_set_pc(struct r_anal_t *a, ut64 pc);
R_API int r_anal_aop(struct r_anal_t *anal, struct r_anal_aop_t *aop,
ut64 addr, void *data, int len);
R_API int r_anal_bb(struct r_anal_t *anal, struct r_anal_bb_t *bb,
ut64 addr, ut8 *buf, ut64 len);
/* reflines.c */
R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,

View File

@ -106,6 +106,9 @@ R_API int r_core_cmdf(void *user, const char *fmt, ...);
R_API int r_core_cmd0(void *user, const char *cmd);
R_API char *r_core_cmd_str(struct r_core_t *core, const char *cmd);
R_API int r_core_cmd_foreach(struct r_core_t *core, const char *cmd, char *each);
/* anal.c */
R_API int r_core_anal_bb (struct r_core_t *core, ut64 at);
#endif
#endif