1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/* radare - LGPL - Copyright 2009-2013 - pancake */
#include <r_sign.h>
#include <r_anal.h>
R_LIB_VERSION (r_sign);
R_API RSign *r_sign_new() {
RSign *sig = R_NEW (RSign);
if (sig) {
sig->s_byte = sig->s_anal = 0;
sig->prefix[0] = '\0';
sig->printf = (PrintfCallback) printf;
sig->items = r_list_new ();
sig->items->free = r_sign_item_free;
}
return sig;
}
R_API void r_sign_prefix(RSign *sig, const char *str) {
if (str) {
strncpy (sig->prefix, str, sizeof (sig->prefix)-1);
sig->prefix[sizeof (sig->prefix)-1] = '\0';
} else sig->prefix[0] = '\0';
}
R_API int r_sign_add(RSign *sig, RAnal *anal, int type, const char *name, const char *arg) {
int len, ret = R_FALSE;
char *data, *ptr;
RSignItem *si; // TODO: like in r_search.. we need r_sign_item_new ()
// TODO: but..we need to use a pool here..
if (!name || !arg || !anal)
return R_FALSE;
if (!(si = R_NEW (RSignItem)))
return R_FALSE;
si->type = type;
snprintf (si->name, sizeof (si->name), "%s.%c.%s",
*sig->prefix?sig->prefix:"sign", type, name);
switch (type) {
case R_SIGN_FUNC: // function signature
// FUNC FORMAT [addr] [function-signature]
ptr = strchr (arg, ' ');
if (ptr) {
// TODO. matching must be done by sym/flag/function name
// sig->addr =
}
sig->s_func++;
r_list_append (sig->items, si);
break;
case R_SIGN_HEAD: // function prefix (push ebp..)
case R_SIGN_BYTE: // function mask
if (!(data = r_anal_strmask (anal, arg))) {
free (si);
break;
}
len = strlen (data)+1;
si->bytes = (ut8 *)malloc (len);
si->mask = (ut8 *)malloc (len);
if (si->bytes == NULL || si->mask == NULL) {
eprintf ("Cannot malloc\n");
free (si->mask);
free (si->bytes);
free (si);
break;
}
si->size = r_hex_str2binmask (data, si->bytes, si->mask);
if (si->size<1) {
free (si->bytes);
free (si->mask);
free (si);
} else {
r_list_append (sig->items, si);
if (type==R_SIGN_HEAD)
sig->s_head++;
else if (type==R_SIGN_BYTE)
sig->s_byte++;
}
free (data);
break;
default:
case R_SIGN_ANAL:
eprintf ("r_sign_add: TODO. unsupported signature type %d\n", type);
break;
}
return ret;
}
R_API void r_sign_list(RSign *sig, int rad) {
if (rad) {
int i;
RListIter *iter;
RSignItem *si;
if (!r_list_empty (sig->items))
sig->printf ("zp-\n");
r_list_foreach (sig->items, iter, si) {
sig->printf ("z%c %s ", si->type, si->name);
// TODO: show mask..
for (i=0; i<si->size; i++)
sig->printf ("%02x", si->bytes[i]);
sig->printf ("\n");
}
} else {
sig->printf ("Loaded %d signatures\n", sig->s_byte + sig->s_anal);
sig->printf (" %d byte signatures\n", sig->s_byte);
sig->printf (" %d head signatures\n", sig->s_head);
sig->printf (" %d func signatures\n", sig->s_func);
}
}
R_API void r_sign_reset(RSign *sig) {
r_list_free (sig->items);
sig->items = r_list_new ();
sig->s_anal = sig->s_byte = sig->s_head = sig->s_func = 0;
}
R_API RSign *r_sign_free(RSign *sig) {
if (!sig) return NULL;
r_list_free (sig->items);
free (sig);
return NULL;
}
R_API void r_sign_item_free(void *_item) {
RSignItem *item = _item;
free (item->bytes);
free (item->mask);
free (item);
}
R_API RSignItem *r_sign_check(RSign *sig, const ut8 *buf, int len) {
RListIter *iter;
RSignItem *si;
r_list_foreach (sig->items, iter, si) {
if (si->type == R_SIGN_BYTE) {
int l = (len>si->size)?si->size:len;
if (!r_mem_cmp_mask (buf, si->bytes, si->mask, l))
return si;
}
}
return NULL;
}
|