2010-01-31 01:30:59 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2010 */
|
2009-03-31 22:32:26 +00:00
|
|
|
/* nibble<.ds@gmail.com> */
|
|
|
|
/* pancake<nopcode.org> */
|
2009-02-06 17:22:27 +00:00
|
|
|
|
2009-02-15 23:57:03 +00:00
|
|
|
#include <r_anal.h>
|
|
|
|
#include <r_util.h>
|
2010-02-26 12:08:42 +00:00
|
|
|
#include <r_list.h>
|
2010-02-28 19:07:36 +00:00
|
|
|
#include "../config.h"
|
|
|
|
|
2010-05-25 23:42:22 +00:00
|
|
|
static RAnalPlugin *anal_static_plugins[] =
|
2010-02-28 19:07:36 +00:00
|
|
|
{ R_ANAL_STATIC_PLUGINS };
|
2009-02-15 23:57:03 +00:00
|
|
|
|
2010-03-19 11:00:04 +00:00
|
|
|
static RAnalVarType anal_default_vartypes[] =
|
2010-03-11 18:52:05 +00:00
|
|
|
{{ "char", "b", 1 },
|
|
|
|
{ "byte", "b", 1 },
|
|
|
|
{ "int", "d", 4 },
|
|
|
|
{ "int32", "d", 4 },
|
|
|
|
{ "dword", "x", 4 },
|
|
|
|
{ "float", "f", 4 },
|
|
|
|
{ NULL, NULL, 0 }};
|
|
|
|
|
2010-03-19 11:00:04 +00:00
|
|
|
R_API RAnal *r_anal_new() {
|
2010-02-28 19:07:36 +00:00
|
|
|
int i;
|
2010-06-04 21:47:35 +00:00
|
|
|
RAnalPlugin *static_plugin;
|
|
|
|
RAnal *anal = R_NEW (RAnal);
|
2010-01-31 01:30:59 +00:00
|
|
|
if (anal) {
|
2010-03-19 11:00:04 +00:00
|
|
|
memset (anal, 0, sizeof (RAnal));
|
2010-03-07 13:00:26 +00:00
|
|
|
anal->bbs = r_anal_bb_list_new ();
|
|
|
|
anal->fcns = r_anal_fcn_list_new ();
|
2010-03-11 18:52:05 +00:00
|
|
|
anal->vartypes = r_anal_var_type_list_new ();
|
2010-01-31 01:30:59 +00:00
|
|
|
r_anal_set_bits (anal, 32);
|
|
|
|
r_anal_set_big_endian (anal, R_FALSE);
|
|
|
|
INIT_LIST_HEAD (&anal->anals);
|
2010-05-28 00:44:51 +00:00
|
|
|
for (i=0; anal_static_plugins[i]; i++) {
|
|
|
|
static_plugin = R_NEW (RAnalPlugin);
|
|
|
|
memcpy (static_plugin, anal_static_plugins[i], sizeof (RAnalPlugin));
|
|
|
|
r_anal_add (anal, static_plugin);
|
|
|
|
}
|
2010-03-11 18:52:05 +00:00
|
|
|
for (i=0; anal_default_vartypes[i].name; i++)
|
2010-03-12 01:45:24 +00:00
|
|
|
r_anal_var_type_add (anal, anal_default_vartypes[i].name,
|
2010-03-11 18:52:05 +00:00
|
|
|
anal_default_vartypes[i].size, anal_default_vartypes[i].fmt);
|
2010-01-31 01:30:59 +00:00
|
|
|
}
|
|
|
|
return anal;
|
2009-02-06 17:22:27 +00:00
|
|
|
}
|
|
|
|
|
2010-05-20 15:40:58 +00:00
|
|
|
R_API RAnal *r_anal_free(RAnal *anal) {
|
|
|
|
if (anal) {
|
|
|
|
/* TODO: Free a->anals here */
|
|
|
|
if (anal->bbs)
|
2010-06-14 16:52:49 +00:00
|
|
|
r_list_free (anal->bbs);
|
2010-05-20 15:40:58 +00:00
|
|
|
if (anal->fcns)
|
2010-06-14 16:52:49 +00:00
|
|
|
r_list_free (anal->fcns);
|
2010-05-20 15:40:58 +00:00
|
|
|
if (anal->vartypes)
|
2010-06-14 16:52:49 +00:00
|
|
|
r_list_free (anal->vartypes);
|
2010-05-20 15:40:58 +00:00
|
|
|
}
|
|
|
|
free (anal);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-03-19 11:00:04 +00:00
|
|
|
R_API void r_anal_set_user_ptr(RAnal *anal, void *user) {
|
2009-02-15 23:57:03 +00:00
|
|
|
anal->user = user;
|
2009-02-06 17:22:27 +00:00
|
|
|
}
|
|
|
|
|
2010-05-25 23:42:22 +00:00
|
|
|
R_API int r_anal_add(RAnal *anal, RAnalPlugin *foo) {
|
2009-02-15 23:57:03 +00:00
|
|
|
if (foo->init)
|
|
|
|
foo->init(anal->user);
|
|
|
|
list_add_tail(&(foo->list), &(anal->anals));
|
2009-02-06 17:22:27 +00:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
2009-02-08 23:19:06 +00:00
|
|
|
|
2009-10-12 15:41:52 +00:00
|
|
|
// TODO: Must be deprecated
|
2010-03-19 11:00:04 +00:00
|
|
|
R_API int r_anal_list(RAnal *anal) {
|
2009-02-15 23:57:03 +00:00
|
|
|
struct list_head *pos;
|
|
|
|
list_for_each_prev(pos, &anal->anals) {
|
2010-05-25 23:42:22 +00:00
|
|
|
RAnalPlugin *h = list_entry(pos, RAnalPlugin, list);
|
2010-02-02 10:09:52 +00:00
|
|
|
printf (" %s: %s\n", h->name, h->desc);
|
2009-02-15 23:57:03 +00:00
|
|
|
}
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-19 11:00:04 +00:00
|
|
|
R_API int r_anal_use(RAnal *anal, const char *name) {
|
2009-02-15 23:57:03 +00:00
|
|
|
struct list_head *pos;
|
2010-02-02 10:09:52 +00:00
|
|
|
list_for_each_prev (pos, &anal->anals) {
|
2010-05-25 23:42:22 +00:00
|
|
|
RAnalPlugin *h = list_entry(pos, RAnalPlugin, list);
|
2010-02-02 10:09:52 +00:00
|
|
|
if (!strcmp (h->name, name)) {
|
2009-02-15 23:57:03 +00:00
|
|
|
anal->cur = h;
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-03-19 11:00:04 +00:00
|
|
|
R_API int r_anal_set_bits(RAnal *anal, int bits) {
|
2009-02-15 23:57:03 +00:00
|
|
|
switch (bits) {
|
2009-08-14 00:37:18 +00:00
|
|
|
case 8:
|
2009-02-15 23:57:03 +00:00
|
|
|
case 16:
|
|
|
|
case 32:
|
|
|
|
case 64:
|
|
|
|
anal->bits = bits;
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
2009-09-25 02:04:51 +00:00
|
|
|
return R_FALSE;
|
2009-02-15 23:57:03 +00:00
|
|
|
}
|
|
|
|
|
2010-03-19 11:00:04 +00:00
|
|
|
R_API int r_anal_set_big_endian(RAnal *anal, int bigend) {
|
2009-09-09 00:35:00 +00:00
|
|
|
anal->big_endian = bigend;
|
2009-02-15 23:57:03 +00:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
2010-05-16 12:04:08 +00:00
|
|
|
|
|
|
|
R_API char *r_anal_strmask (RAnal *anal, const char *data) {
|
2010-05-20 23:46:26 +00:00
|
|
|
RAnalOp *aop;
|
2010-05-16 12:04:08 +00:00
|
|
|
ut8 *buf;
|
|
|
|
char *ret = NULL;
|
|
|
|
int oplen, len, idx = 0;
|
|
|
|
|
|
|
|
ret = strdup (data);
|
|
|
|
buf = malloc (strlen (data));
|
|
|
|
aop = r_anal_aop_new ();
|
|
|
|
if (aop == NULL || ret == NULL || buf == NULL) {
|
|
|
|
free (aop);
|
|
|
|
free (buf);
|
|
|
|
free (ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
len = r_hex_str2bin (data, buf);
|
|
|
|
while (idx < len) {
|
|
|
|
if ((oplen = r_anal_aop (anal, aop, 0, buf+idx, len-idx)) == 0)
|
|
|
|
break;
|
|
|
|
switch (aop->type) {
|
|
|
|
case R_ANAL_OP_TYPE_CALL:
|
|
|
|
case R_ANAL_OP_TYPE_CJMP:
|
|
|
|
case R_ANAL_OP_TYPE_JMP:
|
|
|
|
if (aop->nopcode != 0)
|
|
|
|
memset (ret+(idx+aop->nopcode)*2, '.', (oplen-aop->nopcode)*2);
|
|
|
|
}
|
|
|
|
idx += oplen;
|
|
|
|
}
|
|
|
|
free (aop);
|
|
|
|
free (buf);
|
|
|
|
return ret;
|
|
|
|
}
|