2017-03-07 23:20:48 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2017 - pancake, nibble */
|
2016-09-04 13:43:36 +02:00
|
|
|
|
2017-03-13 00:41:53 +00:00
|
|
|
#include <r_core.h>
|
|
|
|
#include <r_anal.h>
|
|
|
|
#include <r_sign.h>
|
|
|
|
#include <r_list.h>
|
|
|
|
#include <r_cons.h>
|
2012-02-27 02:40:27 +01:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
static bool zignAddFcn(RCore *core, RAnalFunction *fcn, int type, int minzlen, int maxzlen) {
|
|
|
|
int fcnlen = 0, len = 0;
|
|
|
|
ut8 *buf = NULL, *mask = NULL;
|
|
|
|
bool retval = true;
|
2016-09-04 13:54:37 +02:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
fcnlen = r_anal_fcn_realsize (fcn);
|
2016-08-21 08:33:21 +02:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
if (fcnlen < minzlen) {
|
2017-03-12 00:57:29 +00:00
|
|
|
eprintf ("warn: omitting %s zignature is too small. Length is %d. Check zign.min.\n",
|
|
|
|
fcn->name, fcnlen);
|
2017-03-04 19:19:01 +00:00
|
|
|
retval = false;
|
|
|
|
goto exit_func;
|
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
len = R_MIN (fcnlen, maxzlen);
|
|
|
|
|
|
|
|
buf = malloc (len);
|
|
|
|
|
|
|
|
if (r_io_read_at (core->io, fcn->addr, buf, len) != len) {
|
|
|
|
eprintf ("error: cannot read at 0x%08"PFMT64x"\n", fcn->addr);
|
2017-03-04 19:19:01 +00:00
|
|
|
retval = false;
|
|
|
|
goto exit_func;
|
2016-09-25 21:22:20 +02:00
|
|
|
}
|
2017-03-04 19:19:01 +00:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
switch (type) {
|
|
|
|
case R_SIGN_EXACT:
|
|
|
|
mask = malloc (len);
|
|
|
|
memset (mask, 0xff, len);
|
|
|
|
retval = r_sign_add (core->anal, R_SIGN_EXACT, fcn->name, len, buf, mask);
|
|
|
|
break;
|
|
|
|
case R_SIGN_ANAL:
|
|
|
|
retval = r_sign_add_anal (core->anal, fcn->name, len, buf);
|
|
|
|
break;
|
2017-03-04 19:19:01 +00:00
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
exit_func:
|
|
|
|
free (buf);
|
|
|
|
free (mask);
|
2017-03-04 19:19:01 +00:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
return retval;
|
|
|
|
}
|
2017-03-04 19:19:01 +00:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
static bool zignAddHex(RCore *core, const char *name, int type, const char *hexbytes) {
|
|
|
|
ut8 *mask = NULL, *bytes = NULL;
|
|
|
|
int size = 0, blen = 0;
|
|
|
|
bool retval = true;
|
2017-03-04 19:19:01 +00:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
blen = strlen (hexbytes) + 4;
|
|
|
|
bytes = malloc (blen);
|
|
|
|
mask = malloc (blen);
|
2017-03-12 02:08:58 +00:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
size = r_hex_str2binmask (hexbytes, bytes, mask);
|
2017-03-12 02:08:58 +00:00
|
|
|
if (size <= 0) {
|
|
|
|
retval = false;
|
|
|
|
goto exit_func;
|
|
|
|
}
|
2017-03-04 19:19:01 +00:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
switch (type) {
|
|
|
|
case R_SIGN_EXACT:
|
|
|
|
retval = r_sign_add (core->anal, type, name, size, bytes, mask);
|
|
|
|
break;
|
|
|
|
case R_SIGN_ANAL:
|
|
|
|
retval = r_sign_add_anal (core->anal, name, size, bytes);
|
|
|
|
break;
|
|
|
|
}
|
2017-03-04 19:19:01 +00:00
|
|
|
|
2017-03-12 02:08:58 +00:00
|
|
|
exit_func:
|
2017-03-07 23:20:48 +00:00
|
|
|
free (bytes);
|
|
|
|
free (mask);
|
2017-03-04 19:19:01 +00:00
|
|
|
|
|
|
|
return retval;
|
2016-09-25 21:22:20 +02:00
|
|
|
}
|
|
|
|
|
2017-03-13 01:14:51 +00:00
|
|
|
static int zignAddBytes(void *data, const char *input, int type) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-07 23:20:48 +00:00
|
|
|
|
|
|
|
switch (*input) {
|
|
|
|
case ' ':
|
|
|
|
{
|
|
|
|
const char *name = NULL, *hexbytes = NULL;
|
|
|
|
char *args = NULL;
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
args = r_str_new (input + 1);
|
|
|
|
n = r_str_word_set0(args);
|
|
|
|
|
|
|
|
if (n != 2) {
|
2017-03-13 01:14:51 +00:00
|
|
|
eprintf ("usage: za%s name bytes\n", type == R_SIGN_ANAL? "a": "e");
|
2017-03-07 23:20:48 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = r_str_word_get0(args, 0);
|
|
|
|
hexbytes = r_str_word_get0(args, 1);
|
|
|
|
|
2017-03-13 01:14:51 +00:00
|
|
|
if (!zignAddHex (core, name, type, hexbytes)) {
|
2017-03-07 23:20:48 +00:00
|
|
|
eprintf ("error: cannot add zignature\n");
|
|
|
|
}
|
2016-08-21 08:33:21 +02:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
free (args);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
{
|
|
|
|
RAnalFunction *fcni = NULL;
|
|
|
|
RListIter *iter = NULL;
|
|
|
|
const char *name = NULL;
|
|
|
|
int minzlen = r_config_get_i (core->config, "zign.min");
|
|
|
|
int maxzlen = r_config_get_i (core->config, "zign.max");
|
|
|
|
|
|
|
|
if (input[1] != ' ') {
|
2017-03-13 01:14:51 +00:00
|
|
|
eprintf ("usage: za%sf name\n", type == R_SIGN_ANAL? "a": "e");
|
2017-03-07 23:20:48 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = input + 2;
|
|
|
|
|
|
|
|
r_cons_break_push (NULL, NULL);
|
|
|
|
r_list_foreach (core->anal->fcns, iter, fcni) {
|
|
|
|
if (r_cons_is_breaked ()) {
|
2016-09-04 13:54:37 +02:00
|
|
|
break;
|
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
if (r_str_cmp (name, fcni->name, strlen (name))) {
|
2017-03-13 01:14:51 +00:00
|
|
|
if (!zignAddFcn (core, fcni, type, minzlen, maxzlen)) {
|
2017-03-07 23:20:48 +00:00
|
|
|
eprintf ("error: could not add zignature for fcn %s\n", fcni->name);
|
|
|
|
}
|
|
|
|
break;
|
2016-09-04 13:54:37 +02:00
|
|
|
}
|
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
r_cons_break_pop ();
|
2016-09-04 13:54:37 +02:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
break;
|
2017-03-13 01:14:51 +00:00
|
|
|
case 'F':
|
2017-03-07 23:20:48 +00:00
|
|
|
{
|
|
|
|
RAnalFunction *fcni = NULL;
|
|
|
|
RListIter *iter = NULL;
|
|
|
|
int minzlen = r_config_get_i (core->config, "zign.min");
|
|
|
|
int maxzlen = r_config_get_i (core->config, "zign.max");
|
|
|
|
|
|
|
|
r_cons_break_push (NULL, NULL);
|
|
|
|
r_list_foreach (core->anal->fcns, iter, fcni) {
|
|
|
|
if (r_cons_is_breaked ()) {
|
|
|
|
break;
|
|
|
|
}
|
2017-03-13 01:14:51 +00:00
|
|
|
if (!zignAddFcn (core, fcni, type, minzlen, maxzlen)) {
|
|
|
|
eprintf ("error: could not add zignature for fcn %s\n", fcni->name);
|
2017-03-07 23:20:48 +00:00
|
|
|
}
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
r_cons_break_pop ();
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
{
|
2017-03-13 01:14:51 +00:00
|
|
|
if (type == R_SIGN_ANAL) {
|
|
|
|
const char *help_msg[] = {
|
|
|
|
"Usage:", "zaa[fF] [args] ", "# Create anal zignature",
|
|
|
|
"zaa ", "name bytes", "create anal zignature",
|
|
|
|
"zaaf ", "[name]", "create anal zignature for function (use function name if name is not given)",
|
2017-03-13 01:48:23 +00:00
|
|
|
"zaaF ", "", "generate anal zignatures for all functions",
|
2017-03-13 01:14:51 +00:00
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
|
|
|
} else {
|
|
|
|
const char *help_msg[] = {
|
|
|
|
"Usage:", "zae[fF] [args] ", "# Create anal zignature",
|
|
|
|
"zae ", "name bytes", "create anal zignature",
|
|
|
|
"zaef ", "[name]", "create anal zignature for function (use function name if name is not given)",
|
2017-03-13 01:48:23 +00:00
|
|
|
"zaeF ", "", "generate anal zignatures for all functions",
|
2017-03-13 01:14:51 +00:00
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2017-03-13 01:14:51 +00:00
|
|
|
eprintf ("usage: za%s[f] [args]\n", type == R_SIGN_ANAL? "a": "e");
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
return true;
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
static int zignAdd(void *data, const char *input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-07 23:20:48 +00:00
|
|
|
|
|
|
|
switch (*input) {
|
|
|
|
case 'a':
|
2017-03-13 01:14:51 +00:00
|
|
|
return zignAddBytes (data, input + 1, R_SIGN_ANAL);
|
2017-03-07 23:20:48 +00:00
|
|
|
case 'e':
|
2017-03-13 01:14:51 +00:00
|
|
|
return zignAddBytes (data, input + 1, R_SIGN_EXACT);
|
2017-03-07 23:20:48 +00:00
|
|
|
case '?':
|
|
|
|
{
|
|
|
|
const char *help_msg[] = {
|
|
|
|
"Usage:", "za[aemg] [args] ", "# Add zignature",
|
|
|
|
"zaa", "[?]", "add anal zignature",
|
|
|
|
"zae", "[?]", "add exact-match zignature",
|
2017-03-12 19:32:20 +00:00
|
|
|
"zam ", "name params", "add metric zignature (e.g. zm foo bbs=10 calls=printf,exit)",
|
2017-03-07 23:20:48 +00:00
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
break;
|
|
|
|
default:
|
2017-03-12 12:19:00 +00:00
|
|
|
eprintf ("usage: za[aemg] [args]\n");
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int zignLoad(void *data, const char *input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-04 10:21:06 +01:00
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
switch (*input) {
|
|
|
|
case '?':
|
2017-03-12 12:19:00 +00:00
|
|
|
{
|
|
|
|
const char *help_msg[] = {
|
|
|
|
"Usage:", "zo[dz] [args] ", "# Load zignatures from file",
|
|
|
|
"zo ", "filename", "load zignatures from file",
|
|
|
|
"zod ", "filename", "load zinatures from sdb file",
|
|
|
|
"zoz ", "filename", "load zinagures from gzip file",
|
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
|
|
|
}
|
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
default:
|
2017-03-12 12:19:00 +00:00
|
|
|
eprintf ("usage: zo[dz] [args]\n");
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
return true;
|
2017-03-04 10:21:06 +01:00
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
static int zignSpace(void *data, const char *input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-07 23:20:48 +00:00
|
|
|
RSpaces *zs = &core->anal->zign_spaces;
|
2012-02-27 02:40:27 +01:00
|
|
|
|
|
|
|
switch (*input) {
|
2017-03-07 23:20:48 +00:00
|
|
|
case '?':
|
|
|
|
{
|
|
|
|
const char *help_msg[] = {
|
|
|
|
"Usage:", "zs[+-*] [namespace] ", "# Manage zignspaces",
|
|
|
|
"zs", "", "display zignspaces",
|
|
|
|
"zs ", "zignspace", "select zignspace",
|
|
|
|
"zs ", "*", "select all zignspaces",
|
|
|
|
"zs-", "zignspace", "delete zignspace",
|
|
|
|
"zs-", "*", "delete all zignspaces",
|
|
|
|
"zs+", "zignspace", "push previous zignspace and set",
|
|
|
|
"zs-", "", "pop to the previous zignspace",
|
|
|
|
"zsr ", "newname", "rename selected zignspace",
|
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
2016-11-20 19:20:14 +01:00
|
|
|
}
|
2015-05-19 10:17:52 +02:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case '+':
|
|
|
|
if (input[1] != '\x00') {
|
|
|
|
r_space_push (zs, input + 1);
|
2016-11-20 19:20:14 +01:00
|
|
|
} else {
|
2017-03-07 23:20:48 +00:00
|
|
|
eprintf ("Usage: zs+zignspace\n");
|
2016-11-20 19:20:14 +01:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case 'r':
|
|
|
|
if (input[1] == ' ' && input[2] != '\x00') {
|
|
|
|
r_space_rename (zs, NULL, input + 2);
|
2016-11-20 19:20:14 +01:00
|
|
|
} else {
|
2017-03-07 23:20:48 +00:00
|
|
|
eprintf ("Usage: zsr newname\n");
|
2016-11-20 19:20:14 +01:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case '-':
|
|
|
|
if (input[1] == '\x00') {
|
|
|
|
r_space_pop (zs);
|
|
|
|
} else if (input[1] == '*') {
|
|
|
|
r_space_unset (zs, NULL);
|
2017-03-05 10:07:52 +00:00
|
|
|
} else {
|
2017-03-07 23:20:48 +00:00
|
|
|
r_space_unset (zs, input+1);
|
2016-05-02 22:52:41 -04:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case 'j':
|
|
|
|
case '*':
|
|
|
|
case '\0':
|
|
|
|
r_space_list (zs, input[0]);
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case ' ':
|
|
|
|
if (input[1] != '\x00') {
|
|
|
|
r_space_set (zs, input + 1);
|
2015-10-22 04:48:56 +02:00
|
|
|
} else {
|
2017-03-07 23:20:48 +00:00
|
|
|
eprintf ("Usage: zs zignspace\n");
|
2014-06-22 21:23:44 +02:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
default:
|
2012-02-27 02:40:27 +01:00
|
|
|
{
|
2017-03-07 23:20:48 +00:00
|
|
|
int i, count = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
|
|
|
|
if (!zs->spaces[i]) {
|
|
|
|
continue;
|
2016-09-25 21:22:20 +02:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
r_cons_printf ("%02d %c %s\n", count,
|
|
|
|
(i == zs->space_idx)? '*': ' ',
|
|
|
|
zs->spaces[i]);
|
|
|
|
count++;
|
2015-10-14 16:55:55 +02:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int zignFlirt(void *data, const char *input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-07 23:20:48 +00:00
|
|
|
|
|
|
|
switch (*input) {
|
|
|
|
case '?':
|
|
|
|
{
|
|
|
|
const char *help_msg[] = {
|
|
|
|
"Usage:", "zf[dsz] filename ", "# Manage FLIRT signatures",
|
|
|
|
"zfd ", "filename", "open FLIRT file and dump",
|
|
|
|
"zfs ", "filename", "open FLIRT file and scan",
|
|
|
|
"zfz ", "filename", "open FLIRT file and get sig commands (zfz flirt_file > zignatures.sig)",
|
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
2016-09-04 13:54:37 +02:00
|
|
|
}
|
2016-09-04 13:43:36 +02:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
default:
|
2017-03-12 12:19:00 +00:00
|
|
|
eprintf ("usage: zf[dsz] filename\n");
|
2017-03-07 23:20:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-12 18:13:11 +00:00
|
|
|
struct ctxSearchCB {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core;
|
|
|
|
bool rad;
|
|
|
|
};
|
|
|
|
|
2017-03-13 00:41:53 +00:00
|
|
|
static int zignSearchHitCB(RSearchKeyword *kw, RSignItem *it, ut64 addr, void *user) {
|
2017-03-12 19:32:20 +00:00
|
|
|
struct ctxSearchCB *ctx = (struct ctxSearchCB *) user;
|
2017-03-13 00:41:53 +00:00
|
|
|
RConfig *cfg = ctx->core->config;
|
|
|
|
RAnal *a = ctx->core->anal;
|
|
|
|
const char *zign_prefix = r_config_get (cfg, "zign.prefix");
|
2017-03-12 19:32:20 +00:00
|
|
|
char *name;
|
|
|
|
|
2017-03-13 00:41:53 +00:00
|
|
|
if (it->space == -1) {
|
|
|
|
name = r_str_newf ("%s.%s_%d", zign_prefix, it->name, kw->count);
|
2017-03-12 19:32:20 +00:00
|
|
|
} else {
|
2017-03-13 00:41:53 +00:00
|
|
|
name = r_str_newf ("%s.%s.%s_%d", zign_prefix,
|
|
|
|
a->zign_spaces.spaces[it->space], it->name, kw->count);
|
2017-03-12 19:32:20 +00:00
|
|
|
}
|
2017-03-12 18:13:11 +00:00
|
|
|
|
2017-03-13 00:41:53 +00:00
|
|
|
if (ctx->rad) {
|
|
|
|
r_cons_printf ("f %s %d @ 0x%08"PFMT64x"\n", name, kw->keyword_length, addr);
|
2017-03-12 12:44:11 +00:00
|
|
|
} else {
|
2017-03-13 00:41:53 +00:00
|
|
|
r_flag_set(ctx->core->flags, name, addr, kw->keyword_length);
|
2017-03-12 12:44:11 +00:00
|
|
|
}
|
|
|
|
|
2017-03-13 00:41:53 +00:00
|
|
|
free(name);
|
2017-03-12 12:19:00 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-03-12 18:13:11 +00:00
|
|
|
static bool zignSearchRange(RCore *core, ut64 from, ut64 to, bool rad) {
|
2017-03-13 00:41:53 +00:00
|
|
|
RSignSearch *ss;
|
2017-03-12 18:13:11 +00:00
|
|
|
ut8 *buf = malloc (core->blocksize);
|
|
|
|
ut64 at;
|
|
|
|
int rlen;
|
|
|
|
bool retval = true;
|
2017-03-13 00:41:53 +00:00
|
|
|
struct ctxSearchCB ctx = { core, rad };
|
2017-03-12 18:13:11 +00:00
|
|
|
|
2017-03-13 00:41:53 +00:00
|
|
|
ss = r_sign_search_new ();
|
2017-03-13 01:14:51 +00:00
|
|
|
r_sign_search_init (core->anal, ss, zignSearchHitCB, &ctx);
|
2017-03-12 18:13:11 +00:00
|
|
|
|
2017-03-12 19:32:20 +00:00
|
|
|
r_cons_break_push (NULL, NULL);
|
2017-03-12 18:13:11 +00:00
|
|
|
for (at = from; at < to; at += core->blocksize) {
|
2017-03-12 19:32:20 +00:00
|
|
|
if (r_cons_is_breaked ()) {
|
2017-03-12 18:13:11 +00:00
|
|
|
retval = false;
|
2017-03-12 19:32:20 +00:00
|
|
|
break;
|
2017-03-12 18:13:11 +00:00
|
|
|
}
|
|
|
|
rlen = R_MIN (core->blocksize, to - at);
|
|
|
|
if (!r_io_read_at (core->io, at, buf, rlen)) {
|
|
|
|
retval = false;
|
2017-03-12 19:32:20 +00:00
|
|
|
break;
|
2017-03-12 18:13:11 +00:00
|
|
|
}
|
2017-03-13 00:41:53 +00:00
|
|
|
if (r_sign_search_update (core->anal, ss, &at, buf, rlen) == -1) {
|
2017-03-12 18:13:11 +00:00
|
|
|
eprintf ("search: update read error at 0x%08"PFMT64x"\n", at);
|
|
|
|
retval = false;
|
2017-03-12 19:32:20 +00:00
|
|
|
break;
|
2017-03-12 18:13:11 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-12 19:32:20 +00:00
|
|
|
r_cons_break_pop ();
|
2017-03-12 18:13:11 +00:00
|
|
|
|
|
|
|
free (buf);
|
2017-03-13 00:41:53 +00:00
|
|
|
r_sign_search_free (ss);
|
2017-03-12 18:13:11 +00:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2017-03-12 12:19:00 +00:00
|
|
|
static bool zignDoSearch(RCore *core, ut64 from, ut64 to, bool rad) {
|
|
|
|
RList *list;
|
|
|
|
RListIter *iter;
|
|
|
|
RIOMap *map;
|
|
|
|
bool search_all = false;
|
|
|
|
bool retval = true;
|
2017-03-12 19:32:20 +00:00
|
|
|
const char *zign_prefix = r_config_get (core->config, "zign.prefix");
|
|
|
|
|
|
|
|
if (rad) {
|
|
|
|
r_cons_printf ("fs+%s\n", zign_prefix);
|
|
|
|
} else {
|
|
|
|
if (!r_flag_space_push (core->flags, zign_prefix)) {
|
|
|
|
eprintf ("error: cannot create flagspace\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-03-12 12:19:00 +00:00
|
|
|
|
|
|
|
if (from == 0 && to == 0) {
|
|
|
|
search_all = true;
|
|
|
|
} else if (to <= from) {
|
|
|
|
eprintf ("error: invalid rage 0x%08"PFMT64x"-0x%08"PFMT64x"\n", from, to);
|
2017-03-12 19:32:20 +00:00
|
|
|
retval = false;
|
|
|
|
goto exit_func;
|
2017-03-12 12:19:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (search_all) {
|
|
|
|
list = r_core_get_boundaries_ok (core);
|
|
|
|
if (!list) {
|
2017-03-12 19:32:20 +00:00
|
|
|
eprintf ("error: invalid map boundaries\n");
|
|
|
|
retval = false;
|
|
|
|
goto exit_func;
|
2017-03-12 12:19:00 +00:00
|
|
|
}
|
|
|
|
r_list_foreach (list, iter, map) {
|
2017-03-12 18:13:11 +00:00
|
|
|
eprintf ("[+] searching 0x%08"PFMT64x" - 0x%08"PFMT64x"\n", map->from, map->to);
|
|
|
|
retval &= zignSearchRange (core, map->from, map->to, rad);
|
2017-03-12 12:19:00 +00:00
|
|
|
}
|
|
|
|
r_list_free (list);
|
|
|
|
} else {
|
2017-03-12 18:13:11 +00:00
|
|
|
eprintf ("[+] searching 0x%08"PFMT64x" - 0x%08"PFMT64x"\n", from, to);
|
|
|
|
retval = zignSearchRange (core, from, to, rad);
|
2017-03-12 12:19:00 +00:00
|
|
|
}
|
|
|
|
|
2017-03-12 19:32:20 +00:00
|
|
|
exit_func:
|
|
|
|
if (rad) {
|
|
|
|
r_cons_printf ("fs-\n");
|
|
|
|
} else {
|
|
|
|
r_flag_space_pop (core->flags);
|
|
|
|
}
|
|
|
|
|
2017-03-12 12:19:00 +00:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2017-03-12 01:55:59 +00:00
|
|
|
static int zignSearch(void *data, const char *input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-12 01:55:59 +00:00
|
|
|
|
|
|
|
switch (*input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
case '\x00':
|
2017-03-12 01:55:59 +00:00
|
|
|
case ' ':
|
|
|
|
case '*':
|
2017-03-12 12:19:00 +00:00
|
|
|
{
|
|
|
|
ut64 from = 0, to = 0;
|
|
|
|
char *args = NULL;
|
|
|
|
int n = 0;
|
|
|
|
bool retval = true;
|
|
|
|
|
|
|
|
if (input[0]) {
|
|
|
|
args = r_str_new (input + 1);
|
2017-03-12 12:44:11 +00:00
|
|
|
r_str_trim_head (args);
|
2017-03-12 12:19:00 +00:00
|
|
|
n = r_str_word_set0(args);
|
|
|
|
} else {
|
|
|
|
n = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (n) {
|
|
|
|
case 2:
|
|
|
|
from = r_num_math (core->num, r_str_word_get0(args, 0));
|
|
|
|
to = r_num_math (core->num, r_str_word_get0(args, 1));
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
from = core->offset;
|
|
|
|
to = r_num_math (core->num, r_str_word_get0(args, 0));
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
default:
|
2017-03-13 01:48:23 +00:00
|
|
|
eprintf ("usage: z/[*] [from] [to]\n");
|
2017-03-12 12:19:00 +00:00
|
|
|
retval = false;
|
|
|
|
goto exit_case;
|
|
|
|
}
|
|
|
|
|
2017-03-13 01:14:51 +00:00
|
|
|
retval = zignDoSearch (core, from, to, input[0] == '*');
|
2017-03-12 12:19:00 +00:00
|
|
|
|
|
|
|
exit_case:
|
|
|
|
free (args);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
2017-03-12 01:55:59 +00:00
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
{
|
|
|
|
const char *help_msg[] = {
|
2017-03-12 12:19:00 +00:00
|
|
|
"Usage:", "z/[*] [from] [to] ", "# Search signatures",
|
|
|
|
"z/ ", "[from] [to]", "search zignatures on range and flag matches",
|
|
|
|
"z/* ", "[from] [to]", "search zignatures on range and output radare commands",
|
2017-03-12 01:55:59 +00:00
|
|
|
NULL};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2017-03-12 12:19:00 +00:00
|
|
|
eprintf ("usage: z/[*] [from] [to]\n");
|
2017-03-12 01:55:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-07 23:20:48 +00:00
|
|
|
static int cmd_zign(void *data, const char *input) {
|
2017-03-12 12:19:00 +00:00
|
|
|
RCore *core = (RCore *) data;
|
2017-03-07 23:20:48 +00:00
|
|
|
|
|
|
|
switch (*input) {
|
2012-02-27 02:40:27 +01:00
|
|
|
case '\0':
|
|
|
|
case '*':
|
2015-10-14 17:50:17 +02:00
|
|
|
case 'j':
|
2017-03-07 23:20:48 +00:00
|
|
|
r_sign_list (core->anal, input[0]);
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case '-':
|
|
|
|
r_sign_delete (core->anal, input + 1);
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
return zignLoad (data, input + 1);
|
|
|
|
case 'a':
|
|
|
|
return zignAdd (data, input + 1);
|
|
|
|
case 'f':
|
|
|
|
return zignFlirt (data, input + 1);
|
2017-03-13 01:48:23 +00:00
|
|
|
case '/':
|
2017-03-12 01:55:59 +00:00
|
|
|
return zignSearch (data, input + 1);
|
2017-03-07 23:20:48 +00:00
|
|
|
case 'c':
|
2014-09-14 16:16:11 +02:00
|
|
|
break;
|
2017-03-07 23:20:48 +00:00
|
|
|
case 's':
|
|
|
|
return zignSpace (data, input + 1);
|
|
|
|
case '?':
|
2016-08-21 08:33:21 +02:00
|
|
|
{
|
2017-03-07 23:20:48 +00:00
|
|
|
const char* help_msg[] = {
|
2017-03-12 01:05:07 +00:00
|
|
|
"Usage:", "z[*j-aof/cs] [args] ", "# Manage zignatures",
|
2017-03-07 23:20:48 +00:00
|
|
|
"z", "", "show zignagures",
|
|
|
|
"z*", "", "show zignatures in radare format",
|
|
|
|
"zj", "", "show zignatures in json format",
|
|
|
|
"z-", "zignature", "delete zignature",
|
|
|
|
"z-", "*", "delete all zignatures",
|
|
|
|
"za", "[?]", "add zignature",
|
2017-03-12 01:05:07 +00:00
|
|
|
"zo", "[?]", "load zignatures from file",
|
2017-03-07 23:20:48 +00:00
|
|
|
"zf", "[?]", "manage FLIRT signatures",
|
2017-03-13 01:48:23 +00:00
|
|
|
"z/", "[?]", "search zignatures",
|
2017-03-07 23:20:48 +00:00
|
|
|
"zc", "", "check zignatures at address",
|
|
|
|
"zs", "[?]", "manage zignspaces",
|
|
|
|
"NOTE:", "", "bytes can contain '..' (dots) to specify a binary mask",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
2016-08-21 08:33:21 +02:00
|
|
|
}
|
|
|
|
break;
|
2012-02-27 02:40:27 +01:00
|
|
|
default:
|
2017-03-12 12:19:00 +00:00
|
|
|
eprintf ("usage: z[*j-aof/cs] [args]\n");
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|
2017-03-07 23:20:48 +00:00
|
|
|
|
|
|
|
return true;
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|