R_API int r_core_bin_set_env (RCore *r, RBinFile *binfile) { RBinObject *binobj = binfile ? binfile->o: NULL; RBinInfo *info = binobj ? binobj->info: NULL; if (info) { int va = info->has_va; const char * arch = info->arch; ut16 bits = info->bits; ut64 loadaddr = r_config_get_i (r->config, "bin.laddr"); ut64 baseaddr = binobj->baddr; /* Hack to make baddr work on some corner */ r_config_set_i (r->config, "io.va", (binobj->info)? binobj->info->has_va: 0); r_config_set_i (r->config, "bin.laddr", loadaddr); r_config_set_i (r->config, "bin.baddr", baseaddr); r_config_set (r->config, "asm.arch", arch); r_config_set_i (r->config, "asm.bits", bits); r_config_set (r->config, "anal.arch", arch); if (strlen(info->cpu)) r_config_set (r->config, "anal.cpu", info->cpu); else r_config_set (r->config, "anal.cpu", arch); r_asm_use (r->assembler, arch); r_core_bin_info (r, R_CORE_BIN_ACC_ALL, R_CORE_BIN_SET, va, NULL, loadaddr, NULL); r_core_bin_set_cur (r, binfile); return R_TRUE; } return R_FALSE; }
R_API RAnalHint *r_core_hint_begin (RCore *core, RAnalHint* hint, ut64 at) { // XXX not here static char *hint_arch = NULL; static int hint_bits = 0; if (hint) { r_anal_hint_free (hint); hint = NULL; } hint = r_anal_hint_get (core->anal, at); if (hint_arch) { r_config_set (core->config, "asm.arch", hint_arch); hint_arch = NULL; } if (hint_bits) { r_config_set_i (core->config, "asm.bits", hint_bits); hint_bits = 0; } if (hint) { /* arch */ if (hint->arch) { if (!hint_arch) hint_arch = strdup ( r_config_get (core->config, "asm.arch")); r_config_set (core->config, "asm.arch", hint->arch); } /* bits */ if (hint->bits) { if (!hint_bits) hint_bits = r_config_get_i (core->config, "asm.bits"); r_config_set_i (core->config, "asm.bits", hint->bits); } } return hint; }
static void setdiff (RCore *core) { char from[64], to[64]; prompt_read ("diff from: ", from, sizeof (from)); r_config_set (core->config, "diff.from", from); prompt_read ("diff to: ", to, sizeof (to)); r_config_set (core->config, "diff.to", to); }
R_API int r_core_setup_debugger (RCore *r, const char *debugbackend, bool attach) { int pid, *p = NULL; bool is_gdb = !strcmp (debugbackend, "gdb"); RIODesc * fd = r->file ? r_io_desc_get (r->io, r->file->fd) : NULL; const char *prompt = NULL; p = fd ? fd->data : NULL; r_config_set_i (r->config, "cfg.debug", 1); if (!p) { eprintf ("Invalid debug io\n"); return false; } r_config_set (r->config, "io.ff", "true"); r_core_cmdf (r, "dL %s", debugbackend); if (!is_gdb) { pid = r_io_desc_get_pid (fd); r_core_cmdf (r, "dp=%d", pid); if (attach) { r_core_cmdf (r, "dpa %d", pid); } } //this makes to attach twice showing warnings in the output //we get "resource busy" so it seems isn't an issue r_core_cmd (r, ".dr*", 0); /* honor dbg.bep */ { const char *bep = r_config_get (r->config, "dbg.bep"); if (bep) { if (!strcmp (bep, "loader")) { /* do nothing here */ } else if (!strcmp (bep, "entry")) { r_core_cmd (r, "dcu entry0", 0); } else { r_core_cmdf (r, "dcu %s", bep); } } } r_core_cmd (r, "sr PC", 0); /* set the prompt if it's not been set already by the callbacks */ prompt = r_config_get (r->config, "cmd.prompt"); if (prompt && !strcmp (prompt, "")) { if (r_config_get_i (r->config, "dbg.status")) { r_config_set (r->config, "cmd.prompt", ".dr*;drd;sr PC;pi 1;s-"); } else { r_config_set (r->config, "cmd.prompt", ".dr*"); } } r_config_set (r->config, "cmd.vprompt", ".dr*"); return true; }
static int cmd_quit(void *data, const char *input) { RCore *core = (RCore *)data; const char* help_msg[] = { "Usage:", "q[!][!] [retval]", "", "q","","quit program", "q!","","force quit (no questions)", "q!!","","force quit without saving history", "q"," 1","quit with return value 1", "q"," a-b","quit with return value a-b", NULL}; if (input) switch (*input) { case '?': r_core_cmd_help (core, help_msg); break; case '!': if (input[1] == '!') r_config_set (core->config, "scr.histsave", "false"); core->num->value = -1; return -2; case '\0': core->num->value = 0LL; return -2; default: if (*input == ' ') input++; if (*input) r_num_math (core->num, input); else core->num->value = 0LL; //exit (*input?r_num_math (core->num, input+1):0); //if (core->http_up) return R_FALSE; // cancel quit when http is running return -2; } return R_FALSE; }
static int cmd_project(void *data, const char *input) { RCore *core = (RCore *)data; const char *file, *arg = input+1; char *str = strdup (r_config_get (core->config, "file.project")); if (*arg==' ') arg++; file = input[1]?arg:str; switch (input[0]) { case 'o': // if (r_file_is_regular (file)) r_core_project_open (core, file); break; case 's': r_core_project_save (core, file); r_config_set (core->config, "file.project", file); break; case 'i': // if (r_file_is_regular (file)) free (r_core_project_info (core, file)); break; default: r_cons_printf ( "|Usage: P[?osi] [file]\n" "| Po [file] open project\n" "| Ps [file] save project\n" "| Pi [file] show project information\n" "|NOTE: See 'e file.project'\n" "|NOTE: project files are stored in ~/.config/radare2/rdb\n"); break; } free (str); return R_TRUE; }
static int config_dbgbackend_callback(void *user, void *data) { RCore *core = (RCore*) user; RConfigNode *node = (RConfigNode*) data; // XXX: remove this spagetti if (!strcmp (node->value, "bf")) r_config_set (core->config, "asm.arch", "bf"); r_debug_use (core->dbg, node->value); return R_TRUE; }
static bool r_anal_emul_init(RCore *core, bool *state) { state[ROMEM] = r_config_get_i (core->config, "esil.romem"); r_config_set (core->config, "esil.romem", "true"); state[ASM_TRACE] = r_config_get_i (core->config, "asm.trace"); r_config_set (core->config, "asm.trace", "true"); state[ANAL_TRACE] = r_config_get_i (core->config, "anal.trace"); r_config_set (core->config, "anal.trace", "true"); state[DBG_TRACE] = r_config_get_i (core->config, "dbg.trace"); r_config_set (core->config, "dbg.trace", "true"); state[NONULL] = r_config_get_i (core->config, "esil.nonull"); r_config_set (core->config, "esil.nonull", "true"); const char *bp = r_reg_get_name (core->anal->reg, R_REG_NAME_BP); const char *sp = r_reg_get_name (core->anal->reg, R_REG_NAME_SP); if ((bp && !r_reg_getv (core->anal->reg, bp)) || (sp && !r_reg_getv (core->anal->reg, sp))) { eprintf ("Stack isn't initiatized.\n"); eprintf ("Try running aei and aeim commands before aftm for default stack initialization\n"); return false; } return (core->anal->esil != NULL); }
static int config_asmarch_callback(void *user, void *data) { RCore *core = (RCore *) user; RConfigNode *node = (RConfigNode *) data; const char *asmos = r_config_get (core->config, "asm.os"); r_egg_setup (core->egg, node->value, core->anal->bits, 0, R_SYS_OS); if (!r_asm_use (core->assembler, node->value)) eprintf ("asm.arch: cannot find (%s)\n", node->value); if (!r_config_set (core->config, "anal.plugin", node->value)) { char *p, *s = strdup (node->value); p = strchr (s, '.'); if (p) *p = 0; r_config_set (core->config, "anal.plugin", s); free (s); } if (!r_syscall_setup (core->anal->syscall, node->value, asmos, core->anal->bits)) { //eprintf ("asm.arch: Cannot setup syscall '%s/%s' from '%s'\n", // node->value, asmos, R2_LIBDIR"/radare2/"R2_VERSION"/syscall"); } //if (!strcmp (node->value, "bf")) // r_config_set (core->config, "dbg.backend", "bf"); return R_TRUE; }
R_API void r_core_seek_archbits(RCore *core, ut64 addr) { int bits = 0; const char *arch = r_io_section_get_archbits (core->io, addr, &bits); if (!bits && !core->fixedbits) { //if we found bits related with anal hints pick it up __choose_bits_anal_hints (core, addr, &bits); } if (bits && !core->fixedbits) { r_config_set_i (core->config, "asm.bits", bits); } if (arch && !core->fixedarch) { r_config_set (core->config, "asm.arch", arch); } }
R_API boolt r_core_seek(RCore *core, ut64 addr, boolt rb) { RIOSection *newsection; ut64 old = core->offset; ut64 ret; /* XXX unnecesary call */ //r_io_set_fd (core->io, core->file->fd); core->io->section = core->section; // HACK ret = r_io_seek (core->io, addr, R_IO_SEEK_SET); newsection = core->io->section; if (ret == UT64_MAX) { //eprintf ("RET =%d %llx\n", ret, addr); /* XXX handle read errors correctly if (core->ffio) { core->offset = addr; } else return R_FALSE; */ //core->offset = addr; if (!core->io->va) return R_FALSE; memset (core->block, 0xff, core->blocksize); } else core->offset = addr; if (rb) { ret = r_core_block_read (core, 0); if (core->ffio) { if (ret<1 || ret > core->blocksize) memset (core->block, 0xff, core->blocksize); else memset (core->block+ret, 0xff, core->blocksize-ret); ret = core->blocksize; core->offset = addr; } else { if (ret<1) { core->offset = old; //eprintf ("Cannot read block at 0x%08"PFMT64x"\n", addr); } } } if (core->section != newsection) {//&& core->io->section->arch) { int bits = 0;// = core->io->section->bits; const char *arch = r_io_section_get_archbits (core->io, core->offset, &bits); if (arch && bits) { r_config_set (core->config, "asm.arch", arch); r_config_set_i (core->config, "asm.bits", bits); } core->section = core->io->section; } return (ret==-1)? R_FALSE: R_TRUE; }
static int textlog_chat(RCore *core) { char prompt[64]; char buf[1024]; int lastmsg = 0; const char *me = r_config_get (core->config, "cfg.user"); char msg[1024]; eprintf ("Type '/help' for commands:\n"); snprintf (prompt, sizeof (prompt) - 1, "[%s]> ", me); r_line_set_prompt (prompt); for (;;) { r_core_log_list (core, lastmsg, 0, 0); lastmsg = core->log->last; if (r_cons_fgets (buf, sizeof (buf) - 1, 0, NULL) < 0) { return 1; } if (!*buf) { continue; } if (!strcmp (buf, "/help")) { eprintf ("/quit quit the chat (same as ^D)\n"); eprintf ("/name <nick> set cfg.user name\n"); eprintf ("/log show full log\n"); eprintf ("/clear clear text log messages\n"); } else if (!strncmp (buf, "/name ", 6)) { snprintf (msg, sizeof (msg) - 1, "* '%s' is now known as '%s'", me, buf + 6); r_core_log_add (core, msg); r_config_set (core->config, "cfg.user", buf + 6); me = r_config_get (core->config, "cfg.user"); snprintf (prompt, sizeof (prompt) - 1, "[%s]> ", me); r_line_set_prompt (prompt); return 0; } else if (!strcmp (buf, "/log")) { r_core_log_list (core, 0, 0, 0); return 0; } else if (!strcmp (buf, "/clear")) { // r_core_log_del (core, 0); r_core_cmd0 (core, "T-"); return 0; } else if (!strcmp (buf, "/quit")) { return 0; } else if (*buf == '/') { eprintf ("Unknown command: %s\n", buf); } else { snprintf (msg, sizeof (msg) - 1, "[%s] %s", me, buf); r_core_log_add (core, msg); } } return 1; }
static int config_cfgdebug_callback(void *user, void *data) { RCore *core = (RCore*) user; RConfigNode *node = (RConfigNode*) data; if (!core) return R_FALSE; if (core->io) core->io->debug = node->i_value; if (core->dbg && node->i_value) { const char *dbgbackend = r_config_get (core->config, "dbg.backend"); r_debug_use (core->dbg, dbgbackend); if (!strcmp (dbgbackend, "bf")) r_config_set (core->config, "asm.arch", "bf"); if (core->file) { r_debug_select (core->dbg, core->file->fd->fd, core->file->fd->fd); } } else r_debug_use (core->dbg, NULL); return R_TRUE; }
R_API void r_core_seek_archbits(RCore *core, ut64 addr) { int bits = 0; const char *arch = NULL; RBinObject *o = r_bin_cur_object (core->bin); RBinSection *s = o? r_bin_get_section_at (o, addr, core->io->va): NULL; if (s) { arch = s->arch; bits = s->bits; } if (!bits && !core->fixedbits) { //if we found bits related with anal hints pick it up __choose_bits_anal_hints (core, addr, &bits); } if (bits && !core->fixedbits) { r_config_set_i (core->config, "asm.bits", bits); } if (arch && !core->fixedarch) { r_config_set (core->config, "asm.arch", arch); } }
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; }
R_API int r_core_config_init(RCore *core) { int i; char buf[128], *p; RConfig *cfg = cfg = core->config = r_config_new (core); cfg->printf = r_cons_printf; cfg->num = core->num; r_config_set (cfg, "dir.source", ""); r_config_desc (cfg, "dir.source", "Path to find source files"); r_config_set (cfg, "dir.magic", R_MAGIC_PATH); r_config_desc (cfg, "dir.magic", "Path to r_magic files"); r_config_set (cfg, "dir.plugins", LIBDIR"/radare2/"R2_VERSION"/"); r_config_desc (cfg, "dir.plugins", "Path to plugin files to be loaded at startup"); /* anal */ r_config_set (cfg, "anal.prelude", ""); r_config_desc (cfg, "anal.prelude", "Specify an hexpair to find preludes in code"); r_config_set_i (cfg, "anal.depth", 50); // XXX: warn if depth is > 50 .. can be problematic r_config_desc (cfg, "anal.depth", "Max depth at code analysis"); r_config_set_i (cfg, "anal.ptrdepth", 3); r_config_set_cb (cfg, "anal.split", "true", &config_analsplit_callback); r_config_set_cb (cfg, "anal.plugin", R_SYS_ARCH, &config_analplugin_callback); r_config_desc (cfg, "anal.plugin", "Specify the anal plugin to use"); /* asm */ r_config_set_cb (cfg, "asm.arch", R_SYS_ARCH, &config_asmarch_callback); r_config_desc (cfg, "asm.arch", "Set the arch to be usedd by asm"); // XXX: not portable r_parse_use (core->parser, "x86.pseudo"); r_config_set_cb (cfg, "asm.parser", "x86.pseudo", &config_asmparser_callback); r_config_set_i_cb (cfg, "asm.bits", 32, &config_asmbits_callback); r_config_desc (cfg, "asm.bits", "Word size in bits at assembler"); r_config_set (cfg, "asm.bytes", "true"); r_config_desc (cfg, "asm.bytes", "Display the bytes of each instruction"); r_config_set (cfg, "asm.flags", "true"); r_config_desc (cfg, "asm.bytes", "Show flags in disassembly (pd)"); r_config_set (cfg, "asm.size", "false"); r_config_desc (cfg, "asm.size", "Show size of opcodes in disassembly (pd)"); r_config_set (cfg, "asm.lbytes", "true"); r_config_desc (cfg, "asm.lbytes", "Align disasm bytes to left"); r_config_set (cfg, "asm.middle", "false"); // jump in the middle because of antidisasm tricks r_config_set (cfg, "asm.comments", "true"); r_config_desc (cfg, "asm.comments", "Show comments in disassembly view"); r_config_set (cfg, "asm.cmtright", "true"); r_config_desc (cfg, "asm.cmtright", "Show comments at right of disassembly if they fit in screen"); r_config_set (cfg, "asm.ucase", "false"); r_config_desc (cfg, "asm.ucase", "Use uppercase syntax at disassembly"); r_config_set (cfg, "asm.stackptr", "false"); r_config_desc (cfg, "asm.stackptr", "Show stack pointer at disassembly"); r_config_set (cfg, "asm.dwarf", "false"); r_config_desc (cfg, "asm.dwarf", "Show dwarf comment at disassembly"); r_config_set_i (cfg, "asm.nbytes", 8); r_config_set (cfg, "asm.tabs", "false"); r_config_desc (cfg, "asm.nbytes", "Number of bytes for each opcode at disassembly"); r_config_set (cfg, "asm.pseudo", "false"); // DEPRECATED ??? r_config_desc (cfg, "asm.pseudo", "Enable pseudo syntax"); r_config_set (cfg, "asm.filter", "true"); r_config_desc (cfg, "asm.filter", "Show filtered flags at disassembly"); r_config_set (cfg, "asm.varsub", "true"); r_config_desc (cfg, "asm.varsub", "Substitute variables in disasm"); r_config_set (cfg, "asm.trace", "true"); r_config_desc (cfg, "asm.trace", "Show execution traces for each opcode"); r_config_set (cfg, "asm.decode", "false"); r_config_desc (cfg, "asm.decode", "Use code analysis as a disassembler"); r_config_set (cfg, "asm.offset", "true"); r_config_desc (cfg, "asm.offset", "Show offsets at disassembly"); r_config_set (cfg, "asm.offseg", "false"); r_config_desc (cfg, "asm.offseg", "Show offsets as in 16 bit segment addressing mode"); r_config_set (cfg, "asm.lines", "true"); r_config_desc (cfg, "asm.lines", "If enabled show ascci-art lines at disassembly"); r_config_set (cfg, "asm.linesout", "true"); r_config_desc (cfg, "asm.linesout", "If enabled show out of block lines"); r_config_set (cfg, "asm.linesstyle", "false"); r_config_desc (cfg, "asm.linesstyle", "If enabled iterate the jump list backwards"); r_config_set (cfg, "asm.lineswide", "false"); r_config_desc (cfg, "asm.lineswide", "If enabled put an space between lines"); r_config_set_i_cb (cfg, "asm.lineswidth", 10, &config_asmlineswidth_callback); r_config_desc (cfg, "asm.lineswidth", ""); r_config_set (cfg, "asm.linescall", "false"); r_config_desc (cfg, "asm.linescall", "Enable call lines"); r_config_set_cb (cfg, "asm.os", R_SYS_OS, &config_asmos_callback); r_config_desc (cfg, "asm.os", "Select operating system (kernel) (linux, darwin, w32,..)"); r_config_set_cb (cfg, "asm.syntax", "intel", &config_asmsyntax_callback); r_config_desc (cfg, "asm.syntax", "Select assembly syntax"); r_config_set_cb (cfg, "asm.profile", "default", &config_asmprofile_callback); r_config_desc (cfg, "asm.profile", "configure disassembler (default, simple, gas, smart, debug, full)"); /* misc */ #if LIL_ENDIAN r_config_set_cb (cfg, "cfg.bigendian", "false", &config_bigendian_callback); #else r_config_set_cb (cfg, "cfg.bigendian", "true", &config_bigendian_callback); #endif r_config_desc (cfg, "cfg.bigendian", "Use little (false) or big (true) endiannes"); r_config_set_cb (cfg, "cfg.debug", "false", &config_cfgdebug_callback); r_config_desc (cfg, "cfg.debug", "set/unset the debugger mode"); r_config_set_cb (cfg, "cfg.datefmt", "%d:%m:%Y %H:%M:%S %z", &config_cfgdatefmt_callback); r_config_desc (cfg, "cfg.datefmt", "Date format (%d:%m:%Y %H:%M:%S %z)"); r_config_set (cfg, "cfg.fortunes", "true"); r_config_desc (cfg, "cfg.fortunes", "If enabled show tips at start"); r_config_set (cfg, "cfg.wseek", "false"); r_config_desc (cfg, "cfg.wseek", "Seek after write"); r_config_set_i (cfg, "cfg.hashlimit", SLURP_LIMIT); r_config_desc (cfg, "cfg.hashlimit", "If the file its bigger than hashlimit don't calculate the hash"); /* diff */ r_config_set_i (cfg, "diff.from", 0); r_config_desc (cfg, "diff.from", "set source diffing address for px (uses cc command)"); r_config_set_i (cfg, "diff.to", 0); r_config_desc (cfg, "diff.to", "set destination diffing address for px (uses cc command)"); /* debug */ if (core->cons->rows>30) // HACKY r_config_set_i (cfg, "dbg.follow", 64); else r_config_set_i (cfg, "dbg.follow", 32); r_config_desc (cfg, "dbg.follow", "Follow program counter when pc > core->offset + dbg.follow"); r_config_set_cb (cfg, "dbg.backend", "native", &config_dbgbackend_callback); r_config_desc (cfg, "dbg.backend", "Select the debugger backend"); r_config_set (cfg, "dbg.bep", "loader"); // loader, entry, constructor, main r_config_desc (cfg, "cfg.bep", "break on entrypoint (loader, entry, constructor, main)"); r_config_set_cb (cfg, "dbg.stopthreads", "true", &config_stopthreads_callback); r_config_desc (cfg, "dbg.stopthreads", "stop all threads when debugger breaks"); r_config_set_cb (cfg, "dbg.swstep", "false", &config_swstep_callback); r_config_desc (cfg, "dbg.swstep", "If enabled forces the use of software steps (code analysis+breakpoint)"); r_config_set_cb (cfg, "dbg.trace", "true", &config_trace_callback); r_config_desc (cfg, "dbg.trace", "enable debugger trace (see asm.trace)"); r_config_set_cb (cfg, "dbg.trace.tag", "0xff", &config_tracetag_callback); r_config_set_cb (cfg, "fs.view", "normal", &config_fsview_callback); r_config_desc (cfg, "fs.view", "Set visibility options for filesystems"); r_config_set (cfg, "hud.once", "false"); r_config_desc (cfg, "hud.once", "run"); r_config_set (cfg, "bin.strings", "true"); p = r_sys_getenv ("EDITOR"); #if __WINDOWS__ r_config_set (cfg, "cfg.editor", p? p: "notepad"); #else r_config_set (cfg, "cfg.editor", p? p: "vi"); #endif r_config_desc (cfg, "cfg.editor", "Select default editor program"); free (p); if (r_file_exist ("/usr/bin/xdot")) r_config_set (cfg, "cmd.graph", "!xdot a.dot"); else if (r_file_exist ("/usr/bin/open")) r_config_set (cfg, "cmd.graph", "!dot -Tgif -oa.gif a.dot;!open a.gif"); else if (r_file_exist ("/usr/bin/gqview")) r_config_set (cfg, "cmd.graph", "!dot -Tgif -oa.gif a.dot;!gqview a.gif"); else r_config_set (cfg, "cmd.graph", "!dot -Tgif -oa.gif a.dot;!gqview a.gif"); r_config_desc (cfg, "cmd.graph", "Command executed by 'agv' command to view graphs"); r_config_set (cfg, "cmd.hit", ""); r_config_desc (cfg, "cmd.hit", "Command to execute on every search hit"); r_config_set (cfg, "cmd.open", ""); r_config_desc (cfg, "cmd.open", "Command executed when file its opened"); r_config_set_cb (cfg, "cmd.repeat", "true", &config_cmdrepeat_callback); r_config_desc (cfg, "cmd.repeat", "Alias newline (empty command) as '..'"); r_config_set (cfg, "cmd.prompt", ""); r_config_desc (cfg, "cmd.prompt", "Prompt commands"); r_config_set (cfg, "cmd.cprompt", ""); r_config_desc (cfg, "cmd.cprompt", "Column visual prompt commands"); r_config_set (cfg, "cmd.vprompt", ""); r_config_desc (cfg, "cmd.vprompt", "Visual prompt commands"); r_config_set (cfg, "cmd.bp", ""); r_config_desc (cfg, "cmd.bp", "Command to executed every breakpoint hitted"); r_config_set (cfg, "graph.font", "Courier"); r_config_desc (cfg, "graph.font", "font to be used by the dot graphs"); r_config_set_cb (cfg, "scr.sparse", "false", config_scrsparse_callback); r_config_set_cb (cfg, "scr.interactive", "true", config_scrint_callback); r_config_set_cb (cfg, "scr.tee", "", config_teefile_callback); r_config_desc (cfg, "scr.tee", "Pipe console output to file if not empty"); r_config_set_cb (cfg, "scr.prompt", "true", &config_scrprompt_callback); r_config_set_cb (cfg, "scr.color", (core->print->flags&R_PRINT_FLAGS_COLOR)?"true":"false", &config_color_callback); r_config_desc (cfg, "scr.color", "Enable/Disable colors"); r_config_set_cb (cfg, "scr.pager", "", &config_pager_callback); r_config_desc (cfg, "scr.pager", "Select pager program (used if output doesn't fit on window)"); //r_config_set_cb (cfg, "scr.fkey", "function", &config_scrfkey_callback); r_config_set_cb (cfg, "scr.fkey", "hit", &config_scrfkey_callback); r_config_desc (cfg, "scr.fkey", "Select the seek mode in visual"); r_config_set (cfg, "scr.seek", ""); r_config_set_i_cb (cfg, "scr.cols", 16, &config_scrcols_callback); r_config_desc (cfg, "scr.cols", "Configure the number of columns to print"); r_config_set (cfg, "search.in", "file"); r_config_desc (cfg, "search.in", "Specify search boundaries (raw, block, file, section)"); r_config_set_i (cfg, "search.kwidx", 0); r_config_desc (cfg, "search.kwidx", "Store last search index count"); r_config_set (cfg, "search.show", "true"); r_config_desc (cfg, "search.show", "Show search results while found (disable if lot of hits)"); r_config_set (cfg, "search.flags", "true"); r_config_desc (cfg, "search.flags", "If enabled all search results are flagged, else just printed r2 commands"); r_config_set_i (cfg, "search.count", 0); r_config_desc (cfg, "search.count", "Start index number at search hits"); r_config_set (cfg, "search.prefix", "hit"); r_config_desc (cfg, "search.prefix", "Prefix name in search hits label"); r_config_set_i (cfg, "search.from", UT64_MAX); r_config_desc (cfg, "search.from", "Search start address"); r_config_set_i (cfg, "search.to", UT64_MAX); r_config_desc (cfg, "search.to", "Search end address"); r_config_set_i (cfg, "search.distance", 0); // TODO: use i_cb here and remove code in cmd.c r_config_desc (cfg, "search.distance", "Search string distance"); r_config_set_i_cb (cfg, "search.align", 0, &config_searchalign_callback); r_config_desc (cfg, "search.align", "Only catch aligned search hits"); r_config_set_cb (cfg, "scr.html", "false", &config_scrhtml_callback); r_config_desc (cfg, "scr.html", "If enabled disassembly use HTML syntax"); sprintf (buf, "%d", R_CORE_BLOCKSIZE_MAX); r_config_set_cb (cfg, "io.maxblk", buf, &config_iomaxblk_callback); r_config_desc (cfg, "io.maxblk", "set max block size (soft limit)"); r_config_set_cb (cfg, "io.ffio", "true", &config_ioffio_callback); r_config_desc (cfg, "io.ffio", "fill invalid buffers with 0xff instead of returning error"); r_config_set_cb (cfg, "io.va", "true", &config_iova_callback); r_config_desc (cfg, "io.va", "If enabled virtual address layout can be used"); r_config_set_cb (cfg, "io.cache", "false", &config_iocache_callback); r_config_desc (cfg, "io.cache", "Enable cache for io changes"); r_config_set (cfg, "file.analyze", "false"); r_config_desc (cfg, "file.analyze", "Analyze file on load. Same as r2 -c aa .."); r_config_set (cfg, "file.path", ""); r_config_desc (cfg, "file.path", "Path of current file"); r_config_set (cfg, "file.desc", ""); r_config_desc (cfg, "file.desc", "User defined file description. Used by projects"); r_config_set (cfg, "file.project", ""); r_config_desc (cfg, "file.project", "Name of current project"); r_config_set (cfg, "file.md5", ""); r_config_desc (cfg, "file.md5", "md5 sum of current file"); r_config_set (cfg, "file.sha1", ""); r_config_desc (cfg, "file.sha1", "sha1 hash of current file"); r_config_set (cfg, "file.type", ""); r_config_desc (cfg, "file.type", "Type of current file"); r_config_set_i (cfg, "magic.depth", 100); r_config_desc (cfg, "magic.depth", "Recursivity depth in magic description strings"); r_config_set (cfg, "rap.loop", "true"); r_config_desc (cfg, "rap.loop", "run rap as a forever-listening daemon"); /* fkeys */ for (i=1; i<13; i++) { snprintf (buf, sizeof (buf), "key.f%d", i); snprintf (buf+10, sizeof (buf)-10, "Run this when F%d key is pressed in visual mode", i); switch (i) { case 2: p = "dbs $$"; break; case 7: p = "ds"; break; case 8: p = "dso"; break; case 9: p = "dc"; break; default: p = ""; break; } r_config_set (cfg, buf, p); r_config_desc (cfg, buf, buf+10); } /* zoom */ r_config_set_i (cfg, "zoom.maxsz", 512); r_config_desc (cfg, "zoom.maxsz", "Zoom max size of block"); r_config_set_i (cfg, "zoom.from", 0); r_config_desc (cfg, "zoom.from", "Zoom start address"); r_config_set_i (cfg, "zoom.to", 0); r_config_desc (cfg, "zoom.to", "Zoom end address"); r_config_set_cb (cfg, "zoom.byte", "h", &config_zoombyte_callback); r_config_desc (cfg, "zoom.byte", "Zoom specific callback to calculate each byte (See pZ? for help)"); /* TODO cmd */ #if 0 config_set("asm.section", "true"); config_set("asm.reladdr", "false"); // relative offset config_set("asm.functions", "true"); config_set_i("asm.nlines", 6); // show left ref lines config_set("asm.lineswide", "false"); // show left ref lines config_set("asm.trace", "false"); // trace counter config_set("asm.split", "true"); // split code blocks config_set("asm.splitall", "false"); // split code blocks // config_set("asm.follow", ""); config_set("cmd.wp", ""); config_set("cmd.flag", "true"); config_set("cmd.asm", ""); config_set("cmd.user", ""); config_set("cmd.trace", ""); config_set("cmd.visual", ""); config_set("cmd.visualbind", ""); config_set("cmd.touchtrace", ""); config_set("search.flag", "true"); config_set("search.verbose", "true"); config_set("file.id", "false"); config_set("file.flag", "false"); config_set("file.trace", "trace.log"); config_set("file.project", ""); config_set("file.entrypoint", ""); node = config_set("file.scrfilter", ""); node->callback = &config_filterfile_callback; config_set_i("file.size", 0); node = config_set_i("io.vaddr", 0); // OLD file.baddr node->callback = &config_vaddr_callback; node = config_set_i("io.paddr", 0); // physical address node->callback = &config_paddr_callback; config_set("dump.regs", "true"); config_set("dump.user", "true"); config_set("dump.libs", "true"); config_set("dump.fds", "true"); config_set("trace.bt", "false"); config_set("trace.bps", "false"); config_set("trace.calls", "false"); config_set_i("trace.sleep", 0); config_set("trace.smart", "false"); config_set("trace.libs", "true"); config_set("trace.log", "false"); config_set("trace.dup", "false"); config_set("trace.cmtregs", "false"); config_set("cfg.editor", "vi"); node = config_set("cfg.debug", "false"); node->callback = &config_debug_callback; config_set("cfg.noscript", "false"); config_set("cfg.sections", "true"); config_set("cfg.encoding", "ascii"); // cp850 config_set_i("cfg.delta", 4096); // cp850 node = config_set("cfg.verbose", "true"); node->callback = &config_verbose_callback; config_set("cfg.inverse", "false"); config_set_i("cfg.analdepth", 6); config_set("file.insert", "false"); config_set("file.insertblock", "false"); config_set("file.undowrite", "true"); if (first) { node = config_set("file.write", "false"); node->callback = &config_wmode_callback; } node = config_set("cfg.limit", "0"); node->callback = &config_limit_callback; #if __mips__ // ??? config_set("cfg.addrmod", "32"); #else config_set("cfg.addrmod", "4"); #endif config_set("cfg.datefmt", "%d:%m:%Y %H:%M:%S %z"); config_set_i("cfg.count", 0); node = config_set_i("cfg.bsize", 512); node->callback = &config_bsize_callback; config_set_i("cfg.vbsize", 1024); config_set("cfg.vbsize_enabled", "false"); config_set_i("range.from", 0); config_set_i("range.to", 0xffff); config_set("range.traces", "true"); config_set("range.graphs", "true"); config_set("range.functions", "true"); config_set("child.stdio", ""); config_set("child.stdin", ""); config_set("child.stdout", ""); config_set("child.stderr", ""); config_set("child.setgid", ""); // must be int ? config_set("child.chdir", "."); config_set("child.chroot", "/"); config_set("child.setuid", ""); #if __mips__ config_set("dbg.fpregs", "true"); #else config_set("dbg.fpregs", "false"); #endif config_set("dbg.forks", "false"); // stop debugger in any fork or clone config_set("dbg.controlc", "true"); // stop debugger if ^C is pressed config_set_i("dbg.focus", 0); // focus on ps.pid or not (ignore events of rest of procs) config_set("dbg.syms", "true"); config_set("dbg.stepo", "false"); // step over for !contu (debug_step()) config_set("dbg.maps", "true"); config_set("dbg.sections", "true"); config_set("dbg.strings", "false"); config_set("dbg.stop", "false"); config_set("dbg.threads", "false"); config_set("dbg.contscbt", "true"); config_set("dbg.contsc2", "true"); // WTF? config_set("dbg.regs", "true"); config_set("dbg.regs2", "false"); config_set("dbg.stack", "true"); config_set("dbg.vstack", "true"); config_set("dbg.wptrace", "false"); config_set_i("dbg.stacksize", 66); config_set("dbg.stackreg", "esp"); config_set("dbg.bt", "false"); config_set_i("dbg.btlast", 0); config_set("dbg.fullbt", "false"); // user backtrace or lib+user backtrace config_set("dbg.bttype", "default"); // default, st and orig or so! #if __APPLE__ || __ARM__ || __mips__ config_set("dbg.hwbp", "false"); // default, st and orig or so! #else config_set("dbg.hwbp", "true"); // hardware breakpoints by default // ALSO BSD #endif config_set("dir.home", getenv("HOME")); /* dir.monitor */ ptr = getenv("MONITORPATH"); if (ptr == NULL) { sprintf(buf, "%s/.radare/monitor/", ("HOME")); ptr = (const char *)&buf; } config_set("dir.monitor", ptr); config_set("graph.split", "false"); // split blocks // SHOULD BE TRUE, but true algo is buggy config_set("graph.jmpblocks", "true"); config_set("graph.refblocks", "false"); // must be circle nodes config_set("graph.callblocks", "false"); config_set("graph.flagblocks", "true"); config_set_i("graph.depth", 9); config_set("graph.offset", "true"); config_set("graph.render", "cairo"); // aalib/ncurses/text config_set("graph.layout", "default"); // graphviz #endif r_config_lock (cfg, R_TRUE); return R_TRUE; }
static int cb(RDiff *d, void *user, RDiffOp *op) { int i; //, diffmode = (int)(size_t)user; if (showcount) { count++; return 1; } switch (diffmode) { case 'r': if (disasm) { eprintf ("r2cmds (-r) + disasm (-D) not yet implemented\n"); } if (op->a_len == op->b_len) { printf ("wx "); for (i=0; i<op->b_len; i++) printf ("%02x", op->b_buf[i]); printf (" @ 0x%08"PFMT64x"\n", op->b_off); } else { if ((op->a_len)>0) printf ("r-%d @ 0x%08"PFMT64x"\n", op->a_len, op->a_off+delta); if (op->b_len> 0) { printf ("r+%d @ 0x%08"PFMT64x"\n", op->b_len, op->b_off+delta); printf ("wx "); for (i=0; i<op->b_len; i++) printf ("%02x", op->b_buf[i]); printf (" @ 0x%08"PFMT64x"\n", op->b_off+delta); } delta += (op->b_off - op->a_off); } return 1; case 'j': if (disasm) { eprintf ("JSON (-j) + disasm (-D) not yet implemented\n"); } if (json_started) printf(",\n"); json_started = 1; printf ("{\"offset\":%"PFMT64d",", op->a_off); printf("\"from\":\""); for (i = 0;i<op->a_len;i++) printf ("%02x", op->a_buf[i]); printf ("\", \"to\":\""); for (i=0; i<op->b_len; i++) printf ("%02x", op->b_buf[i]); printf ("\"}"); //,\n"); return 1; case 0: default: if (disasm) { printf ("--- 0x%08"PFMT64x"\n", op->a_off); if (!core) { core = opencore (file); if (arch) { r_config_set (core->config, "asm.arch", arch); } if (bits) { r_config_set_i (core->config, "asm.bits", bits); } } if (core) { RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->a_buf, op->a_len); printf ("%s\n", ac->buf_asm); //r_asm_code_free (ac); } } else { printf ("0x%08"PFMT64x" ", op->a_off); for (i = 0; i < op->a_len; i++) printf ("%02x", op->a_buf[i]); } if (disasm) { printf ("+++ 0x%08"PFMT64x"\n", op->b_off); if (!core) { core = opencore (NULL); } if (core) { RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->b_buf, op->b_len); printf ("%s\n", ac->buf_asm); //r_asm_code_free (ac); } } else { printf (" => "); for (i=0; i < op->b_len; i++) printf ("%02x", op->b_buf[i]); printf (" 0x%08"PFMT64x"\n", op->b_off); } return 1; } }
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { char buf[32]; RSocketHTTPRequest *rs; int iport, oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); char *allow = (char *)r_config_get (core->config, "http.allow"); if (core->http_up) { eprintf ("http server is already running\n"); return 1; } if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } if (path && atoi (path)) { port = path; path = NULL; } if (!strcmp (port, "0")) { r_num_irand (); iport = 1024+r_num_rand (45256); snprintf (buf, sizeof (buf), "%d", iport); port = buf; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); core->http_up = R_TRUE; while (!r_cons_singleton ()->breaked) { r_cons_break ((RConsBreak)http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (100); continue; } if (allow && *allow) { int accepted = R_FALSE; const char *host; char *p, *peer = r_socket_to_string (rs->s); char *allows = strdup (allow); //eprintf ("Firewall (%s)\n", allows); int i, count = r_str_split (allows, ','); p = strchr (peer, ':'); if (p) *p = 0; for (i=0; i<count; i++) { host = r_str_word_get0 (allows, i); //eprintf ("--- (%s) (%s)\n", host, peer); if (!strcmp (host, peer)) { accepted = R_TRUE; break; } } free (peer); free (allows); if (!accepted) { r_socket_http_close (rs); continue; } } if (!rs->method || !rs->path) { eprintf ("Invalid http headers received from client\n"); r_socket_http_close (rs); continue; } char *dir = NULL; if (r_config_get_i (core->config, "http.dirlist")) if (r_file_is_directory (rs->path)) dir = strdup (rs->path); if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = rtr_dir_files (uproot); r_socket_http_response (rs, 200, ptr, 0, NULL); free (ptr); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) { char *cmd = rs->path +5; char foo[32]; const char *httpcmd = r_config_get (core->config, "http.uri"); while (*cmd=='/') cmd++; if (httpcmd && *httpcmd) { int len; char *res; // do remote http query and proxy response snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd); res = r_socket_http_get (foo, NULL, &len); if (res) { res[len]=0; r_cons_printf ("%s\n", res); } } else { char *out, *cmd = rs->path+5; r_str_uri_decode (cmd); // eprintf ("CMD (%s)\n", cmd); out = r_core_cmd_str_pipe (core, cmd); // eprintf ("\nOUT LEN = %d\n", strlen (out)); if (out) { char *res = r_str_uri_encode (out); r_socket_http_response (rs, 200, out, 0, "Content-Type: text/plain\n"); free (out); free (res); } else r_socket_http_response (rs, 200, "", 0, NULL); } } else { const char *root = r_config_get (core->config, "http.root"); char *path = r_file_root (root, rs->path); // FD IS OK HERE if (rs->path [strlen (rs->path)-1] == '/') { path = r_str_concat (path, "index.html"); //rs->path = r_str_concat (rs->path, "index.html"); } else { //snprintf (path, sizeof (path), "%s/%s", root, rs->path); if (r_file_is_directory (path)) { char res[128]; snprintf (res, sizeof (res), "Location: %s/\n", rs->path); r_socket_http_response (rs, 302, NULL, 0, res); r_socket_http_close (rs); free (path); free (dir); dir = NULL; continue; } } if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { const char *contenttype = NULL; if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n"; if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n"; if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n"; r_socket_http_response (rs, 200, f, sz, contenttype); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); eprintf ("Dirlisting %s\n", dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else if (!strcmp (rs->method, "POST")) { ut8 *ret; int retlen; char buf[128]; if (r_config_get_i (core->config, "http.upload")) { ret = r_socket_http_handle_upload ( rs->data, rs->data_length, &retlen); if (ret) { ut64 size = r_config_get_i (core->config, "http.maxsize"); if (size && retlen > size) { r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL); } else { char *filename = r_file_root ( r_config_get (core->config, "http.uproot"), rs->path + 4); eprintf ("UPLOADED '%s'\n", filename); r_file_dump (filename, ret, retlen); free (filename); snprintf (buf, sizeof (buf), "<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen); r_socket_http_response (rs, 200, buf, 0, NULL); } free (ret); } } else { r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL); } } else { r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL); } r_socket_http_close (rs); free (dir); } core->http_up = R_FALSE; r_socket_free (s); r_cons_break_end (); r_config_set_i (core->config, "scr.html", x); r_config_set_i (core->config, "scr.color", y); r_config_set_i (core->config, "asm.bytes", z); r_config_set_i (core->config, "scr.interactive", u); r_config_set_i (core->config, "asm.cmtright", v); if (oldsandbox != -1) r_config_set_i (core->config, "cfg.sandbox", oldsandbox); return 0; }
static int bin_info(RCore *r, int mode) { int i, j; char str[R_FLAG_NAME_SIZE]; char size_str[32]; char baddr_str[32]; RBinInfo *info = r_bin_get_info (r->bin); RBinFile *binfile = r_core_bin_cur (r); const char *compiled = NULL; if (!binfile || !info) { if (mode & R_CORE_BIN_JSON) r_cons_printf ("{}"); return false; } compiled = get_compile_time (binfile->sdb); snprintf (size_str, sizeof (size_str), "%"PFMT64d, r_bin_get_size (r->bin)); snprintf (baddr_str, sizeof (baddr_str), "%"PFMT64d, info->baddr); if (IS_MODE_SET (mode)) { r_config_set (r->config, "file.type", info->rclass); r_config_set (r->config, "cfg.bigendian", info->big_endian ? "true" : "false"); if (info->rclass && !strcmp (info->rclass, "fs")) { r_config_set (r->config, "asm.arch", info->arch); r_core_cmdf (r, "m /root %s 0", info->arch); } else { if (info->lang) { r_config_set (r->config, "bin.lang", info->lang); } r_config_set (r->config, "asm.os", info->os); r_config_set (r->config, "asm.arch", info->arch); r_config_set (r->config, "anal.arch", info->arch); snprintf (str, R_FLAG_NAME_SIZE, "%i", info->bits); r_config_set (r->config, "asm.bits", str); r_config_set (r->config, "asm.dwarf", (R_BIN_DBG_STRIPPED &info->dbg_info) ? "false" : "true"); } } else if (IS_MODE_SIMPLE (mode)) { r_cons_printf ("arch %s\n", info->arch); r_cons_printf ("bits %d\n", info->bits); r_cons_printf ("os %s\n", info->os); r_cons_printf ("endian %s\n", info->big_endian? "big": "little"); } else if (IS_MODE_RAD (mode)) { if (info->type && !strcmp (info->type, "fs")) { r_cons_printf ("e file.type=fs\n"); r_cons_printf ("m /root %s 0\n", info->arch); } else { r_cons_printf ("e cfg.bigendian=%s\n" "e asm.bits=%i\n" "e asm.dwarf=%s\n", r_str_bool (info->big_endian), info->bits, r_str_bool (R_BIN_DBG_STRIPPED &info->dbg_info)); if (info->lang && *info->lang) { r_cons_printf ("e bin.lang=%s\n", info->lang); } if (info->rclass && *info->rclass) { r_cons_printf ("e file.type=%s\n", info->rclass); } if (info->os) { r_cons_printf ("e asm.os=%s\n", info->os); } if (info->arch) { r_cons_printf ("e asm.arch=%s\n", info->arch); } } } else { // XXX: if type is 'fs' show something different? if (IS_MODE_JSON (mode)) r_cons_printf ("{"); pair_bool ("pic", info->has_pi, mode, false); pair_bool ("canary", info->has_canary, mode, false); pair_bool ("nx", info->has_nx, mode, false); pair_bool ("crypto", info->has_crypto, mode, false); pair_bool ("va", info->has_va, mode, false); pair_str ("bintype", info->rclass, mode, false); pair_str ("class", info->bclass, mode, false); pair_str ("lang", info->lang, mode, false); pair_str ("arch", info->arch, mode, false); pair_int ("bits", info->bits, mode, false); pair_str ("machine", info->machine, mode, false); pair_str ("os", info->os, mode, false); pair_str ("subsys", info->subsystem, mode, false); pair_str ("endian", info->big_endian ? "big" : "little", mode, false); pair_bool ("stripped", R_BIN_DBG_STRIPPED & info->dbg_info, mode, false); pair_bool ("static", r_bin_is_static (r->bin), mode, false); pair_bool ("linenum", R_BIN_DBG_LINENUMS & info->dbg_info, mode, false); pair_bool ("lsyms", R_BIN_DBG_SYMS & info->dbg_info, mode, false); pair_bool ("relocs", R_BIN_DBG_RELOCS & info->dbg_info, mode, false); pair_str ("rpath", info->rpath, mode, false); pair_str ("binsz", size_str, mode, false); pair_str ("compiled", compiled, mode, false); pair_str ("guid", info->guid, mode, false); pair_str ("dbg_file", info->debug_file_name, mode, true); for (i = 0; info->sum[i].type; i++) { int len; RBinHash *h = &info->sum[i]; ut64 hash = r_hash_name_to_bits (h->type); RHash *rh = r_hash_new (true, hash); len = r_hash_calculate (rh, hash, (const ut8*) binfile->buf->buf+h->from, h->to); if (len < 1) eprintf ("Invaild wtf\n"); r_hash_free (rh); r_cons_printf ("%s\t%d-%dc\t", h->type, h->from, h->to+h->from); for (j = 0; j < h->len; j++) { r_cons_printf ("%02x", h->buf[j]); } r_cons_newline (); } if (IS_MODE_JSON (mode)) r_cons_printf ("}"); } return true; }
int main(int argc, char **argv) { const char *addr = NULL; RCore *c, *c2; RDiff *d; const char *arch = NULL; int bits = 0; char *file, *file2; ut8 *bufa, *bufb; int o, sza, szb, /*diffmode = 0,*/ delta = 0; int mode = MODE_DIFF; int diffops = 0; int threshold = -1; int gdiff_mode = 0; double sim; while ((o = getopt (argc, argv, "a:b:Cnpg:Ojrhcdsvxt:")) != -1) { switch (o) { case 'a': arch = optarg; break; case 'b': bits = atoi (optarg); break; case 'p': useva = R_FALSE; break; case 'r': diffmode = 'r'; break; case 'g': mode = MODE_GRAPH; addr = optarg; break; case 'c': showcount = 1; break; case 'C': mode = MODE_CODE; gdiff_mode++; break; case 'n': showbare = R_TRUE; break; case 'O': diffops = 1; break; case 't': threshold = atoi (optarg); printf ("%s\n", optarg); break; case 'd': delta = 1; break; case 'h': return show_help (1); case 's': mode = MODE_DIST; break; case 'x': mode = MODE_COLS; break; case 'v': printf ("radiff2 v"R2_VERSION"\n"); return 0; case 'j': diffmode = 'j'; break; default: return show_help (0); } } if (argc<3 || optind+2>argc) return show_help (0); if (optind<argc) { file = argv[optind]; } else { file = NULL; } if (optind+1<argc) { file2 = argv[optind+1]; } else { file2 = NULL; } switch (mode) { case MODE_GRAPH: case MODE_CODE: c = opencore (file); if (!c) eprintf ("Cannot open '%s'\n", r_str_get (file)); c2 = opencore (file2); if (!c || !c2) { eprintf ("Cannot open '%s'\n", r_str_get (file2)); return 1; } if (arch) { r_config_set (c->config, "asm.arch", arch); r_config_set (c2->config, "asm.arch", arch); } if (bits) { r_config_set_i (c->config, "asm.bits", bits); r_config_set_i (c2->config, "asm.bits", bits); } r_config_set_i (c->config, "diff.bare", showbare); r_config_set_i (c2->config, "diff.bare", showbare); r_anal_diff_setup_i (c->anal, diffops, threshold, threshold); r_anal_diff_setup_i (c2->anal, diffops, threshold, threshold); if (mode == MODE_GRAPH) { char *words = strdup (addr); char *second = strstr (words, ","); if (second) { ut64 off; *second++ = 0; off = r_num_math (c->num, words); // define the same function at each offset r_core_anal_fcn (c, off, UT64_MAX, R_ANAL_REF_TYPE_NULL, 0); r_core_anal_fcn (c2, r_num_math (c2->num, second), UT64_MAX, R_ANAL_REF_TYPE_NULL, 0); r_core_gdiff (c, c2, R_FALSE); // compute the diff r_core_anal_graph (c, off, R_CORE_ANAL_GRAPHBODY | R_CORE_ANAL_GRAPHDIFF); } else { r_core_anal_fcn (c, r_num_math (c->num, words), UT64_MAX, R_ANAL_REF_TYPE_NULL, 0); r_core_anal_fcn (c2, r_num_math (c2->num, words), UT64_MAX, R_ANAL_REF_TYPE_NULL, 0); r_core_gdiff (c, c2, gdiff_mode); r_core_anal_graph (c, r_num_math (c->num, addr), R_CORE_ANAL_GRAPHBODY | R_CORE_ANAL_GRAPHDIFF); } free (words); } else { r_core_gdiff (c, c2, gdiff_mode); r_core_diff_show (c, c2); } r_cons_flush (); return 0; } bufa = (ut8*)r_file_slurp (file, &sza); if (!bufa) { eprintf ("radiff2: Cannot open %s\n", r_str_get (file)); return 1; } bufb = (ut8*)r_file_slurp (file2, &szb); if (!bufb) { eprintf ("radiff2: Cannot open: %s\n", r_str_get (file2)); free (bufa); return 1; } switch (mode) { case MODE_COLS: { int cols = (r_cons_get_size (NULL)>112)?16:8; dump_cols (bufa, sza, bufb, szb, cols); } break; case MODE_DIFF: d = r_diff_new (0LL, 0LL); r_diff_set_delta (d, delta); if (diffmode == 'j') { printf("{\"files\":[{\"filename\":\"%s\", \"size\":%d, \"sha256\":\"", file, sza); handle_sha256 (bufa, sza); printf("\"},\n{\"filename\":\"%s\", \"size\":%d, \"sha256\":\"", file2, szb); handle_sha256 (bufb, szb); printf("\"}],\n"); printf("\"changes\":["); } r_diff_set_callback (d, &cb, 0);//(void *)(size_t)diffmode); r_diff_buffers (d, bufa, sza, bufb, szb); if (diffmode == 'j') printf("]\n"); r_diff_free (d); break; case MODE_DIST: r_diff_buffers_distance (NULL, bufa, sza, bufb, szb, &count, &sim); printf ("similarity: %.2f\n", sim); printf ("distance: %d\n", count); break; } if (diffmode == 'j' && showcount) printf (",\"count\":%d}\n",count); else if (showcount && diffmode != 'j') printf ("%d\n", count); else if (!showcount && diffmode == 'j') printf ("}\n"); free (bufa); free (bufb); return 0; }
static int cmd_project(void *data, const char *input) { RCore *core = (RCore *)data; const char *file, *arg = input+1; const char *fileproject = r_config_get (core->config, "file.project"); char *str = strdup (fileproject); if (*arg==' ') arg++; file = input[1]?arg:str; switch (input[0]) { case 'c': if (!input[1]) { eprintf ("TODO: Show project saving script to console\n"); } else if (input[1]==' ') { r_core_project_cat (core, input+2); } else eprintf ("Usage: Pc [prjname]\n"); break; case 'o': // if (r_file_is_regular (file)) if (input[1]) { r_core_project_open (core, file); } else { if (file && *file) r_cons_printf ("%s\n", file); } break; case 'l': r_core_project_list (core, input[1]); break; case 'd': r_core_project_delete (core, file); break; case 's': if (r_core_project_save (core, file)) { r_config_set (core->config, "file.project", file); r_cons_printf ("%s\n", file); } break; case 'n': if (!fileproject || !*fileproject) { eprintf ("No project\n"); } else switch (input[1]) { case '-': /* remove lines containing specific words */ { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); FILE *fd = r_sandbox_fopen (str, "w"); if (!fd) { eprintf ("Cannot open %s\n", str); } else { int del = 0; if (data) { char *ptr, *nl; for (ptr = data; ptr; ptr = nl) { nl = strchr (ptr, '\n'); if (nl) { *nl++ = 0; if (strstr (ptr, input+2)) { del ++; } else { fprintf (fd, "%s\n", ptr); } } } free (data); } fclose (fd); free (str); if (del>0) { eprintf ("Deleted %d lines\n", del); } } } break; case ' ': if (input[2]=='-') { char *str = r_core_project_notes_file (core, fileproject); // edit with cfg.editor const char *editor = r_config_get (core->config, "cfg.editor"); if (str && *str && editor && *editor) r_sys_cmdf ("%s %s", editor, str); else eprintf ("No cfg.editor configured\n"); free (str); } else { //char *str = r_core_project_notes_file (core, fileproject); // append line to project notes char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); FILE *fd = r_sandbox_fopen (str, "a"); if (fd) { fprintf (fd, "%s\n", input+2); fclose (fd); } free (str); free (data); } break; case 'j': if (!input[2]) { int len = 0; /* get base64 string */ char *str = r_core_project_notes_file (core, fileproject); if (str) { char *data = r_file_slurp (str, &len); char *res = r_base64_encode_dyn (data, len); if (res) { r_cons_printf ("%s\n", res); free (res); } free (data); free (str); } } else if (input[2] == ' ') { /* set base64 string */ ut8 *data = r_base64_decode_dyn (input+3, 0); if (data) { char *str = r_core_project_notes_file (core, fileproject); if (str) { r_file_dump (str, data, strlen ((const char*)data)); free (str); } free (data); } } else { eprintf ("Usage: `Pnj` or `Pnj ...`\n"); } break; case 0: { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); if (data) { r_cons_printf ("%s\n", data); free (data); } free (str); } break; case '?': { const char* help_msg[] = { "Usage:", "Pn[j-?] [...]", "Project Notes", "Pn", "", "show project notes", "Pn", " -", "edit notes with cfg.editor", "Pn-", "", "delete notes", "Pn-", "str", "delete lines matching /str/ in notes", "Pnj", "", "show notes in base64", "Pnj", " [base64]", "set notes in base64", NULL}; r_core_cmd_help (core, help_msg); } break; } break; case 'i': // if (r_file_is_regular (file)) free (r_core_project_info (core, file)); break; default: { const char* help_msg[] = { "Usage:", "P[?osi] [file]", "Project management", "Pc", "", "show what will be saved in the project script", "Pc", " [file]", "show project script to console", "Pd", " [file]", "delete project", "Pi", " [file]", "show project information", "Pl", "", "list all projects", "Pn", "[j]", "show project notes (Pnj for json)", "Pn", " [base64]", "set notes text", "Pn", " -", "edit notes with cfg.editor", "Po", " [file]", "open project", "Ps", " [file]", "save project", "NOTE:", "", "See 'e file.project'", "NOTE:", "", "project files are stored in ~/.config/radare2/projects", NULL}; r_core_cmd_help (core, help_msg); } break; } free (str); return R_TRUE; }
- follow symlinks #endif R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { RSocketHTTPRequest *rs; int oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); while (!r_cons_singleton ()->breaked) { r_cons_break (http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (200); continue; } if (!rs->method || !rs->path) { r_socket_http_close (rs); continue; } if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = strdup ("<html><body>\n"); const char *file; RListIter *iter; // list files RList *files = r_sys_dir (uproot); eprintf ("Listing directory %s\n", uproot); r_list_foreach (files, iter, file) { if (file[0] == '.') continue; ptr = r_str_concatf (ptr, "<a href=\"/up/%s\">%s</a><br />\n", file, file); } r_list_free (files); ptr = r_str_concat (ptr, "<html><body>\n"); r_socket_http_response (rs, 200, ptr, 0, NULL); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) {
int main(int argc, char **argv) { const char *addr = NULL; RCore *c, *c2; RDiff *d; const char *arch = NULL; int bits = 0; char *file, *file2; ut8 *bufa, *bufb; int o, sza, szb, rad = 0, delta = 0; int mode = MODE_DIFF; int diffops = 0; int threshold = -1; double sim; while ((o = getopt (argc, argv, "a:b:Cnpg:Orhcdsvxt:")) != -1) { switch (o) { case 'a': arch = optarg; break; case 'b': bits = atoi (optarg); break; case 'p': useva = R_FALSE; break; case 'r': rad = 1; break; case 'g': mode = MODE_GRAPH; addr = optarg; break; case 'c': showcount = 1; break; case 'C': mode = MODE_CODE; break; case 'n': showbare = R_TRUE; break; case 'O': diffops = 1; break; case 't': threshold = atoi (optarg); break; case 'd': delta = 1; break; case 'h': return show_help (1); case 's': mode = MODE_DIST; break; case 'x': mode = MODE_COLS; break; case 'v': printf ("radiff2 v"R2_VERSION"\n"); return 0; default: return show_help (0); } } if (argc<3 || optind+2>argc) return show_help (0); file = argv[optind]; file2 = argv[optind+1]; switch (mode) { case MODE_GRAPH: case MODE_CODE: c = opencore (file); if (!c) eprintf ("Cannot open '%s'\n", file); c2 = opencore (file2); if (!c || !c2) { eprintf ("Cannot open '%s'\n", file2); return 1; } if (arch) { r_config_set (c->config, "asm.arch", arch); r_config_set (c2->config, "asm.arch", arch); } if (bits) { r_config_set_i (c->config, "asm.bits", bits); r_config_set_i (c2->config, "asm.bits", bits); } r_config_set_i (c->config, "diff.bare", showbare); r_config_set_i (c2->config, "diff.bare", showbare); r_anal_diff_setup_i (c->anal, diffops, threshold, threshold); r_anal_diff_setup_i (c2->anal, diffops, threshold, threshold); if (mode == MODE_GRAPH) { const char* second = strstr (addr, ","); if (!second) { r_core_gdiff (c, c2, R_TRUE); r_core_anal_graph (c, r_num_math (c->num, addr), R_CORE_ANAL_GRAPHBODY|R_CORE_ANAL_GRAPHDIFF); } else { const ut64 off = strtoull(addr, 0, 16); // define the same function at each offset r_core_anal_fcn (c, off, UT64_MAX, R_ANAL_REF_TYPE_NULL, 0); r_core_anal_fcn (c2, strtoull (second+1, 0, 16), UT64_MAX, R_ANAL_REF_TYPE_NULL, 0); r_core_gdiff (c, c2, R_FALSE); // compute the diff r_core_anal_graph (c, off, R_CORE_ANAL_GRAPHBODY|R_CORE_ANAL_GRAPHDIFF); } } else { r_core_gdiff (c, c2, R_TRUE); r_core_diff_show (c, c2); } return 0; } bufa = (ut8*)r_file_slurp (file, &sza); if (!bufa) { eprintf ("radiff2: Can not open %s\n", bufa); return 1; } bufb = (ut8*)r_file_slurp (file2, &szb); if (!bufb) { eprintf ("radiff2: Cannot open: %s\n", bufb); free (bufa); return 1; } switch (mode) { case MODE_COLS: { int cols = (r_cons_get_size (NULL)>112)?16:8; dump_cols (bufa, sza, bufb, szb, cols); } break; case MODE_DIFF: d = r_diff_new (0LL, 0LL); r_diff_set_delta (d, delta); r_diff_set_callback (d, &cb, (void *)(size_t)rad); r_diff_buffers (d, bufa, sza, bufb, szb); r_diff_free (d); break; case MODE_DIST: r_diff_buffers_distance (NULL, bufa, sza, bufb, szb, &count, &sim); printf ("similarity: %.2f\n", sim); printf ("distance: %d\n", count); break; } if (showcount) printf ("%d\n", count); free (bufa); free (bufb); return 0; }
static int asm_profile(RConfig *cfg, const char *profile) { // TODO: Do a cleanup on those configurations if (!strcmp (profile, "help") || *profile == '?') { r_cons_printf ("Available asm.profile:\n" " default, gas, smart, graph, debug, full, simple\n"); return R_FALSE; } else if (!strcmp (profile, "default")) { r_config_set (cfg, "asm.bytes", "true"); r_config_set (cfg, "asm.lines", "true"); r_config_set (cfg, "asm.linesout", "false"); r_config_set (cfg, "asm.lineswide", "false"); r_config_set (cfg, "asm.offset", "true"); r_config_set (cfg, "asm.comments", "true"); r_config_set (cfg, "asm.flagsline", "false"); r_config_set (cfg, "asm.section", "false"); r_config_set (cfg, "asm.trace", "false"); r_config_set (cfg, "anal.split", "true"); r_config_set (cfg, "asm.flags", "true"); r_config_set (cfg, "asm.size", "false"); r_config_set (cfg, "asm.xrefs", "true"); r_config_set (cfg, "asm.functions", "true"); r_config_set (cfg, "scr.color", "true"); } else if (!strcmp(profile, "compact")) { asm_profile (cfg, "simple"); r_config_set (cfg, "asm.lines", "true"); r_config_set (cfg, "asm.comments", "false"); r_config_set (cfg, "scr.color", "false"); } else if (!strcmp(profile, "gas")) { asm_profile (cfg, "default"); r_config_set (cfg, "asm.lines", "false"); r_config_set (cfg, "asm.comments", "false"); r_config_set (cfg, "asm.section", "false"); r_config_set (cfg, "asm.trace", "false"); r_config_set (cfg, "asm.bytes", "false"); r_config_set (cfg, "asm.stackptr", "false"); r_config_set (cfg, "asm.offset", "false"); r_config_set (cfg, "asm.flags", "true"); r_config_set (cfg, "asm.flagsline", "true"); r_config_set (cfg, "asm.jmpflags", "true"); r_config_set (cfg, "scr.color", "false"); } else if (!strcmp(profile, "smart")) { asm_profile (cfg, "default"); r_config_set (cfg, "asm.section", "false"); r_config_set (cfg, "asm.trace", "false"); r_config_set (cfg, "asm.bytes", "false"); r_config_set (cfg, "asm.stackptr", "false"); } else if (!strcmp (profile, "graph")) { asm_profile (cfg, "default"); r_config_set (cfg, "asm.section", "false"); r_config_set (cfg, "asm.bytes", "false"); r_config_set (cfg, "asm.trace", "false"); r_config_set (cfg, "scr.color", "false"); r_config_set (cfg, "asm.lines", "false"); r_config_set (cfg, "asm.stackptr", "false"); if (r_config_get (cfg, "graph.offset")) r_config_set (cfg, "asm.offset", "true"); else r_config_set (cfg, "asm.offset", "false"); } else if (!strcmp (profile, "debug")) { asm_profile (cfg, "default"); r_config_set (cfg, "asm.trace", "true"); } else if (!strcmp (profile, "full")) { asm_profile (cfg, "default"); r_config_set (cfg, "asm.bytes", "true"); r_config_set (cfg, "asm.lines", "true"); r_config_set (cfg, "asm.linesout", "true"); r_config_set (cfg, "asm.lineswide", "true"); r_config_set (cfg, "asm.section", "true"); r_config_set (cfg, "asm.size", "true"); } else if (!strcmp (profile, "simple")) { asm_profile (cfg, "default"); r_config_set (cfg, "asm.bytes", "false"); r_config_set (cfg, "asm.lines", "false"); r_config_set (cfg, "asm.comments", "true"); r_config_set (cfg, "anal.split", "false"); r_config_set (cfg, "asm.flags", "false"); r_config_set (cfg, "asm.flagsline", "true"); r_config_set (cfg, "asm.xrefs", "false"); r_config_set (cfg, "asm.stackptr", "false"); r_config_set (cfg, "asm.section", "false"); } return R_TRUE; }
static int cmd_project(void *data, const char *input) { RCore *core = (RCore *) data; const char *file, *arg = (input && *input)? input + 1: NULL; const char *fileproject = r_config_get (core->config, "prj.name"); char *str = NULL; if (!input) { return false; } str = strdup (fileproject); arg = strchr (input, ' '); if (arg) { arg++; } else { if (*input) { arg = input + 1; if (*arg == '&') { arg++; } } } file = arg; switch (input[0]) { case 'c': if (input[1] == ' ') { r_core_project_cat (core, input + 2); } else { eprintf ("Usage: Pc [prjname]\n"); } break; case 'o': // if (r_file_is_regular (file)) if (input[1] == '&') { r_core_project_open (core, file, true); } else if (input[1]) { r_core_project_open (core, file, false); } else { if (file && *file) { r_cons_println (file); } } break; case 'l': r_core_project_list (core, input[1]); break; case 'd': case '-': r_core_project_delete (core, file); break; case 's': if (!file || !file[0]) { /* if no argument specified use current project */ file = str; } if (r_core_project_save (core, file)) { r_config_set (core->config, "prj.name", file); r_cons_println (file); } break; case 'S': if (input[1] == ' ') { r_core_project_save_rdb (core, input + 2, R_CORE_PRJ_ALL); } else { eprintf ("Usage: PS [file]\n"); } break; case 'n': if (!fileproject || !*fileproject) { eprintf ("No project\n"); } else { switch (input[1]) { case '-': /* remove lines containing specific words */ { FILE *fd = r_sandbox_fopen (str, "w"); if (!fd) { eprintf ("Cannot open %s\n", str); } else { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); int del = 0; if (data) { char *ptr, *nl; for (ptr = data; ptr; ptr = nl) { nl = strchr (ptr, '\n'); if (nl) { *nl++ = 0; if (strstr (ptr, input + 2)) { del++; } else { fprintf (fd, "%s\n", ptr); } } } free (data); } if (del > 0) { eprintf ("Deleted %d lines\n", del); } free (str); fclose (fd); } } break; case ' ': if (input[2] == '-') { char *str = r_core_project_notes_file (core, fileproject); // edit with cfg.editor const char *editor = r_config_get (core->config, "cfg.editor"); if (str && *str && editor && *editor) { r_sys_cmdf ("%s %s", editor, str); } else { eprintf ("No cfg.editor configured\n"); } free (str); } else { //char *str = r_core_project_notes_file (core, fileproject); // append line to project notes char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); FILE *fd = r_sandbox_fopen (str, "a"); if (fd) { fprintf (fd, "%s\n", input + 2); fclose (fd); } free (str); free (data); } break; case 'j': if (!input[2]) { int len = 0; /* get base64 string */ char *str = r_core_project_notes_file (core, fileproject); if (str) { char *data = r_file_slurp (str, &len); char *res = r_base64_encode_dyn (data, len); if (res) { r_cons_println (res); free (res); } free (data); free (str); } } else if (input[2] == ' ') { /* set base64 string */ ut8 *data = r_base64_decode_dyn (input + 3, -1); if (data) { char *str = r_core_project_notes_file (core, fileproject); if (str) { r_file_dump (str, data, strlen ((const char *) data), 0); free (str); } free (data); } } else { eprintf ("Usage: `Pnj` or `Pnj ...`\n"); } break; case 'x': r_core_project_execute_cmds (core, fileproject); break; case 0: { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); if (data) { r_cons_println (data); free (data); } free (str); } break; case '?': { const char *help_msg[] = { "Usage:", "Pn[j-?] [...]", "Project Notes", "Pn", "", "show project notes", "Pn", " -", "edit notes with cfg.editor", "Pn-", "", "delete notes", "Pn-", "str", "delete lines matching /str/ in notes", "Pnx", "", "run project note commands", "Pnj", "", "show notes in base64", "Pnj", " [base64]", "set notes in base64", NULL }; r_core_cmd_help (core, help_msg); } break; } } break; case 'i': if (file && *file) { char *prjName = r_core_project_info (core, file); r_cons_println (prjName); free (prjName); } break; default: { const char *help_msg[] = { "Usage:", "P[?osi] [file]", "Project management", "Pc", " [file]", "show project script to console", "Pd", " [file]", "delete project", "Pi", " [file]", "show project information", "Pl", "", "list all projects", "Pn", "[j]", "show project notes (Pnj for json)", "Pn", " [base64]", "set notes text", "Pn", " -", "edit notes with cfg.editor", "Po", " [file]", "open project", "Ps", " [file]", "save project", "PS", " [file]", "save script file", "P-", " [file]", "delete project (alias for Pd)", "NOTE:", "", "See 'e??prj.'", "NOTE:", "", "project are stored in ~/.config/radare2/projects", NULL }; r_core_cmd_help (core, help_msg); } break; } free (str); return true; }
static int cb(RDiff *d, void *user, RDiffOp *op) { int i; //, diffmode = (int)(size_t)user; char s[256]; if (showcount) { count++; return 1; } switch (diffmode) { case 'U': // 'U' in theory never handled here case 'u': if (op->a_len > 0) { readstr (s, sizeof (s), op->a_buf, op->a_len); if (*s) { if (!quiet) printf (Color_RED); if (r_mem_is_printable ((const ut8*)s, R_MIN (strlen (s), 5))) { printf ("- %s\n", s); } else { printf ("-:"); int len = op->a_len; //R_MIN (op->a_len, strlen (op->a_buf)); for (i = 0; i < len; i++) { printf ("%02x", op->a_buf[i]); } printf (" \"%s\"\n", op->a_buf); } if (!quiet) printf (Color_RESET); } } if (op->b_len > 0) { readstr (s, sizeof (s), op->b_buf, op->b_len); if (*s) { if (!quiet) printf (Color_GREEN); if (r_mem_is_printable ((const ut8*)s, R_MIN (strlen (s), 5))) { printf ("+ %s\n", s); } else { printf ("+:"); for (i = 0; i < op->b_len; i++) { printf ("%02x", op->b_buf[i]); } printf (" \"%s\"\n", op->b_buf); } if (!quiet) printf (Color_RESET); } } break; case 'r': if (disasm) { eprintf ("r2cmds (-r) + disasm (-D) not yet implemented\n"); } if (op->a_len == op->b_len) { printf ("wx "); for (i = 0; i < op->b_len; i++) { printf ("%02x", op->b_buf[i]); } printf (" @ 0x%08"PFMT64x"\n", op->b_off); } else { if (op->a_len > 0) { printf ("r-%d @ 0x%08"PFMT64x"\n", op->a_len, op->a_off + delta); } if (op->b_len > 0) { printf ("r+%d @ 0x%08"PFMT64x"\n", op->b_len, op->b_off + delta); printf ("wx "); for (i = 0; i < op->b_len; i++) { printf ("%02x", op->b_buf[i]); } printf (" @ 0x%08"PFMT64x"\n", op->b_off+delta); } delta += (op->b_off - op->a_off); } return 1; case 'j': if (disasm) { eprintf ("JSON (-j) + disasm (-D) not yet implemented\n"); } if (json_started) { printf (",\n"); } json_started = 1; printf ("{\"offset\":%"PFMT64d",", op->a_off); printf("\"from\":\""); for (i = 0; i < op->a_len; i++) { printf ("%02x", op->a_buf[i]); } printf ("\", \"to\":\""); for (i = 0; i < op->b_len; i++) { printf ("%02x", op->b_buf[i]); } printf ("\"}"); //,\n"); return 1; case 0: default: if (disasm) { printf ("--- 0x%08"PFMT64x"\n", op->a_off); if (!core) { core = opencore (file); if (arch) { r_config_set (core->config, "asm.arch", arch); } if (bits) { r_config_set_i (core->config, "asm.bits", bits); } } if (core) { RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->a_buf, op->a_len); printf ("%s\n", ac->buf_asm); //r_asm_code_free (ac); } } else { printf ("0x%08"PFMT64x" ", op->a_off); for (i = 0; i < op->a_len; i++) { printf ("%02x", op->a_buf[i]); } } if (disasm) { printf ("+++ 0x%08"PFMT64x"\n", op->b_off); if (!core) { core = opencore (NULL); } if (core) { RAsmCode *ac = r_asm_mdisassemble (core->assembler, op->b_buf, op->b_len); printf ("%s\n", ac->buf_asm); //r_asm_code_free (ac); } } else { printf (" => "); for (i = 0; i < op->b_len; i++) { printf ("%02x", op->b_buf[i]); } printf (" 0x%08"PFMT64x"\n", op->b_off); } return 1; } 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; }