int main(int argc, const char **argv) { char *line; int i; if (argc<2) showusage (1); if (!strcmp (argv[1], "-d")) { if (argc == 4) return dbdiff (argv[2], argv[3]); showusage(0); } else if (!strcmp (argv[1], "-v")) showversion (); if (!strcmp (argv[1], "-h")) showusage (0); if (!strcmp (argv[1], "-j")) { if (argc>2) return sdb_dump (argv[2], 1); printf ("Missing database filename after -j\n"); return 1; } if (!strcmp (argv[1], "-")) { argv[1] = ""; if (argc == 2) { argv[2] = "-"; argc++; } } if (argc == 2) return sdb_dump (argv[1], 0); #if USE_MMAN signal (SIGINT, terminate); signal (SIGHUP, syncronize); #endif if (!strcmp (argv[2], "=")) return createdb (argv[1]); else if (!strcmp (argv[2], "-")) { if ((s = sdb_new (NULL, argv[1], 0))) { sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP); for (;(line = stdin_gets ());) { save = sdb_query (s, line); free (line); } } } else { s = sdb_new (NULL, argv[1], 0); if (!s) return 1; sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP); for (i=2; i<argc; i++) save = sdb_query (s, argv[i]); } terminate (0); return 0; }
static int insertkeys(Sdb *s, const char **args, int nargs, int mode) { int must_save = 0; if (args && nargs > 0) { int i; for (i = 0; i < nargs; i++) { switch (mode) { case '-': must_save |= sdb_query (s, args[i]); break; case '=': if (strchr (args[i], '=')) { char *v, *kv = (char *)strdup (args[i]); v = strchr (kv, '='); if (v) { *v++ = 0; sdb_disk_insert (s, kv, v); } free (kv); } break; } } } return must_save; }
static void __sdb_prompt(Sdb *sdb) { char *line; for (;(line = stdin_gets ());) { sdb_query (sdb, line); free (line); } }
int main(int argc, char **argv) { int i; if (argc<2) showusage (1); if (!strcmp (argv[1], "-v")) showversion (); if (!strcmp (argv[1], "-h")) showusage (0); if (!strcmp (argv[1], "-")) { argv[1] = ""; if (argc == 2) { argv[2] = "-"; argc++; } } if (argc == 2) return sdb_dump (argv[1]); #if USE_MMAN signal (SIGINT, terminate); signal (SIGHUP, syncronize); #endif if (!strcmp (argv[2], "=")) { createdb (argv[1]); } else if (!strcmp (argv[2], "-")) { char line[SDB_VSZ+SDB_KSZ]; // XXX can overflow stack if ((s = sdb_new (argv[1], 0))) for (;;) { fgets (line, sizeof line, stdin); if (feof (stdin)) break; line[strlen (line)-1] = 0; save = sdb_query (s, line); } } else if ((s = sdb_new (argv[1], 0))) { for (i=2; i<argc; i++) save = sdb_query (s, argv[i]); } terminate (0); return 0; }
SDB_VISIBLE int sdb_queryf (Sdb *s, const char *fmt, ...) { char string[4096]; int ret; va_list ap; va_start (ap, fmt); vsnprintf (string, sizeof (string), fmt, ap); ret = sdb_query (s, string); va_end (ap); return ret; }
int main(int argc, const char **argv) { char *line; int i; if (argc<2) showusage (1); if (!strcmp (argv[1], "-v")) showversion (); if (!strcmp (argv[1], "-h")) showusage (0); if (!strcmp (argv[1], "-")) { argv[1] = ""; if (argc == 2) { argv[2] = "-"; argc++; } } if (argc == 2) return sdb_dump (argv[1], 0); #if USE_MMAN signal (SIGINT, terminate); signal (SIGHUP, syncronize); #endif if (!strcmp (argv[2], "[]")) { return sdb_dump (argv[1], 1); } if (!strcmp (argv[2], "=")) return createdb (argv[1]); else if (!strcmp (argv[2], "-")) { if ((s = sdb_new (NULL, argv[1], 0))) { for (;(line = stdin_gets ());) { save = sdb_query (s, line); free (line); } } } else { s = sdb_new (NULL, argv[1], 0); if (!s) return 1; for (i=2; i<argc; i++) save = sdb_query (s, argv[i]); } terminate (0); return 0; }
SDB_VISIBLE int sdb_query_lines (Sdb *s, const char *cmd) { char *o, *p, *op = strdup (cmd); if (!s || !op) return 0; p = op; do { o = strchr (p, '\n'); if (o) *o = 0; sdb_query (s, p); if (o) p = o+1; } while (o); free (op); return 1; }
static int gw_sdb_query(char *query, int (*callback)(int, char **, void *), void *closure) { DBPoolConn *pc; int rows; pc = dbpool_conn_consume(pool); if (pc == NULL) { error(0, "SDB: Database pool got no connection!"); return -1; } rows = sdb_query(pc->conn, query, callback, closure); dbpool_conn_produce(pc); return rows; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore*)data; switch (input[0]) { // t [typename] - show given type in C syntax case 's': { char *q, *p, *o, *e; p = o = strdup (input+1); for (;;) { q = strchr (p, ' '); if (q) *q = 0; if (!*p) { p++; continue; } e = strchr (p, '='); if (e) { *e = 0; r_anal_type_set (core->anal, core->offset, p, r_num_math (core->num, e+1)); } else eprintf ("TODO: implement get\n"); if (!q) break; p = q+1; } free (o); } break; case ' ': { char *fmt = r_anal_type_format (core->anal, input +1); if (fmt) { r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input+1); } break; #if 0 // t* - list all types in 'pf' syntax case '*': r_anal_type_list (core->anal, R_ANAL_TYPE_ANY, 1); break; #endif case 0: // TODO: use r_cons here //sdb_list (core->anal->sdb_types); sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (input[1] == ' ') { const char *filename = input + 2; if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char * help_message[] = { "Usage:", "td[...]", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help(core, help_message); } else if (input[1] == '-') { const char *arg = strchr (input+1, ' '); if (arg) arg++; else arg = input+2; r_anal_type_del (core->anal, arg); } else if (input[1] == ' ') { char tmp[256]; snprintf (tmp, sizeof (tmp), "%s;", input+2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': if (input[1]=='?') { const char * help_message[] = { "Usage: tl", " [typename|addr] ([addr])@[addr|function]", "", NULL }; r_core_cmd_help(core, help_message); } else if (input[1]) { ut64 addr = r_num_math (core->num, input+2); char *ptr = strchr (input + 2, ' '); if (ptr) { addr = r_num_math (core->num, ptr + 1); *ptr = '\0'; } else addr = core->offset; r_anal_type_link (core->anal, input+2, addr); } else { r_core_cmd0 (core, "t~^link"); } break; case '-': if (input[1] == '?') { const char * help_message[] = { "Usage: t-", " <type>", "Delete type by its name", NULL }; r_core_cmd_help(core, help_message); } else if (input[1]=='*') { eprintf ("TODO\n"); } else { const char *name = input + 1; if (*name==' ') name++; if (*name) { r_anal_type_del (core->anal, name); } else eprintf ("Invalid use of t- . See t-? for help.\n"); } break; // tv - get/set type value linked to a given address case 'f': { ut64 addr; char *fmt, key[128]; const char *type; if (input[1]) { addr = r_num_math (core->num, input+1); } else addr = core->offset; snprintf (key, sizeof (key), "link.%"PFMT64x, addr); type = sdb_const_get (core->anal->sdb_types, key, 0); if (type) { fmt = r_anal_type_format (core->anal, type); r_cons_printf ("struct %s {\n", type); if (fmt) { r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x"\n", fmt, addr); free (fmt); }// else eprintf ("Cannot find '%s' type\n", input+1); r_cons_printf ("}\n"); } } break; case '?': if (input[1]) { sdb_query (core->anal->sdb_types, input+1); } else show_help(core); break; } return R_TRUE; }
static int cmd_info(void *data, const char *input) { RCore *core = (RCore *)data; int newline = r_config_get_i (core->config, "scr.interactive"); ut64 offset = r_bin_get_offset (core->bin); RBinObject *o = r_bin_cur_object (core->bin); RCoreFile *cf = core->file; int va = core->io->va || core->io->debug; int mode = 0; //R_CORE_BIN_SIMPLE; int is_array = 0; Sdb *db; if (strchr (input, '*')) mode = R_CORE_BIN_RADARE; if (strchr (input, 'j')) mode = R_CORE_BIN_JSON; if (mode == R_CORE_BIN_JSON) { if (strlen (input+1)>1) is_array = 1; } if (is_array) r_cons_printf ("{"); if (!*input) cmd_info_bin (core, offset, va, mode); while (*input) { switch (*input) { case 'b': { ut64 baddr = r_config_get_i (core->config, "bin.baddr"); if (input[1]==' ') baddr = r_num_math (core->num, input+1); // XXX: this will reload the bin using the buffer. // An assumption is made that assumes there is an underlying // plugin that will be used to load the bin (e.g. malloc://) // TODO: Might be nice to reload a bin at a specified offset? r_core_bin_reload (core, NULL, baddr); r_core_block_read (core, 0); } break; case 'k': db = o ? o->kv : NULL; //:eprintf ("db = %p\n", db); switch (input[1]) { case 'v': if (db) sdb_query (db, input+3); break; case '.': case ' ': if (db) sdb_query (db, input+2); break; case '\0': if (db) sdb_list (db); break; case '?': default: eprintf ("Usage: ik [sdb-query]\n"); } break; case 'o': r_core_bin_load (core, input[1]==' '? input+2: cf->filename, r_config_get_i (core->config, "bin.baddr")); break; #define RBININFO(n,x) \ if (is_array) { \ if (is_array==1) is_array++; else r_cons_printf (","); \ r_cons_printf ("\"%s\":",n); \ }\ r_core_bin_info (core,x,mode,va,NULL,offset); case 'A': newline=0; r_bin_list_archs (core->bin, 1); break; case 'S': RBININFO ("sections",R_CORE_BIN_ACC_SECTIONS); break; case 'h': RBININFO ("fields", R_CORE_BIN_ACC_FIELDS); break; case 'l': RBININFO ("libs", R_CORE_BIN_ACC_LIBS); break; case 's': RBININFO ("symbols", R_CORE_BIN_ACC_SYMBOLS); break; case 'R': case 'r': RBININFO ("relocs", R_CORE_BIN_ACC_RELOCS); break; case 'd': RBININFO ("dwarf", R_CORE_BIN_ACC_DWARF); break; case 'i': RBININFO ("imports",R_CORE_BIN_ACC_IMPORTS); break; case 'I': RBININFO ("info", R_CORE_BIN_ACC_INFO); break; case 'e': RBININFO ("entries",R_CORE_BIN_ACC_ENTRIES); break; case 'z': RBININFO ("strings",R_CORE_BIN_ACC_STRINGS); break; case 'c': case 'C': RBININFO ("classes",R_CORE_BIN_ACC_CLASSES); break; case 'a': { switch (mode) { case R_CORE_BIN_RADARE: cmd_info (core, "i*IiesSz"); break; case R_CORE_BIN_JSON: cmd_info (core, "ijIiesSz"); break; default: case R_CORE_BIN_SIMPLE: cmd_info (core, "iIiesSz"); break; } } break; case '?': r_cons_printf ( "|Usage: i[aeciIsosSz][jq*] ; get info from opened file\n" "|Output mode:\n" "| '*' output in radare commands\n" "| 'j' output in json\n" "| 'q' simple quiet output\n" "|Actions:\n" "| i, ij show info of current file (in JSON)\n" "| iA list archs\n" "| ia show all info (imports, exports, sections..)\n" "| ib reload the current buffer for setting of the bin (use once only)\n" "| ic list classes\n" "| id debug information (source lines)\n" "| ie entrypoint\n" "| ih headers\n" "| ii imports\n" "| iI binary info\n" "| il libraries\n" "| ik [query] key-value database from RBinObject\n" "| io [file] load info from file (or last opened) use bin.baddr\n" "| is symbols\n" "| iS sections\n" "| ir/iR relocs\n" "| iz strings\n" ); goto done; case '*': mode = R_CORE_BIN_RADARE; goto done; case 'j': mode = R_CORE_BIN_JSON; cmd_info_bin (core, offset, va, mode); goto done; default: cmd_info_bin (core, offset, va, mode); break; } input++; if (!strcmp (input, "j")) break; } done: if (is_array) r_cons_printf ("}\n"); if (newline) r_cons_newline(); return 0; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore*)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'k': if (input[1]==' ') { sdb_query (core->anal->sdb_types, input+2); } else sdb_query (core->anal->sdb_types, "*"); break; case 's': { char *q, *p, *o, *e; p = o = strdup (input+1); for (;;) { if (*p == '\0'){ eprintf ("Usage: ts <k>=<v> Set fields at curseek linked type\n"); break; } q = strchr (p, ' '); if (q) *q = 0; if (!*p) { p++; continue; } e = strchr (p, '='); if (e) { *e = 0; r_anal_type_set (core->anal, core->offset, p, r_num_math (core->num, e+1)); } else eprintf ("TODO: implement get\n"); if (!q) break; p = q+1; } free (o); } break; case 'b': { int i; char *p, *s = (strlen (input) > 1) ? strdup (input+2): NULL; const char *isenum; p = s ? strchr (s, ' ') : NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) #if 1 isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { int empty = 1; ut32 num = (ut32)r_num_math (core->num, p); r_cons_printf ("0x%08"PFMT64x" : ", num); for (i=0; i< 32; i++) { if (num & (1<<i)) { const char *q = sdb_fmt (0, "%s.0x%x", s, (1<<i)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (!empty) r_cons_printf (" | "); if (res) r_cons_printf ("%s", res); else r_cons_printf ("0x%x", (1<<i)); empty = 0; } } } else { eprintf ("This is not an enum\n"); } #endif } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { eprintf ("Missing value\n"); break; } char *p, *s = strdup (input+2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_printf ("%s\n", res); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input+2, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input +1); if (fmt) { r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input+1); } } break; #if 0 // t* - list all types in 'pf' syntax case '*': r_anal_type_list (core->anal, R_ANAL_TYPE_ANY, 1); break; #endif case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (input[1] == ' ') { const char *filename = input + 2; if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { // r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char * help_message[] = { "Usage:", "td[...]", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help(core, help_message); } else if (input[1] == '-') { const char *arg = strchr (input+1, ' '); if (arg) arg++; else arg = input+2; r_anal_type_del (core->anal, arg); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp)-1, "%s;", input+2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': if (input[1]=='?') { const char * help_message[] = { "Usage: tl", " [typename|addr] ([addr])@[addr|function]", "", NULL }; r_core_cmd_help(core, help_message); } else if (input[1]) { ut64 addr = r_num_math (core->num, input+2); char *ptr = strchr (input + 2, ' '); if (ptr) { addr = r_num_math (core->num, ptr + 1); *ptr = '\0'; } else addr = core->offset; r_anal_type_link (core->anal, input+2, addr); } else { r_core_cmd0 (core, "t~^link"); } break; case '-': if (input[1] == '?') { const char * help_message[] = { "Usage: t-", " <type>", "Delete type by its name", NULL }; r_core_cmd_help(core, help_message); } else if (input[1]=='*') { eprintf ("TODO\n"); } else { const char *name = input + 1; if (*name==' ') name++; if (*name) { r_anal_type_del (core->anal, name); } else eprintf ("Invalid use of t- . See t-? for help.\n"); } break; // tv - get/set type value linked to a given address case 'f': { ut64 addr; char *fmt, key[128]; const char *type; if (input[1]) { addr = r_num_math (core->num, input+1); } else addr = core->offset; snprintf (key, sizeof (key), "link.%08"PFMT64x, addr); type = sdb_const_get (core->anal->sdb_types, key, 0); if (type) { fmt = r_anal_type_format (core->anal, type); r_cons_printf ("struct %s {\n", type); if (fmt) { r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x"\n", fmt, addr); free (fmt); }// else eprintf ("Cannot find '%s' type\n", input+1); r_cons_printf ("}\n"); } //else eprintf ("Cant find type at 0x%llx\n", addr); } break; case '?': show_help (core); break; } return true; }
static int cmd_info(void *data, const char *input) { RCore *core = (RCore *)data; int newline = r_config_get_i (core->config, "scr.interactive"); ut64 offset = r_bin_get_offset (core->bin); RBinObject *o = r_bin_cur_object (core->bin); RCoreFile *cf = core->file; int va = core->io->va || core->io->debug; int mode = 0; //R_CORE_BIN_SIMPLE; int is_array = 0; Sdb *db; if (strchr (input, '*')) mode = R_CORE_BIN_RADARE; if (strchr (input, 'j')) mode = R_CORE_BIN_JSON; if (mode == R_CORE_BIN_JSON) { if (strlen (input+1)>1) is_array = 1; } if (is_array) r_cons_printf ("{"); if (!*input) cmd_info_bin (core, offset, va, mode); while (*input) { switch (*input) { case 'b': { ut64 baddr = r_config_get_i (core->config, "bin.baddr"); if (input[1]==' ') baddr = r_num_math (core->num, input+1); // XXX: this will reload the bin using the buffer. // An assumption is made that assumes there is an underlying // plugin that will be used to load the bin (e.g. malloc://) // TODO: Might be nice to reload a bin at a specified offset? r_core_bin_reload (core, NULL, baddr); r_core_block_read (core, 0); } break; case 'k': db = o ? o->kv : NULL; //:eprintf ("db = %p\n", db); switch (input[1]) { case 'v': if (db) sdb_query (db, input+3); break; case '.': case ' ': if (db) sdb_query (db, input+2); break; case '\0': if (db) sdb_list (db); break; case '?': default: eprintf ("Usage: ik [sdb-query]\n"); } break; case 'o': { const char *fn = input[1]==' '? input+2: cf->desc->name; ut64 laddr = UT64_MAX; laddr = r_config_get_i (core->config, "bin.baddr"); r_core_bin_load (core, fn, laddr); } break; #define RBININFO(n,x) \ if (is_array) { \ if (is_array==1) is_array++; else r_cons_printf (","); \ r_cons_printf ("\"%s\":",n); \ }\ r_core_bin_info (core,x,mode,va,NULL,offset,NULL); case 'A': newline=0; r_bin_list_archs (core->bin, 1); break; case 'Z': RBININFO ("size",R_CORE_BIN_ACC_SIZE); break; case 'S': RBININFO ("sections",R_CORE_BIN_ACC_SECTIONS); break; case 'h': RBININFO ("fields", R_CORE_BIN_ACC_FIELDS); break; case 'l': RBININFO ("libs", R_CORE_BIN_ACC_LIBS); break; case 's': RBININFO ("symbols", R_CORE_BIN_ACC_SYMBOLS); break; case 'R': case 'r': RBININFO ("relocs", R_CORE_BIN_ACC_RELOCS); break; case 'd': RBININFO ("dwarf", R_CORE_BIN_ACC_DWARF); break; case 'i': RBININFO ("imports",R_CORE_BIN_ACC_IMPORTS); break; case 'I': RBININFO ("info", R_CORE_BIN_ACC_INFO); break; case 'e': RBININFO ("entries",R_CORE_BIN_ACC_ENTRIES); break; case 'z': RBININFO ("strings",R_CORE_BIN_ACC_STRINGS); break; case 'c': case 'C': RBININFO ("classes",R_CORE_BIN_ACC_CLASSES); break; case 'a': { switch (mode) { case R_CORE_BIN_RADARE: cmd_info (core, "i*IiesSz"); break; case R_CORE_BIN_JSON: cmd_info (core, "iIiesSzj"); break; default: case R_CORE_BIN_SIMPLE: cmd_info (core, "iIiesSz"); break; } } break; case '?': { const char * help_message[] = { "Usage: i", "", "Get info from opened file", "Output mode:", "", "", "'*'", "", "Output in radare commands", "'j'", "", "Output in json", "'q'", "", "Simple quiet output", "Actions:", "", "", "i|ij", "", "Show info of current file (in JSON)", "iA", "", "List archs", "ia", "", "Show all info (imports, exports, sections..)", "ib", "", "Reload the current buffer for setting of the bin (use once only)", "ic", "", "List classes", "id", "", "Debug information (source lines)", "ie", "", "Entrypoint", "ih", "", "Headers", "ii", "", "Imports", "iI", "", "Binary info", "ik", " [query]", "Key-value database from RBinObject", "il", "", "Libraries", "io", " [file]", "Load info from file (or last opened) use bin.baddr", "ir|iR", "", "Relocs", "is", "", "Symbols", "iS", "", "Sections", "iz", "", "Strings", NULL }; r_core_cmd_help(core, help_message); } goto done; case '*': mode = R_CORE_BIN_RADARE; goto done; case 'j': mode = R_CORE_BIN_JSON; cmd_info_bin (core, offset, va, mode); goto done; default: cmd_info_bin (core, offset, va, mode); break; } input++; if (!strcmp (input, "j")) break; } done: if (is_array) r_cons_printf ("}\n"); if (newline) r_cons_newline(); return 0; }
int main(int argc, char **argv) { const char *query = NULL; int c, bits = 0, actions_done = 0, actions = 0, action = ACTION_UNK; char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins"); char *ptr, *arch = NULL, *arch_name = NULL; const char *op = NULL; RCoreBinFilter filter; RCore core; RCoreFile *cf = NULL; int xtr_idx = 0; // load all files if extraction is necessary. int fd = -1; int rawstr = 0; r_core_init (&core); bin = core.bin; l = r_lib_new ("radare_plugin"); r_lib_add_handler (l, R_LIB_TYPE_BIN, "bin plugins", &__lib_bin_cb, &__lib_bin_dt, NULL); r_lib_add_handler (l, R_LIB_TYPE_BIN_XTR, "bin xtr plugins", &__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL); /* load plugins everywhere */ r_lib_opendir (l, getenv ("LIBR_PLUGINS")); r_lib_opendir (l, homeplugindir); r_lib_opendir (l, LIBDIR"/radare2/"R2_VERSION); #define is_active(x) (action&x) #define set_action(x) actions++; action |=x while ((c = getopt (argc, argv, "jgqAf:a:B:b:c:Ck:dMm:n:N:@:isSIHelRwO:o:rvLhxzZ")) != -1) { switch (c) { case 'g': set_action (ACTION_CLASSES); set_action (ACTION_IMPORTS); set_action (ACTION_SYMBOLS); set_action (ACTION_SECTIONS); set_action (ACTION_STRINGS); set_action (ACTION_SIZE); set_action (ACTION_INFO); set_action (ACTION_FIELDS); set_action (ACTION_DWARF); set_action (ACTION_ENTRIES); set_action (ACTION_MAIN); set_action (ACTION_LIBS); set_action (ACTION_RELOCS); set_action (ACTION_EXTRACT); break; case 'q': rad = R_CORE_BIN_SIMPLE; break; case 'j': rad = R_CORE_BIN_JSON; break; case 'A': set_action (ACTION_LISTARCHS); break; case 'a': if (optarg) arch = optarg; break; case 'c': if (!optarg) { eprintf ("Missing argument for -c"); return 1; } set_action (ACTION_CREATE); create = strdup (optarg); break; case 'k': query = optarg; break; case 'C': set_action (ACTION_CLASSES); break; case 'f': if (optarg) arch_name = strdup (optarg); break; case 'b': bits = r_num_math (NULL, optarg); break; case 'm': at = r_num_math (NULL, optarg); set_action (ACTION_SRCLINE); break; case 'i': set_action (ACTION_IMPORTS); break; case 's': set_action (ACTION_SYMBOLS); break; case 'S': set_action (ACTION_SECTIONS); break; case 'z': if (is_active (ACTION_STRINGS)) { rawstr = R_TRUE; } else set_action (ACTION_STRINGS); break; case 'Z': set_action (ACTION_SIZE); break; case 'I': set_action (ACTION_INFO); break; case 'H': set_action (ACTION_FIELDS); break; case 'd': set_action (ACTION_DWARF); break; case 'e': set_action (ACTION_ENTRIES); break; case 'M': set_action (ACTION_MAIN); break; case 'l': set_action (ACTION_LIBS); break; case 'R': set_action (ACTION_RELOCS); break; case 'x': set_action (ACTION_EXTRACT); break; case 'w': rw = R_TRUE; break; case 'O': op = optarg; set_action (ACTION_OPERATION); if (op && !strcmp (op, "help")) { printf ("Operation string:\n" " Dump symbols: d/s/1024\n" " Dump section: d/S/.text\n" " Resize section: r/.data/1024\n"); return 0; } if (optind==argc) { eprintf ("Missing filename\n"); return 1; } break; case 'o': output = optarg; break; case 'r': rad = R_TRUE; break; case 'v': va = R_TRUE; break; case 'L': r_bin_list (bin); return 1; case 'B': baddr = r_num_math (NULL, optarg); break; case '@': at = r_num_math (NULL, optarg); break; case 'n': name = optarg; break; case 'N': bin->minstrlen = r_num_math (NULL, optarg); break; //case 'V': return blob_version ("rabin2"); case 'h': return rabin_show_help (1); default: action |= ACTION_HELP; } } file = argv[optind]; if (!query) if (action & ACTION_HELP || action == ACTION_UNK || file == NULL) { if (va) return blob_version ("rabin2"); return rabin_show_help (0); } if (arch) { ptr = strchr (arch, '_'); if (ptr) { *ptr = '\0'; bits = r_num_math (NULL, ptr+1); } } if (action & ACTION_CREATE) { // TODO: move in a function outside RBuffer *b; int datalen, codelen; ut8 *data = NULL, *code = NULL; char *p2, *p = strchr (create, ':'); if (!p) { eprintf ("Invalid format for -c flag. Use 'format:codehexpair:datahexpair'\n"); return 1; } *p++ = 0; p2 = strchr (p, ':'); if (p2) { // has data *p2++ = 0; data = malloc (strlen (p2)+1); datalen = r_hex_str2bin (p2, data); } else { data = NULL; datalen = 0; } code = malloc (strlen (p)+1); if (!code) { return 1; } codelen = r_hex_str2bin (p, code); if (!arch) arch = "x86"; if (!bits) bits = 32; if (!r_bin_use_arch (bin, arch, bits, create)) { eprintf ("Cannot set arch\n"); return 1; } b = r_bin_create (bin, code, codelen, data, datalen); if (b) { if (r_file_dump (file, b->buf, b->length)) { eprintf ("dumped %d bytes in '%s'\n", b->length, file); r_file_chmod (file, "+x", 0); } else eprintf ("error dumping into a.out\n"); r_buf_free (b); } else eprintf ("Cannot create binary for this format '%s'.\n", create); r_bin_free (bin); return 0; } r_config_set_i (core.config, "bin.rawstr", rawstr); cf = r_core_file_open (&core, file, R_IO_READ, 0); fd = cf ? r_core_file_cur_fd (&core) : -1; if (!cf || fd == -1) { eprintf ("r_core: Cannot open file\n"); return 1; } if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) { if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) { eprintf ("r_bin: Cannot open file\n"); return 1; } } if (query) { if (!strcmp (query, "-")) { __sdb_prompt (bin->cur->sdb); } else sdb_query (bin->cur->sdb, query); return 0; } // XXX: TODO move this to libr/core/bin.c if (action & ACTION_LISTARCHS || ((arch || bits || arch_name) && !r_bin_select (bin, arch, bits, arch_name))) { if (rad == R_CORE_BIN_JSON) { int i; printf ("["); for (i = 0; i < bin->narch; i++) { if (r_bin_select_idx (bin, bin->file, i)) { RBinObject *o = r_bin_cur_object (bin); RBinInfo *info = o ? o->info : NULL; printf ("%s{\"arch\":\"%s\",\"bits\":%d," "\"offset\":%"PFMT64d",\"machine\":\"%s\"}", i?",":"",info->arch, info->bits, bin->cur->offset, info->machine); } } printf ("]"); } else r_bin_list_archs (bin, 1); free (arch_name); } if (baddr != 0LL) { r_bin_set_baddr (bin, baddr); bin->cur->o->baddr = baddr; } core.bin = bin; filter.offset = at; filter.name = name; r_cons_new ()->is_interactive = R_FALSE; #define isradjson (rad==R_CORE_BIN_JSON&&actions>0) #define run_action(n,x,y) {\ if (action&x) {\ if (isradjson) r_cons_printf ("\"%s\":",n);\ if (!r_core_bin_info (&core, y, rad, va, &filter, 0)) {\ if (isradjson) r_cons_printf("false");\ };\ actions_done++;\ if (isradjson) r_cons_printf (actions==actions_done? "":",");\ }\ } if (isradjson) r_cons_printf ("{"); run_action ("sections", ACTION_SECTIONS, R_CORE_BIN_ACC_SECTIONS); run_action ("entries", ACTION_ENTRIES, R_CORE_BIN_ACC_ENTRIES); run_action ("main", ACTION_MAIN, R_CORE_BIN_ACC_MAIN); run_action ("imports", ACTION_IMPORTS, R_CORE_BIN_ACC_IMPORTS); run_action ("classes", ACTION_CLASSES, R_CORE_BIN_ACC_CLASSES); run_action ("symbols", ACTION_SYMBOLS, R_CORE_BIN_ACC_SYMBOLS); run_action ("strings", ACTION_STRINGS, R_CORE_BIN_ACC_STRINGS); run_action ("info", ACTION_INFO, R_CORE_BIN_ACC_INFO); run_action ("fields", ACTION_FIELDS, R_CORE_BIN_ACC_FIELDS); run_action ("libs", ACTION_LIBS, R_CORE_BIN_ACC_LIBS); run_action ("relocs", ACTION_RELOCS, R_CORE_BIN_ACC_RELOCS); run_action ("dwarf", ACTION_DWARF, R_CORE_BIN_ACC_DWARF); run_action ("size", ACTION_SIZE, R_CORE_BIN_ACC_SIZE); if (action&ACTION_SRCLINE) rabin_show_srcline (at); if (action&ACTION_EXTRACT) rabin_extract ((arch==NULL && arch_name==NULL && bits==0)); if (op != NULL && action&ACTION_OPERATION) rabin_do_operation (op); if (isradjson) printf ("}"); r_cons_flush (); r_core_fini (&core); return 0; }
int main(int argc, const char **argv) { char *line; const char *arg, *grep = NULL; int i, ret, fmt = MODE_DFLT; int db0 = 1, argi = 1; bool interactive = false; /* terminate flags */ if (argc < 2) { return showusage (1); } arg = argv[1]; if (arg[0] == '-') {// && arg[1] && arg[2]==0) { switch (arg[1]) { case 0: /* no-op */ break; case '0': fmt = MODE_ZERO; db0++; argi++; if (db0 >= argc) { return showusage (1); } break; case 'g': db0 += 2; if (db0 >= argc) { return showusage (1); } grep = argv[2]; argi += 2; break; case 'J': options |= SDB_OPTION_JOURNAL; db0++; argi++; if (db0 >= argc) { return showusage (1); } break; case 'c': return (argc < 3)? showusage (1) : showcount (argv[2]); case 'v': return showversion (); case 'h': return showusage (2); case 'e': return base64encode (); case 'd': return base64decode (); case 'D': if (argc == 4) { return dbdiff (argv[2], argv[3]); } return showusage (0); case 'j': if (argc > 2) { return sdb_dump (argv[db0 + 1], MODE_JSON); } return jsonIndent(); default: eprintf ("Invalid flag %s\n", arg); break; } } /* sdb - */ if (argi == 1 && !strcmp (argv[argi], "-")) { /* no database */ argv[argi] = ""; if (argc == db0 + 1) { interactive = true; /* if no argument passed */ argv[argi] = "-"; argc++; argi++; } } /* sdb dbname */ if (argc - 1 == db0) { if (grep) { return sdb_grep (argv[db0], fmt, grep); } return sdb_dump (argv[db0], fmt); } #if USE_MMAN signal (SIGINT, terminate); signal (SIGHUP, synchronize); #endif ret = 0; if (interactive || !strcmp (argv[db0 + 1], "-")) { if ((s = sdb_new (NULL, argv[db0], 0))) { sdb_config (s, options); int kvs = db0 + 2; if (kvs < argc) { save |= insertkeys (s, argv + argi + 2, argc - kvs, '-'); } for (;(line = stdin_slurp (NULL));) { save |= sdb_query (s, line); if (fmt) { fflush (stdout); write (1, "", 1); } free (line); } } } else if (!strcmp (argv[db0 + 1], "=")) { ret = createdb (argv[db0], NULL, 0); } else { s = sdb_new (NULL, argv[db0], 0); if (!s) { return 1; } sdb_config (s, options); for (i = db0 + 1; i < argc; i++) { save |= sdb_query (s, argv[i]); if (fmt) { fflush (stdout); write (1, "", 1); } } } terminate (0); return ret; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore *)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'k': if (input[1] == ' ') { sdb_query (core->anal->sdb_types, input + 2); } else sdb_query (core->anal->sdb_types, "*"); break; case 's': { char *q, *p, *o, *e; p = o = strdup (input + 1); for (;;) { if (*p == '\0') { eprintf ("Usage: ts <k>=<v> Set fields at curseek linked type\n"); break; } q = strchr (p, ' '); if (q) *q = 0; if (!*p) { p++; continue; } e = strchr (p, '='); if (e) { *e = 0; r_anal_type_set (core->anal, core->offset, p, r_num_math (core->num, e + 1)); } else eprintf ("TODO: implement get\n"); if (!q) break; p = q + 1; } free (o); } break; case 'b': { char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL; const char *isenum; p = s? strchr (s, ' '): NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { *--p = '.'; const char *res = sdb_const_get (core->anal->sdb_types, s, 0); if (res) r_cons_printf ("%s\n", res); else eprintf ("Invalid enum member\n"); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_printf ("%s\n", name); } } } free (name); ls_free (l); break; } char *p, *s = strdup (input + 2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_printf ("%s\n", res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input + 1); if (fmt) { r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input + 1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (!r_sandbox_enable (0)) { if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { //r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } } else { eprintf ("Sandbox: system call disabled\n"); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char *help_message[] = { "Usage:", "\"td [...]\"", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help (core, help_message); r_cons_printf ("Note: The td command should be put between double quotes\n" "Example: \" td struct foo {int bar;int cow};\"" "\nt"); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); sdb_query_lines (core->anal->sdb_types, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': if (input[1] == '?') { const char *help_message[] = { "Usage: tl", " [typename|addr] ([addr])@[addr|function]", "", NULL }; r_core_cmd_help (core, help_message); } else if (input[1]) { ut64 addr = r_num_math (core->num, input + 2); char *ptr = strchr (input + 2, ' '); if (ptr) { addr = r_num_math (core->num, ptr + 1); *ptr = '\0'; } else addr = core->offset; r_anal_type_link (core->anal, input + 2, addr); } else { r_core_cmd0 (core, "t~^link"); } break; case '-': if (input[1] == '?') { const char *help_message[] = { "Usage: t-", " <type>", "Delete type by its name", NULL }; r_core_cmd_help (core, help_message); } else if (input[1] == '*') { sdb_foreach (core->anal->sdb_types, sdbdelete, core); } else { const char *name = input + 1; while (IS_WHITESPACE (*name)) name++; if (*name) { SdbKv *kv; SdbListIter *iter; int tmp_len = strlen (name); char *tmp = malloc (tmp_len + 2); r_anal_type_del (core->anal, name); if (tmp) { snprintf (tmp, tmp_len + 1, "%s.", name); SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strncmp (kv->key, tmp, tmp_len - 1)) r_anal_type_del (core->anal, kv->key); } free (tmp); } } else eprintf ("Invalid use of t- . See t-? for help.\n"); }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore *)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'u': // "tu" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE tu[...]", "", "", "tu", "", "List all loaded unions", "tu?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifunion, core); break; } break; case 'k': // "tk" if (input[1] == ' ') { sdb_query (core->anal->sdb_types, input + 2); } else sdb_query (core->anal->sdb_types, "*"); fflush (stdout); break; case 's': // "ts" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE ts[...]", "", "", "ts", "", "List all loaded structs", "ts?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifstruct, core); break; } break; case 'b': { char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL; const char *isenum; p = s? strchr (s, ' '): NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { *--p = '.'; const char *res = sdb_const_get (core->anal->sdb_types, s, 0); if (res) r_cons_println (res); else eprintf ("Invalid enum member\n"); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_println (name); } } } free (name); ls_free (l); break; } if (input[1] == '?') { const char *help_message[] = { "USAGE te[...]", "", "", "te", "", "List all loaded enums", "te", " <enum> <value>", "Show name for given enum number", "te?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); break; } char *p, *s = strdup (input + 2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strncmp (isenum, "enum", 4)) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_println (res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input + 1); if (fmt) { r_str_chop (fmt); r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input + 1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (!r_sandbox_enable (0)) { if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); save_parsed_type (core, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } else if (input[1] == 's') { const char *dbpath = input + 3; if (r_file_exists (dbpath)) { Sdb *db_tmp = sdb_new (0, dbpath, 0); sdb_merge (core->anal->sdb_types, db_tmp); sdb_close (db_tmp); sdb_free (db_tmp); } } } else { eprintf ("Sandbox: system call disabled\n"); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char *help_message[] = { "Usage:", "\"td [...]\"", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help (core, help_message); r_cons_printf ("Note: The td command should be put between double quotes\n" "Example: \" td struct foo {int bar;int cow};\"" "\nt"); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': switch (input[1]) { case '?': { const char *help_message[] = { "Usage:", "", "", "tl", "", "list all links in readable format", "tl", "[typename]", "link a type to current adress.", "tl", "[typename] = [address]", "link type to given address.", "tls", "[address]", "show link at given address", "tl-*", "", "delete all links.", "tl-", "[address]", "delete link at given address.", "tl*", "", "list all links in radare2 command format", "tl?", "", "print this help.", NULL }; r_core_cmd_help (core, help_message); } break; case ' ': { char *type = strdup (input + 2); char *ptr = strchr (type, '='); ut64 addr; if (ptr) { *ptr++ = 0; r_str_chop (ptr); if (ptr && *ptr) { addr = r_num_math (core->num, ptr); } else { eprintf ("address is unvalid\n"); free (type); break; } } else { addr = core->offset; } r_str_chop (type); char *tmp = sdb_get (core->anal->sdb_types, type, 0); if (tmp && *tmp) { r_anal_type_link (core->anal, type, addr); free (tmp); } else { eprintf ("unknown type %s\n", type); } free (type); } break; case 's': { int ptr; char *addr = strdup (input + 2); SdbKv *kv; SdbListIter *sdb_iter; SdbList *sdb_list = sdb_foreach_list (core->anal->sdb_types); r_str_chop (addr); ptr = r_num_math (NULL, addr); //r_core_cmdf (core, "tl~0x%08"PFMT64x" = ", addr); ls_foreach (sdb_list, sdb_iter, kv) { char *linkptr; if (strncmp (kv->key, "link.", strlen ("link."))) { continue; } linkptr = sdb_fmt (-1,"0x%s", kv->key + strlen ("link.")); if (ptr == r_num_math (NULL, linkptr)) { linklist_readable (core, kv->key, kv->value); } } free (addr); ls_free (sdb_list); } break; case '-': switch (input[2]) { case '*': sdb_foreach (core->anal->sdb_types, sdbdeletelink, core); break; case ' ': { const char *ptr = input + 3; ut64 addr = r_num_math (core->num, ptr); r_anal_type_unlink (core->anal, addr); } break; } break; case '*': sdb_foreach (core->anal->sdb_types, linklist, core); break; case '\0': sdb_foreach (core->anal->sdb_types, linklist_readable, core); break; }
int main(int argc, const char **argv) { char *line; int i, ret, fmt = MODE_DFLT; int db0 = 1, argi = 1; int interactive = 0; /* terminate flags */ if (argc<2) showusage (1); if (!strcmp (argv[1], "-d")) { if (argc == 4) return dbdiff (argv[2], argv[3]); showusage (0); } if (!strcmp (argv[1], "-v")) showversion (); if (!strcmp (argv[1], "-h")) showusage (2); if (!strcmp (argv[1], "-j")) { if (argc>2) return sdb_dump (argv[db0+1], MODE_JSON); eprintf ("Missing database filename after -j\n"); return 1; } /* flags */ if (!strcmp (argv[argi], "-0")) { fmt = MODE_ZERO; db0++; argi++; } if (!strcmp (argv[argi], "-")) { /* no database */ argv[argi] = ""; if (argc == db0+1) { interactive = 1; /* if no argument passed */ argv[argi] = "-"; argc++; argi++; } } if (argc-1 == db0) return sdb_dump (argv[db0], fmt); #if USE_MMAN signal (SIGINT, terminate); signal (SIGHUP, syncronize); #endif ret = 0; if (interactive || !strcmp (argv[db0+1], "-")) { if ((s = sdb_new (NULL, argv[db0], 0))) { save |= insertkeys (s, argv+3, argc-3, '-'); sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP); for (;(line = stdin_gets ());) { save |= sdb_query (s, line); if (fmt) { fflush (stdout); write (1, "", 1); } free (line); } } } else if (!strcmp (argv[db0+1], "=")) { ret = createdb (argv[db0], argv+db0+2, argc-(db0+2)); } else { s = sdb_new (NULL, argv[db0], 0); if (!s) return 1; sdb_config (s, SDB_OPTION_FS | SDB_OPTION_NOSTAMP); for (i=db0+1; i<argc; i++) { save |= sdb_query (s, argv[i]); if (fmt) { fflush (stdout); write (1, "", 1); } } } terminate (0); return ret; }