mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-11 15:04:23 +00:00
* r_anal
- Split anal.c in several files (bb.c, aop.c, var.c...)
This commit is contained in:
parent
071aaf0a4e
commit
9a1f1bc44c
@ -8,7 +8,7 @@ foo: pre libr_anal.${EXT_SO} libr_anal.${EXT_AR} plugins
|
|||||||
|
|
||||||
include ${STATIC_ANAL_PLUGINS}
|
include ${STATIC_ANAL_PLUGINS}
|
||||||
STATIC_OBJS=$(subst ..,p/..,$(subst anal_,p/anal_,$(STATIC_OBJ)))
|
STATIC_OBJS=$(subst ..,p/..,$(subst anal_,p/anal_,$(STATIC_OBJ)))
|
||||||
OBJ=${STATIC_OBJS} ctx.o reflines.o var.o anal.o
|
OBJ=${STATIC_OBJS} ctx.o reflines.o ref.o aop.o fcn.o bb.o var.o anal.o
|
||||||
|
|
||||||
pre:
|
pre:
|
||||||
if [ ! -e libr_anal.${EXT_SO} ]; then rm -f ${STATIC_OBJS} ; fi
|
if [ ! -e libr_anal.${EXT_SO} ]; then rm -f ${STATIC_OBJS} ; fi
|
||||||
|
272
libr/anal/anal.c
272
libr/anal/anal.c
@ -23,46 +23,6 @@ R_API RAnalysis *r_anal_new() {
|
|||||||
return r_anal_init (MALLOC_STRUCT (RAnalysis));
|
return r_anal_init (MALLOC_STRUCT (RAnalysis));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API RAnalysisBB *r_anal_bb_new() {
|
|
||||||
return r_anal_bb_init (MALLOC_STRUCT (RAnalysisBB));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysisAop *r_anal_aop_new() {
|
|
||||||
return r_anal_aop_init (MALLOC_STRUCT (RAnalysisAop));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysisFcn *r_anal_fcn_new() {
|
|
||||||
return r_anal_fcn_init (MALLOC_STRUCT (RAnalysisFcn));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysisRef *r_anal_ref_new() {
|
|
||||||
return r_anal_ref_init (MALLOC_STRUCT (RAnalysisRef));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RList *r_anal_bb_list_new() {
|
|
||||||
RList *list = r_list_new ();
|
|
||||||
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_free;
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RList *r_anal_fcn_list_new() {
|
|
||||||
RList *list = r_list_new ();
|
|
||||||
list->free = &r_anal_fcn_free;
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RList *r_anal_ref_list_new() {
|
|
||||||
RList *list = r_list_new ();
|
|
||||||
list->free = &r_anal_ref_free;
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysis *r_anal_free(RAnalysis *a) {
|
R_API RAnalysis *r_anal_free(RAnalysis *a) {
|
||||||
if (a) {
|
if (a) {
|
||||||
/* TODO: Free a->anals here */
|
/* TODO: Free a->anals here */
|
||||||
@ -77,34 +37,6 @@ R_API RAnalysis *r_anal_free(RAnalysis *a) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_anal_aop_free(void *aop) {
|
|
||||||
free (aop);
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API void r_anal_ref_free(void *ref) {
|
|
||||||
free (ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API void r_anal_bb_free(void *bb) {
|
|
||||||
if (bb && ((RAnalysisBB*)bb)->aops)
|
|
||||||
r_list_destroy (((RAnalysisBB*)bb)->aops);
|
|
||||||
free (bb);
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API void r_anal_fcn_free(void *fcn) {
|
|
||||||
if (fcn) {
|
|
||||||
if (((RAnalysisFcn*)fcn)->name)
|
|
||||||
free (((RAnalysisFcn*)fcn)->name);
|
|
||||||
if (((RAnalysisFcn*)fcn)->refs)
|
|
||||||
r_list_destroy (((RAnalysisFcn*)fcn)->refs);
|
|
||||||
if (((RAnalysisFcn*)fcn)->xrefs)
|
|
||||||
r_list_destroy (((RAnalysisFcn*)fcn)->xrefs);
|
|
||||||
if (((RAnalysisFcn*)fcn)->vars)
|
|
||||||
r_list_destroy (((RAnalysisFcn*)fcn)->vars);
|
|
||||||
}
|
|
||||||
free (fcn);
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysis *r_anal_init(RAnalysis *anal) {
|
R_API RAnalysis *r_anal_init(RAnalysis *anal) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -125,44 +57,6 @@ R_API RAnalysis *r_anal_init(RAnalysis *anal) {
|
|||||||
return anal;
|
return anal;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API RAnalysisBB *r_anal_bb_init(RAnalysisBB *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(RAnalysisAop *aop) {
|
|
||||||
if (aop) {
|
|
||||||
memset (aop, 0, sizeof (RAnalysisAop));
|
|
||||||
aop->addr = -1;
|
|
||||||
aop->jump = -1;
|
|
||||||
aop->fail = -1;
|
|
||||||
}
|
|
||||||
return aop;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysisFcn *r_anal_fcn_init(RAnalysisFcn *fcn) {
|
|
||||||
if (fcn) {
|
|
||||||
memset (fcn, 0, sizeof (RAnalysisFcn));
|
|
||||||
fcn->addr = -1;
|
|
||||||
fcn->vars = r_anal_var_list_new ();
|
|
||||||
fcn->refs = r_anal_ref_list_new ();
|
|
||||||
fcn->xrefs = r_anal_ref_list_new ();
|
|
||||||
}
|
|
||||||
return fcn;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API RAnalysisRef *r_anal_ref_init(RAnalysisRef *ref) {
|
|
||||||
if (ref)
|
|
||||||
*ref = -1;
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API void r_anal_set_user_ptr(RAnalysis *anal, void *user) {
|
R_API void r_anal_set_user_ptr(RAnalysis *anal, void *user) {
|
||||||
anal->user = user;
|
anal->user = user;
|
||||||
}
|
}
|
||||||
@ -212,169 +106,3 @@ R_API int r_anal_set_big_endian(RAnalysis *anal, int bigend) {
|
|||||||
anal->big_endian = bigend;
|
anal->big_endian = bigend;
|
||||||
return R_TRUE;
|
return R_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_anal_aop(RAnalysis *anal, RAnalysisAop *aop, ut64 addr, const ut8 *data, int len) {
|
|
||||||
if (anal && aop && anal->cur && anal->cur->aop)
|
|
||||||
return anal->cur->aop(anal, aop, addr, data, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API int r_anal_bb(RAnalysis *anal, RAnalysisBB *bb, ut64 addr, ut8 *buf, ut64 len) {
|
|
||||||
RAnalysisAop *aop;
|
|
||||||
int oplen, idx = 0;
|
|
||||||
|
|
||||||
if (bb->addr == -1)
|
|
||||||
bb->addr = addr;
|
|
||||||
while (idx < len) {
|
|
||||||
if (!(aop = r_anal_aop_new())) {
|
|
||||||
eprintf ("Error: new (aop)\n");
|
|
||||||
return R_ANAL_RET_ERROR;
|
|
||||||
}
|
|
||||||
if ((oplen = r_anal_aop (anal, aop, addr+idx, buf+idx, len-idx)) == 0) {
|
|
||||||
r_anal_aop_free (aop);
|
|
||||||
if (idx == 0)
|
|
||||||
return R_ANAL_RET_ERROR;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
idx += oplen;
|
|
||||||
bb->size += oplen;
|
|
||||||
r_list_append (bb->aops, aop);
|
|
||||||
switch (aop->type) {
|
|
||||||
case R_ANAL_OP_TYPE_CJMP:
|
|
||||||
bb->fail = aop->fail;
|
|
||||||
case R_ANAL_OP_TYPE_JMP:
|
|
||||||
bb->jump = aop->jump;
|
|
||||||
case R_ANAL_OP_TYPE_RET:
|
|
||||||
return R_ANAL_RET_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bb->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API int r_anal_bb_split(RAnalysis *anal, RAnalysisBB *bb, RList *bbs, ut64 addr) {
|
|
||||||
RAnalysisBB *bbi;
|
|
||||||
RAnalysisAop *aopi;
|
|
||||||
RListIter *iter;
|
|
||||||
|
|
||||||
r_list_foreach (bbs, iter, bbi)
|
|
||||||
if (addr == bbi->addr)
|
|
||||||
return R_ANAL_RET_DUP;
|
|
||||||
else if (addr > bbi->addr && addr < bbi->addr + bbi->size) {
|
|
||||||
r_list_append (bbs, bb);
|
|
||||||
bb->addr = addr;
|
|
||||||
bb->size = bbi->addr + bbi->size - addr;
|
|
||||||
bb->jump = bbi->jump;
|
|
||||||
bb->fail = bbi->fail;
|
|
||||||
bbi->size = addr - bbi->addr;
|
|
||||||
bbi->jump = addr;
|
|
||||||
bbi->fail = -1;
|
|
||||||
iter = r_list_iterator (bbi->aops);
|
|
||||||
while (r_list_iter_next (iter)) {
|
|
||||||
aopi = r_list_iter_get (iter);
|
|
||||||
if (aopi->addr >= addr) {
|
|
||||||
r_list_split (bbi->aops, aopi);
|
|
||||||
r_list_append (bb->aops, aopi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return R_ANAL_RET_END;
|
|
||||||
}
|
|
||||||
return R_ANAL_RET_NEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API int r_anal_bb_overlap(RAnalysis *anal, RAnalysisBB *bb, RList *bbs) {
|
|
||||||
RAnalysisBB *bbi;
|
|
||||||
RAnalysisAop *aopi;
|
|
||||||
RListIter *iter;
|
|
||||||
|
|
||||||
r_list_foreach (bbs, iter, bbi)
|
|
||||||
if (bbi->addr > bb->addr && bbi->addr < bb->addr+bb->size) {
|
|
||||||
bb->size = bbi->addr - bb->addr;
|
|
||||||
bb->jump = bbi->addr;
|
|
||||||
bb->fail = -1;
|
|
||||||
r_list_foreach (bb->aops, iter, aopi)
|
|
||||||
if (aopi->addr >= bbi->addr)
|
|
||||||
r_list_unlink (bb->aops, aopi);
|
|
||||||
r_list_append (bbs, bb);
|
|
||||||
return R_ANAL_RET_END;
|
|
||||||
}
|
|
||||||
return R_ANAL_RET_NEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API int r_anal_fcn(RAnalysis *anal, RAnalysisFcn *fcn, ut64 addr, ut8 *buf, ut64 len) {
|
|
||||||
RAnalysisRef *ref, *refi;
|
|
||||||
RListIter *iter;
|
|
||||||
RAnalysisAop aop;
|
|
||||||
ut64 *jump;
|
|
||||||
char *varname;
|
|
||||||
int oplen, idx = 0;
|
|
||||||
|
|
||||||
if (fcn->addr == -1)
|
|
||||||
fcn->addr = addr;
|
|
||||||
while (idx < len) {
|
|
||||||
if ((oplen = r_anal_aop (anal, &aop, addr+idx, buf+idx, len-idx)) == 0) {
|
|
||||||
if (idx == 0)
|
|
||||||
return R_ANAL_RET_ERROR;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
idx += oplen;
|
|
||||||
fcn->size += oplen;
|
|
||||||
/* TODO: Parse R_ANAL_VAR_ARGREG */
|
|
||||||
switch (aop.stackop) {
|
|
||||||
case R_ANAL_STACK_LOCAL_SET:
|
|
||||||
if (aop.ref < 0) {
|
|
||||||
varname = r_str_dup_printf ("arg_%i", -aop.ref);
|
|
||||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref, R_ANAL_VAR_TYPE_ARG,
|
|
||||||
varname, NULL, 1);
|
|
||||||
} else {
|
|
||||||
varname = r_str_dup_printf ("local_%i", aop.ref);
|
|
||||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_LOCAL,
|
|
||||||
varname, NULL, 1);
|
|
||||||
}
|
|
||||||
free (varname);
|
|
||||||
break;
|
|
||||||
case R_ANAL_STACK_ARG_SET:
|
|
||||||
varname = r_str_dup_printf ("arg_%i", aop.ref);
|
|
||||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_ARG,
|
|
||||||
varname, NULL, 1);
|
|
||||||
free (varname);
|
|
||||||
break;
|
|
||||||
case R_ANAL_STACK_ARG_GET:
|
|
||||||
varname = r_str_dup_printf ("arg_%i", aop.ref);
|
|
||||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_ARG,
|
|
||||||
varname, NULL, 0);
|
|
||||||
free (varname);
|
|
||||||
break;
|
|
||||||
case R_ANAL_STACK_LOCAL_GET:
|
|
||||||
if (aop.ref < 0) {
|
|
||||||
varname = r_str_dup_printf ("arg_%i", -aop.ref);
|
|
||||||
r_anal_var_add (anal, fcn, aop.addr, -aop.ref, R_ANAL_VAR_TYPE_ARG,
|
|
||||||
varname, NULL, 0);
|
|
||||||
} else {
|
|
||||||
varname = r_str_dup_printf ("local_%i", aop.ref);
|
|
||||||
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_LOCAL,
|
|
||||||
varname, NULL, 0);
|
|
||||||
}
|
|
||||||
free (varname);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (aop.type) {
|
|
||||||
case R_ANAL_OP_TYPE_CALL:
|
|
||||||
r_list_foreach (fcn->refs, iter, refi) {
|
|
||||||
jump = (ut64*)refi;
|
|
||||||
if (aop.jump == *jump)
|
|
||||||
goto _dup_ref;
|
|
||||||
}
|
|
||||||
if (!(ref = r_anal_ref_new())) {
|
|
||||||
eprintf ("Error: new (ref)\n");
|
|
||||||
return R_ANAL_RET_ERROR;
|
|
||||||
}
|
|
||||||
*ref = aop.jump;
|
|
||||||
r_list_append (fcn->refs, ref);
|
|
||||||
_dup_ref:
|
|
||||||
break;
|
|
||||||
case R_ANAL_OP_TYPE_RET:
|
|
||||||
return R_ANAL_RET_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fcn->size;
|
|
||||||
}
|
|
||||||
|
37
libr/anal/aop.c
Normal file
37
libr/anal/aop.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* radare - LGPL - Copyright 2010 */
|
||||||
|
/* nibble<.ds@gmail.com> */
|
||||||
|
/* pancake<nopcode.org> */
|
||||||
|
|
||||||
|
#include <r_anal.h>
|
||||||
|
#include <r_util.h>
|
||||||
|
#include <r_list.h>
|
||||||
|
|
||||||
|
R_API RAnalysisAop *r_anal_aop_new() {
|
||||||
|
return r_anal_aop_init (MALLOC_STRUCT (RAnalysisAop));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RList *r_anal_aop_list_new() {
|
||||||
|
RList *list = r_list_new ();
|
||||||
|
list->free = &r_anal_aop_free;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API void r_anal_aop_free(void *aop) {
|
||||||
|
free (aop);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RAnalysisAop *r_anal_aop_init(RAnalysisAop *aop) {
|
||||||
|
if (aop) {
|
||||||
|
memset (aop, 0, sizeof (RAnalysisAop));
|
||||||
|
aop->addr = -1;
|
||||||
|
aop->jump = -1;
|
||||||
|
aop->fail = -1;
|
||||||
|
}
|
||||||
|
return aop;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API int r_anal_aop(RAnalysis *anal, RAnalysisAop *aop, ut64 addr, const ut8 *data, int len) {
|
||||||
|
if (anal && aop && anal->cur && anal->cur->aop)
|
||||||
|
return anal->cur->aop(anal, aop, addr, data, len);
|
||||||
|
return 0;
|
||||||
|
}
|
115
libr/anal/bb.c
Normal file
115
libr/anal/bb.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/* radare - LGPL - Copyright 2010 */
|
||||||
|
/* nibble<.ds@gmail.com> */
|
||||||
|
/* pancake<nopcode.org> */
|
||||||
|
|
||||||
|
#include <r_anal.h>
|
||||||
|
#include <r_util.h>
|
||||||
|
#include <r_list.h>
|
||||||
|
|
||||||
|
R_API RAnalysisBB *r_anal_bb_new() {
|
||||||
|
return r_anal_bb_init (MALLOC_STRUCT (RAnalysisBB));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RList *r_anal_bb_list_new() {
|
||||||
|
RList *list = r_list_new ();
|
||||||
|
list->free = &r_anal_bb_free;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API void r_anal_bb_free(void *bb) {
|
||||||
|
if (bb && ((RAnalysisBB*)bb)->aops)
|
||||||
|
r_list_destroy (((RAnalysisBB*)bb)->aops);
|
||||||
|
free (bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RAnalysisBB *r_anal_bb_init(RAnalysisBB *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 int r_anal_bb(RAnalysis *anal, RAnalysisBB *bb, ut64 addr, ut8 *buf, ut64 len) {
|
||||||
|
RAnalysisAop *aop;
|
||||||
|
int oplen, idx = 0;
|
||||||
|
|
||||||
|
if (bb->addr == -1)
|
||||||
|
bb->addr = addr;
|
||||||
|
while (idx < len) {
|
||||||
|
if (!(aop = r_anal_aop_new())) {
|
||||||
|
eprintf ("Error: new (aop)\n");
|
||||||
|
return R_ANAL_RET_ERROR;
|
||||||
|
}
|
||||||
|
if ((oplen = r_anal_aop (anal, aop, addr+idx, buf+idx, len-idx)) == 0) {
|
||||||
|
r_anal_aop_free (aop);
|
||||||
|
if (idx == 0)
|
||||||
|
return R_ANAL_RET_ERROR;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
idx += oplen;
|
||||||
|
bb->size += oplen;
|
||||||
|
r_list_append (bb->aops, aop);
|
||||||
|
switch (aop->type) {
|
||||||
|
case R_ANAL_OP_TYPE_CJMP:
|
||||||
|
bb->fail = aop->fail;
|
||||||
|
case R_ANAL_OP_TYPE_JMP:
|
||||||
|
bb->jump = aop->jump;
|
||||||
|
case R_ANAL_OP_TYPE_RET:
|
||||||
|
return R_ANAL_RET_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bb->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API int r_anal_bb_split(RAnalysis *anal, RAnalysisBB *bb, RList *bbs, ut64 addr) {
|
||||||
|
RAnalysisBB *bbi;
|
||||||
|
RAnalysisAop *aopi;
|
||||||
|
RListIter *iter;
|
||||||
|
|
||||||
|
r_list_foreach (bbs, iter, bbi)
|
||||||
|
if (addr == bbi->addr)
|
||||||
|
return R_ANAL_RET_DUP;
|
||||||
|
else if (addr > bbi->addr && addr < bbi->addr + bbi->size) {
|
||||||
|
r_list_append (bbs, bb);
|
||||||
|
bb->addr = addr;
|
||||||
|
bb->size = bbi->addr + bbi->size - addr;
|
||||||
|
bb->jump = bbi->jump;
|
||||||
|
bb->fail = bbi->fail;
|
||||||
|
bbi->size = addr - bbi->addr;
|
||||||
|
bbi->jump = addr;
|
||||||
|
bbi->fail = -1;
|
||||||
|
iter = r_list_iterator (bbi->aops);
|
||||||
|
while (r_list_iter_next (iter)) {
|
||||||
|
aopi = r_list_iter_get (iter);
|
||||||
|
if (aopi->addr >= addr) {
|
||||||
|
r_list_split (bbi->aops, aopi);
|
||||||
|
r_list_append (bb->aops, aopi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R_ANAL_RET_END;
|
||||||
|
}
|
||||||
|
return R_ANAL_RET_NEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API int r_anal_bb_overlap(RAnalysis *anal, RAnalysisBB *bb, RList *bbs) {
|
||||||
|
RAnalysisBB *bbi;
|
||||||
|
RAnalysisAop *aopi;
|
||||||
|
RListIter *iter;
|
||||||
|
|
||||||
|
r_list_foreach (bbs, iter, bbi)
|
||||||
|
if (bbi->addr > bb->addr && bbi->addr < bb->addr+bb->size) {
|
||||||
|
bb->size = bbi->addr - bb->addr;
|
||||||
|
bb->jump = bbi->addr;
|
||||||
|
bb->fail = -1;
|
||||||
|
r_list_foreach (bb->aops, iter, aopi)
|
||||||
|
if (aopi->addr >= bbi->addr)
|
||||||
|
r_list_unlink (bb->aops, aopi);
|
||||||
|
r_list_append (bbs, bb);
|
||||||
|
return R_ANAL_RET_END;
|
||||||
|
}
|
||||||
|
return R_ANAL_RET_NEW;
|
||||||
|
}
|
121
libr/anal/fcn.c
Normal file
121
libr/anal/fcn.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* radare - LGPL - Copyright 2010 */
|
||||||
|
/* nibble<.ds@gmail.com> */
|
||||||
|
/* pancake<nopcode.org> */
|
||||||
|
|
||||||
|
#include <r_anal.h>
|
||||||
|
#include <r_util.h>
|
||||||
|
#include <r_list.h>
|
||||||
|
|
||||||
|
R_API RAnalysisFcn *r_anal_fcn_new() {
|
||||||
|
return r_anal_fcn_init (MALLOC_STRUCT (RAnalysisFcn));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RList *r_anal_fcn_list_new() {
|
||||||
|
RList *list = r_list_new ();
|
||||||
|
list->free = &r_anal_fcn_free;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API void r_anal_fcn_free(void *fcn) {
|
||||||
|
if (fcn) {
|
||||||
|
if (((RAnalysisFcn*)fcn)->name)
|
||||||
|
free (((RAnalysisFcn*)fcn)->name);
|
||||||
|
if (((RAnalysisFcn*)fcn)->refs)
|
||||||
|
r_list_destroy (((RAnalysisFcn*)fcn)->refs);
|
||||||
|
if (((RAnalysisFcn*)fcn)->xrefs)
|
||||||
|
r_list_destroy (((RAnalysisFcn*)fcn)->xrefs);
|
||||||
|
if (((RAnalysisFcn*)fcn)->vars)
|
||||||
|
r_list_destroy (((RAnalysisFcn*)fcn)->vars);
|
||||||
|
}
|
||||||
|
free (fcn);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RAnalysisFcn *r_anal_fcn_init(RAnalysisFcn *fcn) {
|
||||||
|
if (fcn) {
|
||||||
|
memset (fcn, 0, sizeof (RAnalysisFcn));
|
||||||
|
fcn->addr = -1;
|
||||||
|
fcn->vars = r_anal_var_list_new ();
|
||||||
|
fcn->refs = r_anal_ref_list_new ();
|
||||||
|
fcn->xrefs = r_anal_ref_list_new ();
|
||||||
|
}
|
||||||
|
return fcn;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API int r_anal_fcn(RAnalysis *anal, RAnalysisFcn *fcn, ut64 addr, ut8 *buf, ut64 len) {
|
||||||
|
RAnalysisRef *ref, *refi;
|
||||||
|
RListIter *iter;
|
||||||
|
RAnalysisAop aop;
|
||||||
|
ut64 *jump;
|
||||||
|
char *varname;
|
||||||
|
int oplen, idx = 0;
|
||||||
|
|
||||||
|
if (fcn->addr == -1)
|
||||||
|
fcn->addr = addr;
|
||||||
|
while (idx < len) {
|
||||||
|
if ((oplen = r_anal_aop (anal, &aop, addr+idx, buf+idx, len-idx)) == 0) {
|
||||||
|
if (idx == 0)
|
||||||
|
return R_ANAL_RET_ERROR;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
idx += oplen;
|
||||||
|
fcn->size += oplen;
|
||||||
|
/* TODO: Parse R_ANAL_VAR_ARGREG */
|
||||||
|
switch (aop.stackop) {
|
||||||
|
case R_ANAL_STACK_LOCAL_SET:
|
||||||
|
if (aop.ref < 0) {
|
||||||
|
varname = r_str_dup_printf ("arg_%i", -aop.ref);
|
||||||
|
r_anal_var_add (anal, fcn, aop.addr, -aop.ref, R_ANAL_VAR_TYPE_ARG,
|
||||||
|
varname, NULL, 1);
|
||||||
|
} else {
|
||||||
|
varname = r_str_dup_printf ("local_%i", aop.ref);
|
||||||
|
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_LOCAL,
|
||||||
|
varname, NULL, 1);
|
||||||
|
}
|
||||||
|
free (varname);
|
||||||
|
break;
|
||||||
|
case R_ANAL_STACK_ARG_SET:
|
||||||
|
varname = r_str_dup_printf ("arg_%i", aop.ref);
|
||||||
|
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_ARG,
|
||||||
|
varname, NULL, 1);
|
||||||
|
free (varname);
|
||||||
|
break;
|
||||||
|
case R_ANAL_STACK_ARG_GET:
|
||||||
|
varname = r_str_dup_printf ("arg_%i", aop.ref);
|
||||||
|
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_ARG,
|
||||||
|
varname, NULL, 0);
|
||||||
|
free (varname);
|
||||||
|
break;
|
||||||
|
case R_ANAL_STACK_LOCAL_GET:
|
||||||
|
if (aop.ref < 0) {
|
||||||
|
varname = r_str_dup_printf ("arg_%i", -aop.ref);
|
||||||
|
r_anal_var_add (anal, fcn, aop.addr, -aop.ref, R_ANAL_VAR_TYPE_ARG,
|
||||||
|
varname, NULL, 0);
|
||||||
|
} else {
|
||||||
|
varname = r_str_dup_printf ("local_%i", aop.ref);
|
||||||
|
r_anal_var_add (anal, fcn, aop.addr, aop.ref, R_ANAL_VAR_TYPE_LOCAL,
|
||||||
|
varname, NULL, 0);
|
||||||
|
}
|
||||||
|
free (varname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (aop.type) {
|
||||||
|
case R_ANAL_OP_TYPE_CALL:
|
||||||
|
r_list_foreach (fcn->refs, iter, refi) {
|
||||||
|
jump = (ut64*)refi;
|
||||||
|
if (aop.jump == *jump)
|
||||||
|
goto _dup_ref;
|
||||||
|
}
|
||||||
|
if (!(ref = r_anal_ref_new())) {
|
||||||
|
eprintf ("Error: new (ref)\n");
|
||||||
|
return R_ANAL_RET_ERROR;
|
||||||
|
}
|
||||||
|
*ref = aop.jump;
|
||||||
|
r_list_append (fcn->refs, ref);
|
||||||
|
_dup_ref:
|
||||||
|
break;
|
||||||
|
case R_ANAL_OP_TYPE_RET:
|
||||||
|
return R_ANAL_RET_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fcn->size;
|
||||||
|
}
|
27
libr/anal/ref.c
Normal file
27
libr/anal/ref.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* radare - LGPL - Copyright 2010 */
|
||||||
|
/* nibble<.ds@gmail.com> */
|
||||||
|
/* pancake<nopcode.org> */
|
||||||
|
|
||||||
|
#include <r_anal.h>
|
||||||
|
#include <r_util.h>
|
||||||
|
#include <r_list.h>
|
||||||
|
|
||||||
|
R_API RAnalysisRef *r_anal_ref_new() {
|
||||||
|
return r_anal_ref_init (MALLOC_STRUCT (RAnalysisRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RList *r_anal_ref_list_new() {
|
||||||
|
RList *list = r_list_new ();
|
||||||
|
list->free = &r_anal_ref_free;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API void r_anal_ref_free(void *ref) {
|
||||||
|
free (ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_API RAnalysisRef *r_anal_ref_init(RAnalysisRef *ref) {
|
||||||
|
if (ref)
|
||||||
|
*ref = -1;
|
||||||
|
return ref;
|
||||||
|
}
|
@ -6,7 +6,6 @@
|
|||||||
#include <r_util.h>
|
#include <r_util.h>
|
||||||
#include <r_list.h>
|
#include <r_list.h>
|
||||||
|
|
||||||
|
|
||||||
R_API RAnalysisVar *r_anal_var_new() {
|
R_API RAnalysisVar *r_anal_var_new() {
|
||||||
return r_anal_var_init (MALLOC_STRUCT (RAnalysisVar));
|
return r_anal_var_init (MALLOC_STRUCT (RAnalysisVar));
|
||||||
}
|
}
|
||||||
|
@ -198,27 +198,11 @@ typedef struct r_anal_handle_t {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
} RAnalysisHandle;
|
} RAnalysisHandle;
|
||||||
|
|
||||||
/* anal.c */
|
|
||||||
#ifdef R_API
|
#ifdef R_API
|
||||||
|
/* anal.c */
|
||||||
R_API RAnalysis *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 RAnalysisFcn *r_anal_fcn_new();
|
|
||||||
R_API RAnalysisRef *r_anal_ref_new();
|
|
||||||
R_API RList *r_anal_bb_list_new();
|
|
||||||
R_API RList *r_anal_aop_list_new();
|
|
||||||
R_API RList *r_anal_fcn_list_new();
|
|
||||||
R_API RList *r_anal_ref_list_new();
|
|
||||||
R_API RAnalysis *r_anal_free(struct r_anal_t *r);
|
R_API RAnalysis *r_anal_free(struct r_anal_t *r);
|
||||||
R_API void r_anal_aop_free(void *aop);
|
|
||||||
R_API void r_anal_ref_free(void *ref);
|
|
||||||
R_API void r_anal_bb_free(void *bb);
|
|
||||||
R_API void r_anal_fcn_free(void *fcn);
|
|
||||||
R_API RAnalysis *r_anal_init(struct r_anal_t *anal);
|
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 RAnalysisFcn *r_anal_fcn_init(RAnalysisFcn *fcn);
|
|
||||||
R_API RAnalysisRef *r_anal_ref_init(RAnalysisRef *ref);
|
|
||||||
R_API void r_anal_set_user_ptr(struct r_anal_t *anal, void *user);
|
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_add(struct r_anal_t *anal, struct r_anal_handle_t *foo);
|
||||||
R_API int r_anal_list(struct r_anal_t *anal);
|
R_API int r_anal_list(struct r_anal_t *anal);
|
||||||
@ -226,10 +210,37 @@ R_API int r_anal_use(struct r_anal_t *anal, const char *name);
|
|||||||
R_API int r_anal_set_bits(struct r_anal_t *anal, int bits);
|
R_API int r_anal_set_bits(struct r_anal_t *anal, int bits);
|
||||||
R_API int r_anal_set_big_endian(struct r_anal_t *anal, int boolean);
|
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_set_pc(struct r_anal_t *a, ut64 pc);
|
||||||
R_API int r_anal_aop(RAnalysis *anal, RAnalysisAop *aop, ut64 addr,
|
|
||||||
const ut8 *data, int len);
|
/* bb.c */
|
||||||
|
R_API RAnalysisBB *r_anal_bb_new();
|
||||||
|
R_API RList *r_anal_bb_list_new();
|
||||||
|
R_API void r_anal_bb_free(void *bb);
|
||||||
|
R_API RAnalysisBB *r_anal_bb_init(struct r_anal_bb_t *bb);
|
||||||
R_API int r_anal_bb(struct r_anal_t *anal, 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);
|
ut64 addr, ut8 *buf, ut64 len);
|
||||||
|
R_API int r_anal_bb_split(RAnalysis *anal, RAnalysisBB *bb, RList *bbs, ut64 addr);
|
||||||
|
R_API int r_anal_bb_overlap(RAnalysis *anal, RAnalysisBB *bb, RList *bbs);
|
||||||
|
|
||||||
|
/* aop.c */
|
||||||
|
R_API RAnalysisAop *r_anal_aop_new();
|
||||||
|
R_API RList *r_anal_aop_list_new();
|
||||||
|
R_API void r_anal_aop_free(void *aop);
|
||||||
|
R_API RAnalysisAop *r_anal_aop_init(struct r_anal_aop_t *aop);
|
||||||
|
R_API int r_anal_aop(RAnalysis *anal, RAnalysisAop *aop, ut64 addr,
|
||||||
|
const ut8 *data, int len);
|
||||||
|
|
||||||
|
/* fcn.c */
|
||||||
|
R_API RAnalysisFcn *r_anal_fcn_new();
|
||||||
|
R_API RList *r_anal_fcn_list_new();
|
||||||
|
R_API void r_anal_fcn_free(void *fcn);
|
||||||
|
R_API RAnalysisFcn *r_anal_fcn_init(RAnalysisFcn *fcn);
|
||||||
|
R_API int r_anal_fcn(RAnalysis *anal, RAnalysisFcn *fcn, ut64 addr, ut8 *buf, ut64 len);
|
||||||
|
|
||||||
|
/* ref.c */
|
||||||
|
R_API RAnalysisRef *r_anal_ref_new();
|
||||||
|
R_API RList *r_anal_ref_list_new();
|
||||||
|
R_API void r_anal_ref_free(void *ref);
|
||||||
|
R_API RAnalysisRef *r_anal_ref_init(RAnalysisRef *ref);
|
||||||
|
|
||||||
/* var.c */
|
/* var.c */
|
||||||
R_API RAnalysisVar *r_anal_var_new();
|
R_API RAnalysisVar *r_anal_var_new();
|
||||||
@ -260,9 +271,6 @@ R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
|
|||||||
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout);
|
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout);
|
||||||
R_API int r_anal_reflines_str(struct r_anal_t *anal, struct r_anal_refline_t *list,
|
R_API int r_anal_reflines_str(struct r_anal_t *anal, struct r_anal_refline_t *list,
|
||||||
ut64 addr, char *str, int opts);
|
ut64 addr, char *str, int opts);
|
||||||
R_API int r_anal_bb_split(RAnalysis *anal, RAnalysisBB *bb, RList *bbs, ut64 addr);
|
|
||||||
R_API int r_anal_bb_overlap(RAnalysis *anal, RAnalysisBB *bb, RList *bbs);
|
|
||||||
R_API int r_anal_fcn(RAnalysis *anal, RAnalysisFcn *fcn, ut64 addr, ut8 *buf, ut64 len);
|
|
||||||
|
|
||||||
/* plugin pointers */
|
/* plugin pointers */
|
||||||
extern RAnalysisHandle r_anal_plugin_arm;
|
extern RAnalysisHandle r_anal_plugin_arm;
|
||||||
|
Loading…
Reference in New Issue
Block a user