rizin/librz/main/rz_sign.c
2021-01-21 22:05:44 +08:00

172 lines
3.6 KiB
C

// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_main.h>
#include <rz_core.h>
static void rasign_show_help(void) {
printf("Usage: rz-sign [options] [file]\n"
" -a [-a] add extra 'a' to analysis command\n"
" -f interpret the file as a FLIRT .sig file and dump signatures\n"
" -h help menu\n"
" -j show signatures in json\n"
" -o sigs.sdb add signatures to file, create if it does not exist\n"
" -q quiet mode\n"
" -r show output in rizin commands\n"
" -s signspace save all signatures under this signspace\n"
" -v show version information\n"
"Examples:\n"
" rz_sign -o libc.sdb libc.so.6\n");
}
static RzCore *opencore(const char *fname) {
RzCoreFile *rfile = NULL;
RzCore *c = rz_core_new();
if (!c) {
eprintf("Count not get core\n");
return NULL;
}
rz_core_loadlibs(c, RZ_CORE_LOADLIBS_ALL, NULL);
rz_config_set_i(c->config, "scr.interactive", false);
if (fname) {
#if __WINDOWS__
char *winf = rz_acp_to_utf8(fname);
rfile = rz_core_file_open(c, winf, 0, 0);
free(winf);
#else
rfile = rz_core_file_open(c, fname, 0, 0);
#endif
if (!rfile) {
eprintf("Could not open file %s\n", fname);
rz_core_free(c);
return NULL;
}
(void)rz_core_bin_load(c, NULL, UT64_MAX);
(void)rz_core_bin_update_arch_bits(c);
rz_cons_flush();
}
return c;
}
static void find_functions(RzCore *core, size_t count) {
const char *cmd = NULL;
switch (count) {
case 0: cmd = "aa"; break;
case 1: cmd = "aaa"; break;
case 2: cmd = "aaaa"; break;
}
rz_core_cmd0(core, cmd);
}
RZ_API int rz_main_rz_sign(int argc, const char **argv) {
const char *ofile = NULL;
const char *space = NULL;
int c;
size_t a_cnt = 0;
bool rad = false;
bool quiet = false;
bool json = false;
bool flirt = false;
RzGetopt opt;
rz_getopt_init(&opt, argc, argv, "afhjo:qrs:v");
while ((c = rz_getopt_next(&opt)) != -1) {
switch (c) {
case 'a':
a_cnt++;
break;
case 'o':
ofile = opt.arg;
break;
case 's':
space = opt.arg;
break;
case 'r':
rad = true;
break;
case 'j':
json = true;
break;
case 'q':
quiet = true;
break;
case 'f':
flirt = true;
break;
case 'v':
return rz_main_version_print("rz_sign");
case 'h':
rasign_show_help();
return 0;
default:
rasign_show_help();
return -1;
}
}
if (a_cnt > 2) {
eprintf("Invalid analysis (too many -a's?)\n");
rasign_show_help();
return -1;
}
const char *ifile = NULL;
if (opt.ind >= argc) {
eprintf("must provide a file\n");
rasign_show_help();
return -1;
}
ifile = argv[opt.ind];
RzCore *core = NULL;
if (flirt) {
if (rad || ofile || json) {
eprintf("Only FLIRT output is supported for FLIRT files\n");
return -1;
}
core = opencore(NULL);
rz_sign_flirt_dump(core->analysis, ifile);
rz_cons_flush();
rz_core_free(core);
return 0;
} else {
core = opencore(ifile);
}
if (!core) {
eprintf("Could not get core\n");
return -1;
}
// quiet mode
if (quiet) {
rz_config_set(core->config, "scr.interactive", "false");
rz_config_set(core->config, "scr.prompt", "false");
rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
}
if (space) {
rz_spaces_set(&core->analysis->zign_spaces, space);
}
// run analysis to find functions
find_functions(core, a_cnt);
// create zignatures
rz_core_cmd0(core, "zg");
// write sigs to file
if (ofile) {
rz_core_cmdf(core, "\"zos %s\"", ofile);
}
if (rad) {
rz_core_flush(core, "z*");
}
if (json) {
rz_core_flush(core, "zj");
}
rz_core_free(core);
return 0;
}