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, char **argv) { int c, bits = 0; int action = ACTION_UNK; const char *op = NULL; char *arch = NULL, *arch_name = NULL; ut64 offset; bin = r_bin_new (); 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 */ char *homeplugindir = r_str_home (".radare/plugins"); r_lib_opendir (l, getenv ("LIBR_PLUGINS")); r_lib_opendir (l, homeplugindir); r_lib_opendir (l, LIBDIR"/radare2/"); } while ((c = getopt (argc, argv, "Af:a:B:b:c:CdMm:n:@:VisSzIHelRwO:o:p:rvLhx")) != -1) { switch(c) { case 'A': action |= ACTION_LISTARCHS; break; case 'a': if (optarg) arch = strdup (optarg); break; case 'c': if (!optarg) { eprintf ("Missing argument for -c"); return 1; } action = ACTION_CREATE; create = strdup (optarg); break; case 'C': 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); action |= ACTION_SRCLINE; break; case 'i': action |= ACTION_IMPORTS; break; case 's': action |= ACTION_SYMBOLS; break; case 'S': action |= ACTION_SECTIONS; break; case 'z': action |= ACTION_STRINGS; break; case 'I': action |= ACTION_INFO; break; case 'H': action |= ACTION_FIELDS; break; case 'd': action |= ACTION_DWARF; break; case 'e': action |= ACTION_ENTRIES; break; case 'M': action |= ACTION_MAIN; break; case 'l': action |= ACTION_LIBS; break; case 'R': action |= ACTION_RELOCS; break; case 'x': action |= ACTION_EXTRACT; break; case 'w': rw = R_TRUE; break; case 'O': op = optarg; action |= ACTION_OPERATION; if (optind==argc) { eprintf ("Missing filename\n"); return 1; } // return rabin_do_operation (op); 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': gbaddr = r_num_math (NULL, optarg); break; case '@': at = r_num_math (NULL, optarg); break; case 'n': name = optarg; break; case 'V': printf ("rabin2 v"R2_VERSION"\n"); return 0; case 'h': default: action |= ACTION_HELP; } } file = argv[optind]; if (action == ACTION_HELP || action == ACTION_UNK || file == NULL) return rabin_show_help (); if (arch) { char *ptr; 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)); datalen = r_hex_str2bin (p2, data); } else { data = NULL; datalen = 0; } code = malloc (strlen (p)); 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; } if (!r_bin_load (bin, file, R_FALSE) && !r_bin_load (bin, file, R_TRUE)) { eprintf ("r_bin: Cannot open '%s'\n", file); return 1; } if (action & ACTION_LISTARCHS || ((arch || bits || arch_name) && !r_bin_select (bin, arch, bits, arch_name))) { r_bin_list_archs (bin); free (arch); free (arch_name); r_bin_free (bin); return 1; } if (gbaddr != 0LL) bin->curarch.baddr = gbaddr; RCore core; core.bin = bin; RCoreBinFilter filter; filter.offset = at; filter.name = name; offset = r_bin_get_offset (bin); r_cons_new ()->is_interactive = R_FALSE; if (action&ACTION_SECTIONS) r_core_bin_info (&core, R_CORE_BIN_ACC_SECTIONS, rad, va, &filter, 0); if (action&ACTION_ENTRIES) r_core_bin_info (&core, R_CORE_BIN_ACC_ENTRIES, rad, va, NULL, offset); if (action&ACTION_MAIN) r_core_bin_info (&core, R_CORE_BIN_ACC_MAIN, rad, va, NULL, offset); if (action&ACTION_IMPORTS) r_core_bin_info (&core, R_CORE_BIN_ACC_IMPORTS, rad, va, &filter, offset); if (action&ACTION_CLASSES) r_core_bin_info (&core, R_CORE_BIN_ACC_CLASSES, rad, va, NULL, 0); if (action&ACTION_SYMBOLS) r_core_bin_info (&core, R_CORE_BIN_ACC_SYMBOLS, rad, va, &filter, offset); if (action&ACTION_STRINGS) r_core_bin_info (&core, R_CORE_BIN_ACC_STRINGS, rad, va, NULL, 0); if (action&ACTION_INFO) r_core_bin_info (&core, R_CORE_BIN_ACC_INFO, rad, va, NULL, 0); if (action&ACTION_FIELDS) r_core_bin_info (&core, R_CORE_BIN_ACC_FIELDS, rad, va, NULL, 0); if (action&ACTION_LIBS) r_core_bin_info (&core, R_CORE_BIN_ACC_LIBS, rad, va, NULL, 0); if (action&ACTION_RELOCS) r_core_bin_info (&core, R_CORE_BIN_ACC_RELOCS, rad, va, NULL, 0); if (action&ACTION_DWARF) rabin_show_dwarf (&core); 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); free (arch); r_bin_free (bin); r_cons_flush (); return 0; }