static int main_print_var(const char *var_name) { int i = 0; char *confighome = r_str_home (R2_HOME_CONFIGDIR); char *datahome = r_str_home (R2_HOME_DATADIR); char *cachehome = r_str_home (R2_HOME_CACHEDIR); char *homeplugins = r_str_home (R2_HOME_PLUGINS); char *homezigns = r_str_home (R2_HOME_ZIGNS); char *plugins = r_str_r2_prefix (R2_PLUGINS); char *magicpath = r_str_r2_prefix (R2_SDB_MAGIC); struct radare2_var_t { const char *name; const char *value; } r2_vars[] = { { "R2_PREFIX", R2_PREFIX }, { "R2_MAGICPATH", magicpath }, { "R2_PREFIX", R2_PREFIX }, { "R2_INCDIR", R2_INCDIR }, { "R2_LIBDIR", R2_LIBDIR }, { "R2_LIBEXT", R_LIB_EXT }, { "R2_RCONFIGHOME", confighome }, { "R2_RDATAHOME", datahome }, { "R2_RCACHEHOME", cachehome }, { "R2_LIBR_PLUGINS", plugins }, { "R2_USER_PLUGINS", homeplugins }, { "R2_USER_ZIGNS", homezigns }, { NULL, NULL } }; int delta = 0; if (var_name && strncmp (var_name, "R2_", 3)) { delta = 3; } if (var_name) { while (r2_vars[i].name) { if (!strcmp (r2_vars[i].name + delta, var_name)) { printf ("%s\n", r2_vars[i].value); break; } i++; } } else { while (r2_vars[i].name) { printf ("%s=%s\n", r2_vars[i].name, r2_vars[i].value); i++; } } free (confighome); free (datahome); free (cachehome); free (homeplugins); free (homezigns); free (plugins); free (magicpath); return 0; }
static int r_core_project_init() { int ret; char *str = r_str_home (".radare2"); if (str && (ret = r_sys_mkdir (str))) { if (!ret) { free (str); str = r_str_home (".radare2/plugins"); ret = r_sys_mkdir (str); if (ret) eprintf ("Cannot create ~/.radare2/plugins\n"); } } str = r_str_home (".radare2/rdb"); ret = r_sys_mkdir (str); free (str); return ret; }
R_API RList *r_core_list_themes(RCore *core) { RList *files = NULL; RListIter *iter; const char *fn; char *home = r_str_home (".config/radare2/cons/"); RList *list = r_list_new (); getNext = false; if (home) { files = r_sys_dir (home); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { r_list_append (list, strdup (fn)); } } r_list_free (files); R_FREE (home); } files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/"); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { r_list_append (list, strdup (fn)); } } r_list_free (files); files = NULL; return list; }
static int r_core_visual_hud(RCore *core) { const char *f = R2_LIBDIR"/radare2/"R2_VERSION"/hud/main"; char *homehud = r_str_home (R2_HOMEDIR"/hud"); char *res = NULL; char *p = 0; showcursor (core, R_TRUE); if (homehud) res = r_cons_hud_file (homehud); if (!res) { if (r_file_exists (f)) res = r_cons_hud_file (f); else r_cons_message ("Cannot find hud file"); } r_cons_clear (); if (res) { p = strchr (res, '\t'); core->printidx = 1; r_cons_printf ("%s\n", res); r_cons_flush (); if (p) r_core_cmd0 (core, p+1); free (res); } showcursor (core, R_FALSE); r_cons_flush (); free (homehud); return (int)(size_t)p; }
R_API int r_core_visual_hud(RCore *core) { const char *c = r_config_get (core->config, "hud.path"); const char *f = R2_LIBDIR"/radare2/"R2_VERSION"/hud/main"; char *homehud = r_str_home (R2_HOMEDIR"/hud"); char *res = NULL; char *p = 0; showcursor (core, true); if (c && *c && r_file_exists (c)) res = r_cons_hud_file (c); if (!res && homehud) res = r_cons_hud_file (homehud); if (!res && r_file_exists (f)) res = r_cons_hud_file (f); if (!res) r_cons_message ("Cannot find hud file"); r_cons_clear (); if (res) { p = strchr (res, '\t'); r_cons_printf ("%s\n", res); r_cons_flush (); if (p) r_core_cmd0 (core, p+1); free (res); } showcursor (core, false); r_cons_flush (); free (homehud); return (int)(size_t)p; }
static bool cmd_load_theme(RCore *core, const char *_arg) { bool failed = false; char *path; if (!_arg || !*_arg) { return false; } char *arg = strdup (_arg); char *tmp = r_str_newf (R_JOIN_2_PATHS (R2_HOME_THEMES, "%s"), arg); char *home = tmp ? r_str_home (tmp) : NULL; free (tmp); tmp = r_str_newf (R_JOIN_2_PATHS (R2_THEMES, "%s"), arg); path = tmp ? r_str_r2_prefix (tmp) : NULL; free (tmp); if (!load_theme (core, home)) { if (load_theme (core, path)) { curtheme = r_str_dup (curtheme, arg); } else { if (load_theme (core, arg)) { curtheme = r_str_dup (curtheme, arg); } else { char *absfile = r_file_abspath (arg); eprintf ("eco: cannot open colorscheme profile (%s)\n", absfile); free (absfile); failed = true; } } } free (home); free (path); free (arg); return !failed; }
static void radare2_rc(RCore *r) { char* env_debug = r_sys_getenv ("R_DEBUG"); bool has_debug = false; if (env_debug) { has_debug = true; R_FREE (env_debug); } char *homerc = r_str_home (".radare2rc"); if (homerc && r_file_is_regular (homerc)) { if (has_debug) { eprintf ("USER CONFIG loaded from %s\n", homerc); } r_core_cmd_file (r, homerc); } free (homerc); homerc = r_str_home (".config/radare2/radare2rc"); if (homerc && r_file_is_regular (homerc)) { if (has_debug) { eprintf ("USER CONFIG loaded from %s\n", homerc); } r_core_cmd_file (r, homerc); } free (homerc); homerc = r_str_home (".config/radare2/radare2rc.d"); if (homerc) { if (r_file_is_directory (homerc)) { char *file; RListIter *iter; RList *files = r_sys_dir (homerc); r_list_foreach (files, iter, file) { if (*file != '.') { char *path = r_str_newf ("%s/%s", homerc, file); if (r_file_is_regular (path)) { if (has_debug) { eprintf ("USER CONFIG loaded from %s\n", homerc); } r_core_cmd_file (r, path); } free (path); } } r_list_free (files); } free (homerc); } }
static char *r_core_project_file(const char *file) { char buf[128]; if (!strchr (file, '/')) { snprintf (buf, sizeof (buf), ".radare2/rdb/%s", file); return r_str_home (buf); } return strdup (file); }
R_API void r_anal_xrefs_load(RAnal *anal, const char *prjfile) { char *path, *db = r_str_newf (R2_HOMEDIR"/projects/%s.d/xrefs", prjfile); path = r_str_home (db); //eprintf ("Open (%s)\n", path); sdb_free (DB); DB = sdb_new (path, "xrefs", 0); sdb_array_set (DB, "types", -1, "code,data", 0); free (db); }
R_API void r_anal_xrefs_load(RAnal *anal, const char *prjfile) { char *path, *db = r_str_dup_printf (R2_HOMEDIR"/rdb/%s.d/xrefs", prjfile); path = r_str_home (db); //eprintf ("Open (%s)\n", path); sdb_free (DB); DB = sdb_new (path, 0); sdb_aset (DB, "types", -1, "code"SDB_SS"data", 0); free (db); }
static bool inHomeWww(const char *path) { bool ret = false; char *homeWww = r_str_home (R2_HOME_WWWROOT R_SYS_DIR); if (homeWww) { if (!strncmp (path, homeWww, strlen (homeWww))) { ret = true; } free (homeWww); } return ret; }
static bool inHomeWww(const char *path) { bool ret = false; char *homeWww = r_str_home (".config/radare2/www/"); if (homeWww) { if (!strncmp (path, homeWww, strlen (homeWww))) { ret = true; } free (homeWww); } return ret; }
R_API int r_cons_pipe_open(const char *file, int fdn, int append) { char *targetFile; if (fdn < 1) { return -1; } if (!strncmp (file, "~/", 2) || !strncmp (file, "~\\", 2)) { targetFile = r_str_home (file + 2); } else { targetFile = strdup (file); } int fd = r_sandbox_open (targetFile, O_BINARY | O_RDWR | O_CREAT | (append? O_APPEND: O_TRUNC), 0644); if (fd==-1) { eprintf ("r_cons_pipe_open: Cannot open file '%s'\n", file); free (targetFile); return -1; }// else eprintf ("%s created\n", file); if (backup_fd != -1) { close (backup_fd); } backup_fdn = fdn; #if __WINDOWS__ && !__CYGWIN__ backup_fd = 2002-(fd-2); // windows xp has 2048 as limit fd if (_dup2 (fdn, backup_fd) == -1) { #else backup_fd = sysconf (_SC_OPEN_MAX)-(fd-2); // portable getdtablesize() if (backup_fd < 2) { backup_fd = 2002 - (fd - 2); // fallback } if (dup2 (fdn, backup_fd) == -1) { #endif eprintf ("Cannot dup stdout to %d\n", backup_fd); free (targetFile); return -1; } close (fdn); dup2 (fd, fdn); free (targetFile); return fd; } R_API void r_cons_pipe_close(int fd) { if (fd == -1) { return; } close (fd); if (backup_fd != -1) { dup2 (backup_fd, backup_fdn); close (backup_fd); backup_fd = -1; } }
R_API int r_core_loadlibs(struct r_core_t *core) { /* TODO: all those default plugin paths should be defined in r_lib */ char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins"); core->lib = r_lib_new ("radare_plugin"); r_core_loadlibs_init (core); r_lib_opendir (core->lib, r_config_get (core->config, "dir.plugins")); r_lib_opendir (core->lib, getenv (R_LIB_ENV)); // !!!! // r_lib_opendir (core->lib, "."); r_lib_opendir (core->lib, homeplugindir); r_lib_opendir (core->lib, R2_LIBDIR"/radare2/"); free (homeplugindir); return R_TRUE; }
R_API RList *r_core_list_themes(RCore *core) { RList *list = r_list_newf (free); getNext = false; char *path = r_str_home (R2_HOME_THEMES R_SYS_DIR); if (path) { list_themes_in_path (list, path); R_FREE (path); } path = r_str_r2_prefix (R2_THEMES R_SYS_DIR); if (path) { list_themes_in_path (list, path); R_FREE (path); } return list; }
static void nextpal(RCore *core, int mode) { RList *files; RListIter *iter; const char *fn; char *home = r_str_home (".config/radare2/cons/"); getNext = false; if (home) { files = r_sys_dir (home); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (!nextpal_item (core, mode, fn)) { r_list_free (files); R_FREE (home); goto done; } } } r_list_free (files); R_FREE (home); } files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/"); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (!nextpal_item (core, mode, fn)) goto done; } } done: if (getNext) { R_FREE (curtheme); nextpal (core, mode); return; } if (mode == 'l' && !curtheme && !r_list_empty (files)) { nextpal (core, mode); // beware infinite loop here return; } r_list_free (files); if (curtheme) { r_core_cmdf (core, "eco %s", curtheme); } }
static int main_print_var(const char *var_name) { int i = 0; char *homedir = r_str_home (R2_HOMEDIR); char *homeplugs = r_str_newf ("%s" R_SYS_DIR "plugins", homedir); char *homezigns = r_str_newf ("%s" R_SYS_DIR "zigns", homedir); struct radare2_var_t { const char *name; const char *value; } r2_vars[] = { { "R2_PREFIX", R2_PREFIX }, { "MAGICPATH", R_MAGIC_PATH }, { "PREFIX", R2_PREFIX }, { "INCDIR", R2_INCDIR }, { "LIBDIR", R2_LIBDIR }, { "LIBEXT", R_LIB_EXT }, { "RHOMEDIR", homedir }, { "LIBR_PLUGINS", R2_PREFIX"/lib/radare2/"R2_VERSION }, { "USER_PLUGINS", homeplugs }, { "USER_ZIGNS", homezigns }, { NULL, NULL } }; if (var_name) { while (r2_vars[i].name) { if (!strcmp (r2_vars[i].name, var_name)) { printf ("%s\n", r2_vars[i].value); break; } i++; } } else { while (r2_vars[i].name) { printf ("%s=%s\n", r2_vars[i].name, r2_vars[i].value); i++; } } free (homedir); free (homeplugs); free (homezigns); return 0; }
static int cmd_eval(void *data, const char *input) { char *p; RCore *core = (RCore *)data; switch (input[0]) { case 't': // env if (input[1] == 'a') { r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son"); } else if (input[1]==' ' && input[2]) { RConfigNode *node = r_config_node_get (core->config, input+2); if (node) { const char *type = r_config_node_type (node); if (type && *type) { r_cons_println (type); } } } else { eprintf ("Usage: et [varname] ; show type of eval var\n"); } break; case 'n': // env if (!strchr (input, '=')) { char *var, *p; var = strchr (input, ' '); if (var) while (*var==' ') var++; p = r_sys_getenv (var); if (p) { r_cons_println (p); free (p); } else { char **e = r_sys_get_environ (); while (e && *e) { r_cons_println (*e); e++; } } } else if (strlen (input)>3) { char *v, *k = strdup (input+3); if (!k) break; v = strchr (k, '='); if (v) { *v++ = 0; r_sys_setenv (k, v); } free (k); } return true; case 'x': // exit // XXX we need headers for the cmd_xxx files. return cmd_quit (data, ""); case 'j': // json r_config_list (core->config, NULL, 'j'); break; case 'v': // verbose r_config_list (core->config, input + 1, 'v'); break; case 'q': // quiet list of eval keys r_config_list (core->config, NULL, 'q'); break; case '\0': // "e" r_config_list (core->config, NULL, 0); break; case 'c': // "ec" switch (input[1]) { case 'd': r_cons_pal_init (NULL); break; case '?': { const char *helpmsg[] = { "Usage ec[s?] [key][[=| ]fg] [bg]","","", "ec","","list all color keys", "ec*","","same as above, but using r2 commands", "ecd","","set default palette", "ecr","","set random palette (see also scr.randpal)", "ecs","","show a colorful palette", "ecj","","show palette in JSON", "ecc"," [prefix]","show palette in CSS", "eco"," dark|white","load white color scheme template", "ecp","","load previous color theme", "ecn","","load next color theme", "ecH","[?]","highlight word or instruction", "ec"," prompt red","change color of prompt", "ec"," prompt red blue","change color and background of prompt", ""," ","", "colors:","","rgb:000, red, green, blue, ...", "e scr.rgbcolor","=1|0","for 256 color cube (boolean)", "e scr.truecolor","=1|0","for 256*256*256 colors (boolean)", "$DATADIR/radare2/cons","","~/.config/radare2/cons ./", NULL}; r_core_cmd_help (core, helpmsg); } break; case 'o': // "eco" if (input[2] == 'j') { nextpal (core, 'j'); } else if (input[2] == ' ') { bool failed = false; char *home, path[512]; snprintf (path, sizeof (path), ".config/radare2/cons/%s", input + 3); home = r_str_home (path); snprintf (path, sizeof (path), R2_DATDIR"/radare2/" R2_VERSION"/cons/%s", input + 3); if (!load_theme (core, home)) { if (load_theme (core, path)) { //curtheme = r_str_dup (curtheme, path); curtheme = r_str_dup (curtheme, input + 3); } else { if (load_theme (core, input + 3)) { curtheme = r_str_dup (curtheme, input + 3); } else { char *absfile = r_file_abspath (input + 3); eprintf ("eco: cannot open colorscheme profile (%s)\n", absfile); free (absfile); failed = true; } } } free (home); if (failed) { eprintf ("Something went wrong\n"); } } else if (input[2] == '?') { eprintf ("Usage: eco [themename] ;load theme from "R2_DATDIR"/radare2/"R2_VERSION"/cons/\n"); } else { nextpal (core, 'l'); } break; case 's': r_cons_pal_show (); break; // "ecs" case '*': r_cons_pal_list (1, NULL); break; // "ec*" case 'h': // echo if (( p = strchr (input, ' ') )) { r_cons_strcat (p+1); r_cons_newline (); } else { // "ech" r_cons_pal_list ('h', NULL); } break; case 'j': // "ecj" r_cons_pal_list ('j', NULL); break; case 'c': // "ecc" r_cons_pal_list ('c', input + 2); break; case '\0': // "ec" r_cons_pal_list (0, NULL); break; case 'r': // "ecr" r_cons_pal_random (); break; case 'n': // "ecn" nextpal (core, 'n'); break; case 'p': // "ecp" nextpal (core, 'p'); break; case 'H': { // "ecH" char *color_code = NULL; char *word = NULL; int argc = 0; char** argv = r_str_argv (input + 4, &argc); switch (input[2]) { case '?': { const char *helpmsg[] = { "Usage ecH[iw-?]","","", "ecHi","[color]","highlight current instruction with 'color' background", "ecHw","[word] [color]","highlight 'word ' in current instruction with 'color' background", "ecH-","","remove all highlights on current instruction", NULL }; r_core_cmd_help (core, helpmsg); } break; case '-': r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, ""); return false; case '\0': case 'i': // "ecHi if (argc) { char *dup = r_str_newf ("bgonly %s", argv[0]); color_code = r_cons_pal_parse (dup); R_FREE (dup); } break; case 'w': // "ecHw" if (!argc) { eprintf ("Usage: echw word [color]\n"); r_str_argv_free (argv); return true; } word = strdup (argv[0]); if (argc > 1) { char *dup = r_str_newf ("bgonly %s", argv[1]); color_code = r_cons_pal_parse (dup); if (!color_code) { eprintf ("Unknown color %s\n", argv[1]); r_str_argv_free (argv); free (dup); free (word); return true; } R_FREE (dup); } break; default: eprintf ("See ecH?\n"); r_str_argv_free (argv); return true; } char *str = r_meta_get_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset); char *dup = r_str_newf ("%s \"%s%s\"", str?str:"", word?word:"", color_code?color_code:r_cons_pal_get ("highlight")); r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, dup); r_str_argv_free (argv); R_FREE (word); R_FREE (dup); break; } default: { char *p = strdup (input + 2); char *q = strchr (p, '='); if (!q) { q = strchr (p, ' '); } if (q) { // set *q++ = 0; r_cons_pal_set (p, q); } else { const char *k = r_cons_pal_get (p); if (k) { eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k); } } free (p); } } break; case 'e': if (input[1] == ' ') { char *p; const char *val, *input2 = strchr (input+2, ' '); if (input2) input2++; else input2 = input+2; val = r_config_get (core->config, input2); p = r_core_editor (core, NULL, val); if (p) { r_str_replace_char (p, '\n', ';'); r_config_set (core->config, input2, p); } } else { eprintf ("Usage: ee varname\n"); } break; case '!': input = r_str_chop_ro (input+1); if (!r_config_toggle (core->config, input)) eprintf ("r_config: '%s' is not a boolean variable.\n", input); break; case 's': r_config_list (core->config, (input[1])? input + 1: NULL, 's'); break; case '-': r_core_config_init (core); //eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n"); break; case '*': r_config_list (core->config, NULL, 1); break; case '?': switch (input[1]) { case '?': r_config_list (core->config, input+2, 2); break; default: r_config_list (core->config, input+1, 2); break; case 0: r_core_cmd_help (core, help_msg_e); } break; case 'r': if (input[1]) { const char *key = input+((input[1]==' ')?2:1); if (!r_config_readonly (core->config, key)) { eprintf ("cannot find key '%s'\n", key); } } else { eprintf ("Usage: er [key]\n"); } break; case ' ': r_config_eval (core->config, input+1); break; default: r_config_eval (core->config, input); break; } 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; }
static int cmd_eval(void *data, const char *input) { char *p; RCore *core = (RCore *)data; switch (input[0]) { case 't': // env if (input[1]==' ' && input[2]) { RConfigNode *node = r_config_node_get (core->config, input+2); if (node) { const char *type = r_config_node_type (node); if (type && *type) { r_cons_printf ("%s\n", type); } } } else { eprintf ("Usage: et [varname] ; show type of eval var\n"); } break; case 'n': // env if (!strchr (input, '=')) { char *var, *p; var = strchr (input, ' '); if (var) while (*var==' ') var++; p = r_sys_getenv (var); if (p) { r_cons_printf ("%s\n", p); free (p); } else { char **e = r_sys_get_environ (); while (e && *e) { r_cons_printf ("%s\n", *e); e++; } } } else if (strlen (input)>3) { char *v, *k = strdup (input+3); if (!k) break; v = strchr (k, '='); if (v) { *v++ = 0; r_sys_setenv (k, v); } free (k); } return true; case 'x': // exit return cmd_quit (data, ""); case 'j': r_config_list (core->config, NULL, 'j'); break; case '\0': r_config_list (core->config, NULL, 0); break; case 'c': switch (input[1]) { case 'h': // echo if (( p = strchr (input, ' ') )) { r_cons_strcat (p+1); r_cons_newline (); } break; case 'd': r_cons_pal_init (NULL); break; case '?': { const char *helpmsg[] = { "Usage ec[s?] [key][[=| ]fg] [bg]","","", "ec","","list all color keys", "ec*","","same as above, but using r2 commands", "ecd","","set default palette", "ecr","","set random palette", "ecs","","show a colorful palette", "ecj","","show palette in JSON", "ecc","","show palette in CSS", "eco"," dark|white","load white color scheme template", "ecn","","load next color theme", "ec"," prompt red","change color of prompt", "ec"," prompt red blue","change color and background of prompt", ""," ","", "colors:","","rgb:000, red, green, blue, ...", "e scr.rgbcolor","=1|0","for 256 color cube (boolean)", "e scr.truecolor","=1|0","for 256*256*256 colors (boolean)", "$DATADIR/radare2/cons","","~/.config/radare2/cons ./", NULL}; r_core_cmd_help (core, helpmsg); } break; case 'o': // "eco" if (input[2] == ' ') { bool failed = false; char *home, path[512]; snprintf (path, sizeof (path), ".config/radare2/cons/%s", input+3); home = r_str_home (path); snprintf (path, sizeof (path), R2_DATDIR"/radare2/" R2_VERSION"/cons/%s", input+3); if (!r_core_cmd_file (core, home)) { if (r_core_cmd_file (core, path)) { //curtheme = r_str_dup (curtheme, path); curtheme = r_str_dup (curtheme, input + 3); } else { if (r_core_cmd_file (core, input+3)) { curtheme = r_str_dup (curtheme, input + 3); } else { eprintf ("eco: cannot open colorscheme profile (%s)\n", path); failed = true; } } } free (home); } else { nextpal (core, 'l'); } break; case 's': r_cons_pal_show (); break; case '*': r_cons_pal_list (1); break; case 'j': r_cons_pal_list ('j'); break; case 'c': r_cons_pal_list ('c'); break; case '\0': r_cons_pal_list (0); break; case 'r': // "ecr" r_cons_pal_random (); break; case 'n': // "ecn" nextpal (core, 'n'); break; default: { char *p = strdup (input + 2); char *q = strchr (p, '='); if (!q) q = strchr (p, ' '); if (q) { // set *q++ = 0; r_cons_pal_set (p, q); } else { const char *k = r_cons_pal_get (p); if (k) eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k); } free (p); } } break; case 'e': if (input[1]==' ') { char *p; const char *val, *input2 = strchr (input+2, ' '); if (input2) input2++; else input2 = input+2; val = r_config_get (core->config, input2); p = r_core_editor (core, NULL, val); if (p) { r_str_replace_char (p, '\n', ';'); r_config_set (core->config, input2, p); } } else eprintf ("Usage: ee varname\n"); break; case '!': input = r_str_chop_ro (input+1); if (!r_config_toggle (core->config, input)) eprintf ("r_config: '%s' is not a boolean variable.\n", input); break; case '-': r_core_config_init (core); //eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n"); break; case 'v': eprintf ("Invalid command '%s'. Use 'e?'\n", input); break; case '*': r_config_list (core->config, NULL, 1); break; case '?': switch (input[1]) { case '?': r_config_list (core->config, input+2, 2); break; default: r_config_list (core->config, input+1, 2); break; case 0:{ const char* help_msg[] = { "Usage:", "e[?] [var[=value]]", "Evaluable vars", "e","?asm.bytes", "show description", "e", "??", "list config vars with description", "e", "", "list config vars", "e-", "", "reset config vars", "e*", "", "dump config vars in r commands", "e!", "a", "invert the boolean value of 'a' var", "ee", "var", "open editor to change the value of var", "er", " [key]", "set config key as readonly. no way back", "ec", " [k] [color]", "set color for given key (prompt, offset, ...)", "et", " [key]", "show type of given config variable", "e", " a", "get value of var 'a'", "e", " a=b", "set var 'a' the 'b' value", "env", " [k[=v]]", "get/set environment variable", NULL}; r_core_cmd_help (core, help_msg); } } break; case 'r': if (input[1]) { const char *key = input+((input[1]==' ')?2:1); if (!r_config_readonly (core->config, key)) eprintf ("cannot find key '%s'\n", key); } else eprintf ("Usage: er [key]\n"); break; case ' ': r_config_eval (core->config, input+1); break; default: r_config_eval (core->config, input); break; } return 0; }
static void nextpal(RCore *core, int mode) { // TODO: use r_core_list_themes() here instead of rewalking all the time RList *files = NULL; RListIter *iter; const char *fn; int ctr = 0; char *home = r_str_home (".config/radare2/cons/"); getNext = false; if (mode == 'j') { r_cons_printf ("["); } if (home) { files = r_sys_dir (home); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (mode == 'p') { const char *nfn = iter->n? iter->n->data: NULL; if (!curtheme) { free (home); r_list_free (files); return; } eprintf ("%s %s %s\n", nfn, curtheme, fn); if (nfn && !strcmp (nfn, curtheme)) { r_list_free (files); files = NULL; free (curtheme); curtheme = strdup (fn); R_FREE (home); goto done; } } else { if (!nextpal_item (core, mode, fn, ctr++)) { r_list_free (files); files = NULL; R_FREE (home); goto done; } } } } r_list_free (files); R_FREE (home); } files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/"); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (mode == 'p') { const char *nfn = iter->n? iter->n->data: NULL; if (!curtheme) { free (home); r_list_free (files); return; } eprintf ("%s %s %s\n", nfn, curtheme, fn); if (nfn && !strcmp (nfn, curtheme)) { free (curtheme); curtheme = strdup (fn); goto done; } } else { if (!nextpal_item (core, mode, fn, ctr++)) { goto done; } } } } done: if (getNext) { R_FREE (curtheme); nextpal (core, mode); return; } if (mode == 'l' && !curtheme && !r_list_empty (files)) { //nextpal (core, mode); } else { if (curtheme) { r_core_cmdf (core, "eco %s", curtheme); } } r_list_free (files); files = NULL; if (mode == 'j') { r_cons_printf ("]\n"); } }
static char *expand_home(const char *p) { if (*p=='~') return r_str_home (p); return strdup (p); }
static int main_help(int line) { if (line < 2) { printf ("Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]\n" " [-s addr] [-B baddr] [-M maddr] [-c cmd] [-e k=v] file|pid|-|--|=\n"); } if (line != 1) { printf ( " -- run radare2 without opening any file\n" " - same as 'r2 malloc://512'\n" " = read file from stdin (use -i and -c to run cmds)\n" " -= perform !=! command to run all commands remotely\n" " -0 print \\x00 after init and every command\n" " -a [arch] set asm.arch\n" " -A run 'aaa' command to analyze all referenced code\n" " -b [bits] set asm.bits\n" " -B [baddr] set base address for PIE binaries\n" " -c 'cmd..' execute radare command\n" " -C file is host:port (alias for -c+=http://%%s/cmd/)\n" " -d debug the executable 'file' or running process 'pid'\n" " -D [backend] enable debug mode (e cfg.debug=true)\n" " -e k=v evaluate config var\n" " -f block size = file size\n" " -F [binplug] force to use that rbin plugin\n" " -h, -hh show help message, -hh for long\n" " -H ([var]) display variable\n" " -i [file] run script file\n" " -I [file] run script file before the file is opened\n" " -k [k=v] perform sdb query into core->sdb\n" " -l [lib] load plugin file\n" " -L list supported IO plugins\n" " -m [addr] map file at given address (loadaddr)\n" " -M do not demangle symbol names\n" " -n, -nn do not load RBin info (-nn only load bin structures)\n" " -N do not load user settings and scripts\n" " -o [OS/kern] set asm.os (linux, macos, w32, netbsd, ...)\n" " -q quiet mode (no prompt) and quit after -i\n" " -p [prj] use project, list if no arg, load if no file\n" " -P [file] apply rapatch file and quit\n" " -R [rarun2] specify rarun2 profile to load (same as -e dbg.profile=X)\n" " -s [addr] initial seek\n" " -S start r2 in sandbox mode\n" #if USE_THREADS " -t load rabin2 info in thread\n" #endif " -u set bin.filter=false to get raw sym/sec/cls names\n" " -v, -V show radare2 version (-V show lib versions)\n" " -w open file in write mode\n" " -X [rr2rule] specify custom rarun2 directive\n" " -z, -zz do not load strings or load them even in raw\n"); } if (line == 2) { char *homedir = r_str_home (R2_HOMEDIR); printf ( "Scripts:\n" " system "R2_PREFIX"/share/radare2/radare2rc\n" " user ~/.radare2rc ${RHOMEDIR}/radare2/radare2rc (and radare2rc.d/)\n" " file ${filename}.r2\n" "Plugins:\n" " binrc ~/.config/radare2/rc.d/bin-<format>/ (elf, elf64, mach0, ..)\n" " plugins "R2_PREFIX"/lib/radare2/last\n" " USER_PLUGINS ~/.config/radare2/plugins\n" " LIBR_PLUGINS "R2_PREFIX"/lib/radare2/"R2_VERSION"\n" " USER_ZIGNS ~/.config/radare2/zigns\n" "Environment:\n" " RHOMEDIR %s\n" // TODO: rename to RHOME R2HOME? " RCFILE ~/.radare2rc (user preferences, batch script)\n" // TOO GENERIC " MAGICPATH "R_MAGIC_PATH"\n" " R_DEBUG if defined, show error messages and crash signal\n" " VAPIDIR path to extra vapi directory\n" " R2_NOPLUGINS do not load r2 shared plugins\n" "Paths:\n" " PREFIX "R2_PREFIX"\n" " INCDIR "R2_INCDIR"\n" " LIBDIR "R2_LIBDIR"\n" " LIBEXT "R_LIB_EXT"\n" , homedir); free (homedir); } return 0; }
static int main_help(int line) { if (line < 2) { printf ("Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]\n" " [-s addr] [-B baddr] [-m maddr] [-c cmd] [-e k=v] file|pid|-|--|=\n"); } if (line != 1) { printf ( " -- run radare2 without opening any file\n" " - same as 'r2 malloc://512'\n" " = read file from stdin (use -i and -c to run cmds)\n" " -= perform !=! command to run all commands remotely\n" " -0 print \\x00 after init and every command\n" " -2 close stderr file descriptor (silent warning messages)\n" " -a [arch] set asm.arch\n" " -A run 'aaa' command to analyze all referenced code\n" " -b [bits] set asm.bits\n" " -B [baddr] set base address for PIE binaries\n" " -c 'cmd..' execute radare command\n" " -C file is host:port (alias for -c+=http://%%s/cmd/)\n" " -d debug the executable 'file' or running process 'pid'\n" " -D [backend] enable debug mode (e cfg.debug=true)\n" " -e k=v evaluate config var\n" " -f block size = file size\n" " -F [binplug] force to use that rbin plugin\n" " -h, -hh show help message, -hh for long\n" " -H ([var]) display variable\n" " -i [file] run script file\n" " -I [file] run script file before the file is opened\n" " -k [OS/kern] set asm.os (linux, macos, w32, netbsd, ...)\n" " -l [lib] load plugin file\n" " -L list supported IO plugins\n" " -m [addr] map file at given address (loadaddr)\n" " -M do not demangle symbol names\n" " -n, -nn do not load RBin info (-nn only load bin structures)\n" " -N do not load user settings and scripts\n" " -q quiet mode (no prompt) and quit after -i\n" " -Q quiet mode (no prompt) and quit faster (quickLeak=true)\n" " -p [prj] use project, list if no arg, load if no file\n" " -P [file] apply rapatch file and quit\n" " -r [rarun2] specify rarun2 profile to load (same as -e dbg.profile=X)\n" " -R [rr2rule] specify custom rarun2 directive\n" " -s [addr] initial seek\n" " -S start r2 in sandbox mode\n" #if USE_THREADS " -t load rabin2 info in thread\n" #endif " -u set bin.filter=false to get raw sym/sec/cls names\n" " -v, -V show radare2 version (-V show lib versions)\n" " -w open file in write mode\n" " -x open without exec-flag (asm.emu will not work), See io.exec\n" " -X same as -e bin.usextr=false (useful for dyldcache)\n" " -z, -zz do not load strings or load them even in raw\n"); } if (line == 2) { char *datahome = r_str_home (R2_HOME_DATADIR); const char *dirPrefix = r_sys_prefix (NULL); printf ( "Scripts:\n" " system ${R2_PREFIX}/share/radare2/radare2rc\n" " user ~/.radare2rc " R_JOIN_2_PATHS ("~", R2_HOME_RC) " (and " R_JOIN_3_PATHS ("~", R2_HOME_RC_DIR,"") ")\n" " file ${filename}.r2\n" "Plugins:\n" " binrc " R_JOIN_4_PATHS ("~", R2_HOME_BINRC, "bin-<format>", "") " (elf, elf64, mach0, ..)\n" " R2_USER_PLUGINS " R_JOIN_2_PATHS ("~", R2_HOME_PLUGINS) "\n" " R2_LIBR_PLUGINS " R_JOIN_2_PATHS ("%s", R2_PLUGINS) "\n" " R2_USER_ZIGNS " R_JOIN_2_PATHS ("~", R2_HOME_ZIGNS) "\n" "Environment:\n" " R2_RDATAHOME %s\n" // TODO: rename to RHOME R2HOME? " RCFILE ~/.radare2rc (user preferences, batch script)\n" // TOO GENERIC " R2_MAGICPATH " R_JOIN_2_PATHS ("%s", R2_SDB_MAGIC) "\n" " R_DEBUG if defined, show error messages and crash signal\n" " R_DEBUG_ASSERT=1 set a breakpoint when hitting an assert\n" " VAPIDIR path to extra vapi directory\n" " R2_NOPLUGINS do not load r2 shared plugins\n" "Paths:\n" " R2_PREFIX "R2_PREFIX"\n" " R2_INCDIR "R2_INCDIR"\n" " R2_LIBDIR "R2_LIBDIR"\n" " R2_LIBEXT "R_LIB_EXT"\n" , dirPrefix, datahome, dirPrefix); free (datahome); } 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': { 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 '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]) { 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+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; // 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 (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); } 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 ("Cannot find type at 0x%llx\n", addr); } break; case '?': show_help (core); break; }
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, 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; }