static int bin_main(RCore *r, int mode, int va) { RBinAddr *binmain = r_bin_get_sym (r->bin, R_BIN_SYM_MAIN); ut64 addr; if (!binmain) return false; addr = va ? r_bin_a2b (r->bin, binmain->vaddr) : binmain->paddr; if (IS_MODE_SET (mode)) { r_flag_space_set (r->flags, "symbols"); r_flag_set (r->flags, "main", addr, r->blocksize, 0); } else if (IS_MODE_SIMPLE (mode)) { r_cons_printf ("%"PFMT64d, addr); } else if (IS_MODE_RAD (mode)) { r_cons_printf ("fs symbols\n"); r_cons_printf ("f main @ 0x%08"PFMT64x"\n", addr); } else if (IS_MODE_JSON (mode)) { r_cons_printf ("{\"vaddr\":%" PFMT64d ",\"paddr\":%" PFMT64d "}", addr, binmain->paddr); } else { r_cons_printf ("[Main]\n"); r_cons_printf ("vaddr=0x%08"PFMT64x" paddr=0x%08"PFMT64x"\n", addr, binmain->paddr); } return true; }
static int bin_entry(RCore *r, int mode, ut64 laddr, int va) { char str[R_FLAG_NAME_SIZE]; RList *entries = r_bin_get_entries (r->bin); RListIter *iter; RBinAddr *entry = NULL; int i = 0; ut64 baddr = r_bin_get_baddr (r->bin); if (IS_MODE_RAD (mode)) r_cons_printf ("fs symbols\n"); else if (IS_MODE_JSON (mode)) r_cons_printf ("["); else if (IS_MODE_NORMAL (mode)) r_cons_printf ("[Entrypoints]\n"); r_list_foreach (entries, iter, entry) { ut64 paddr = entry->paddr; ut64 at = rva (r->bin, paddr, entry->vaddr, va); if (IS_MODE_SET (mode)) { r_flag_space_set (r->flags, "symbols"); snprintf (str, R_FLAG_NAME_SIZE, "entry%i", i); r_flag_set (r->flags, str, at, 1, 0); } else if (IS_MODE_SIMPLE (mode)) { r_cons_printf ("0x%08"PFMT64x"\n", at); } else if (IS_MODE_JSON (mode)) { r_cons_printf ("%s{\"vaddr\":%" PFMT64d "," "\"paddr\":%" PFMT64d "," "\"baddr\":%" PFMT64d "," "\"laddr\":%" PFMT64d "}", iter->p ? "," : "", at, paddr, baddr, laddr); } else if (IS_MODE_RAD (mode)) { r_cons_printf ("f entry%i 1 @ 0x%08"PFMT64x"\n", i, at); r_cons_printf ("s entry%i\n", i); } else { r_cons_printf ( "vaddr=0x%08"PFMT64x " paddr=0x%08"PFMT64x " baddr=0x%08"PFMT64x " laddr=0x%08"PFMT64x"\n", at, paddr, baddr, laddr); } i++; }
R_API int r_core_visual_cmd(RCore *core, int ch) { RAsmOp op; ut64 offset = core->offset; char buf[4096]; int i, ret, offscreen, cols = core->print->cols, delta = 0; ch = r_cons_arrow_to_hjkl (ch); ch = visual_nkey (core, ch); if (ch<2) return 1; // do we need hotkeys for data references? not only calls? if (ch>='0'&& ch<='9') { ut64 off = core->asmqjmps[ch-'0']; if (off != UT64_MAX) { int delta = R_ABS ((st64)off-(st64)offset); r_io_sundo_push (core->io, offset); if (curset && delta<100) { cursor = delta; } else { r_core_visual_seek_animation (core, off); //r_core_seek (core, off, 1); } r_core_block_read (core, 1); } } else switch (ch) { case 0x0d: { r_cons_enable_mouse (R_TRUE); RAnalOp *op = r_core_anal_op (core, core->offset+cursor); if (op) { if (op->type == R_ANAL_OP_TYPE_JMP || op->type == R_ANAL_OP_TYPE_CJMP || op->type == R_ANAL_OP_TYPE_CALL) { r_io_sundo_push (core->io, offset); r_core_visual_seek_animation(core, op->jump); } } r_anal_op_free (op); } break; case 90: // shift+tab if (!strcmp (printfmt[0], "x")) printfmt[0] = "pxa"; else printfmt[0] = "x"; break; case 9: // tab { // XXX: unify diff mode detection ut64 f = r_config_get_i (core->config, "diff.from"); ut64 t = r_config_get_i (core->config, "diff.to"); if (f == t && f == 0) { core->print->col = core->print->col==1? 2: 1; } else { ut64 delta = offset - f; r_core_seek (core, t+delta, 1); r_config_set_i (core->config, "diff.from", t); r_config_set_i (core->config, "diff.to", f); } } break; case 'a': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_printf ("Enter assembler opcodes separated with ';':\n"); showcursor (core, R_TRUE); r_cons_flush (); r_cons_set_raw (R_FALSE); strcpy (buf, "wa "); r_line_set_prompt (":> "); if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0'; if (*buf) { if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, R_TRUE); if (curset) r_core_seek (core, core->offset - cursor, 1); } showcursor (core, R_FALSE); r_cons_set_raw (R_TRUE); break; case '!': r_cons_2048(); break; case 'o': visual_offset (core); break; case 'A': { int oc = curset; ut64 off = curset? core->offset+cursor : core->offset; curset = 0; r_core_visual_asm (core, off); curset = oc; } break; case 'c': setcursor (core, curset?0:1); break; case 'C': color = color? 0: 1; r_config_set_i (core->config, "scr.color", color); break; case 'd': r_core_visual_define (core); break; case 'D': setdiff (core); break; case 'f': { int range, min, max; char name[256], *n; r_line_set_prompt ("flag name: "); showcursor (core, R_TRUE); if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) { n = r_str_chop (name); if (*name=='-') { if (*n) r_flag_unset (core->flags, n+1, NULL); } else { if (ocursor != -1) { min = R_MIN (cursor, ocursor); max = R_MAX (cursor, ocursor); } else { min = max = cursor; } range = max-min+1; if (range<1) range = 1; if (*n) r_flag_set (core->flags, n, core->offset + min, range, 1); } } } showcursor (core, R_FALSE); break; case 'F': r_flag_unset_i (core->flags, core->offset + cursor, NULL); break; case 'n': r_core_seek_next (core, r_config_get (core->config, "scr.nkey")); break; case 'N': r_core_seek_previous (core, r_config_get (core->config, "scr.nkey")); break; case 'i': case 'I': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } showcursor (core, R_TRUE); r_cons_flush (); r_cons_set_raw (0); if (ch=='I') { strcpy (buf, "wow "); r_line_set_prompt ("insert hexpair block: "); if (r_cons_fgets (buf+4, sizeof (buf)-5, 0, NULL) <0) buf[0]='\0'; char *p = strdup (buf); int cur = core->print->cur; if (cur>=core->blocksize) cur = core->print->cur-1; snprintf (buf, sizeof (buf), "%s @ $$0!%i", p, core->blocksize-cursor); r_core_cmd (core, buf, 0); free (p); break; } delta = (ocursor!=-1)? R_MIN (cursor, ocursor): cursor; if (core->print->col==2) { strcpy (buf, "\"w "); r_line_set_prompt ("insert string: "); if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0) buf[0]='\0'; strcat (buf, "\""); } else { r_line_set_prompt ("insert hex: "); if (ocursor != -1) { int bs = R_ABS (cursor-ocursor)+1; core->blocksize = bs; strcpy (buf, "wow "); } else { strcpy (buf, "wx "); } if (r_cons_fgets (buf+strlen (buf), sizeof (buf)-strlen (buf), 0, NULL) <0) buf[0]='\0'; } if (curset) r_core_seek (core, core->offset + delta, 0); r_core_cmd (core, buf, 1); if (curset) r_core_seek (core, offset, 1); r_cons_set_raw (1); showcursor (core, R_FALSE); break; case 'R': r_core_cmd0 (core, "ecr"); break; case 'e': r_core_visual_config (core); break; case 'E': r_core_visual_colors (core); break; case 'M': r_core_visual_mounts (core); break; case 't': r_core_visual_trackflags (core); break; case 'x': { int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_gotoxy (1, 1); r_cons_printf ("[GOTO XREF]> \n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s) \n", count, refi->at, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } } } else xrefs = NULL;
static int bin_strings(RCore *r, int mode, int va) { char *q, str[R_FLAG_NAME_SIZE]; RBinSection *section; int hasstr, minstr, maxstr, rawstr; RBinString *string; RListIter *iter; RList *list; RBin *bin = r->bin; RBinFile * binfile = r_core_bin_cur (r); RBinPlugin *plugin = r_bin_file_cur_plugin (binfile); if (!binfile) return false; minstr = r_config_get_i (r->config, "bin.minstr"); maxstr = r_config_get_i (r->config, "bin.maxstr"); rawstr = r_config_get_i (r->config, "bin.rawstr"); binfile->rawstr = rawstr; if (!(hasstr = r_config_get_i (r->config, "bin.strings"))) { return 0; } if (!plugin) return 0; if (plugin->info && plugin->name) { if (strcmp (plugin->name, "any") == 0 && !rawstr) { return false; } } bin->minstrlen = minstr; minstr = bin->minstrlen; if ((list = r_bin_get_strings (bin)) == NULL) return false; if (IS_MODE_JSON (mode)) r_cons_printf ("["); if (IS_MODE_RAD (mode)) r_cons_printf ("fs strings"); if (IS_MODE_SET (mode) && r_config_get_i (r->config, "bin.strings")) { r_flag_space_set (r->flags, "strings"); r_cons_break (NULL, NULL); } r_list_foreach (list, iter, string) { const char *section_name, *type_string; ut64 paddr = string->paddr; ut64 vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr); ut64 addr = va ? vaddr : paddr; if (string->length < minstr) continue; if (maxstr && string->length > maxstr) continue; section = r_bin_get_section_at (r_bin_cur_object (bin), paddr, 0); section_name = section ? section->name : "unknown"; type_string = string->type == 'w' ? "wide" : "ascii"; if (IS_MODE_SET (mode)) { char *f_name; if (r_cons_singleton()->breaked) break; r_meta_add (r->anal, R_META_TYPE_STRING, addr, addr + string->size, string->string); f_name = strdup (string->string); r_name_filter (f_name, R_FLAG_NAME_SIZE); snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name); r_flag_set (r->flags, str, addr, string->size, 0); free (f_name); } else if (IS_MODE_SIMPLE (mode)) { r_cons_printf ("0x%"PFMT64x" %d %d %s\n", addr, string->size, string->length, string->string); } else if (IS_MODE_JSON (mode)) { q = r_base64_encode_dyn (string->string, -1); r_cons_printf ("%s{\"vaddr\":%"PFMT64d ",\"paddr\":%"PFMT64d",\"ordinal\":%d" ",\"size\":%d,\"length\":%d,\"section\":\"%s\"," "\"type\":\"%s\",\"string\":\"%s\"}", iter->p ? ",": "", vaddr, paddr, string->ordinal, string->size, string->length, section_name, type_string, q); free (q); } else if (IS_MODE_RAD (mode)) { char *f_name; f_name = strdup (string->string); r_name_filter (f_name, R_FLAG_NAME_SIZE); snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name); r_cons_printf ("f str.%s %"PFMT64d" @ 0x%08"PFMT64x"\n" "Cs %"PFMT64d" @ 0x%08"PFMT64x"\n", f_name, string->size, addr, string->size, addr); free (f_name); } else { r_cons_printf ("vaddr=0x%08"PFMT64x" paddr=0x%08" PFMT64x" ordinal=%03u sz=%u len=%u " "section=%s type=%s string=%s\n", vaddr, paddr, string->ordinal, string->size, string->length, section_name, type_string, string->string); } } if (IS_MODE_JSON (mode)) r_cons_printf ("]"); if (IS_MODE_SET (mode)) r_cons_break_end (); return true; }
R_API int r_core_visual_cmd(RCore *core, int ch) { RAsmOp op; char buf[4096]; int i, ret, offscreen, cols = core->print->cols; ch = r_cons_arrow_to_hjkl (ch); ch = visual_nkey (core, ch); if (ch<2) return 1; // do we need hotkeys for data references? not only calls? if (ch>='0'&& ch<='9') { r_io_sundo_push (core->io, core->offset); r_core_seek (core, core->asmqjmps[ch-'0'], 1); r_core_block_read (core, 1); } else switch (ch) { case 9: // tab { // XXX: unify diff mode detection ut64 f = r_config_get_i (core->config, "diff.from"); ut64 t = r_config_get_i (core->config, "diff.to"); if (f == t && f == 0) { core->print->col = core->print->col==1? 2: 1; } else { ut64 delta = core->offset - f; r_core_seek (core, t+delta, 1); r_config_set_i (core->config, "diff.from", t); r_config_set_i (core->config, "diff.to", f); } } break; case 'c': // XXX dupped flag imho setcursor (core, curset ^ 1); break; case 'd': r_core_visual_define (core); break; case 'D': setdiff (core); break; case 'C': color ^= 1; if (color) flags |= R_PRINT_FLAGS_COLOR; else flags &= ~(flags&R_PRINT_FLAGS_COLOR); r_config_set_i (core->config, "scr.color", color); r_print_set_flags (core->print, flags); break; case 'f': { int range; char name[256], *n; r_line_set_prompt ("flag name: "); if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) { n = r_str_chop (name); if (*name=='-') { if (*n) r_flag_unset (core->flags, n+1, NULL); } else { range = curset? (R_ABS (cursor-ocursor)+1): 1; if (range<1) range = 1; if (*n) r_flag_set (core->flags, n, core->offset + cursor, range, 1); } } } break; case 'F': r_flag_unset_i (core->flags, core->offset + cursor, NULL); break; case 'n': r_core_seek_next (core, r_config_get (core->config, "scr.nkey")); break; case 'N': r_core_seek_previous (core, r_config_get (core->config, "scr.nkey")); break; case 'A': { int oc = curset; ut64 off = curset? core->offset+cursor : core->offset; curset = 0; r_core_visual_asm (core, off); curset = oc; } break; case 'a': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_printf ("Enter assembler opcodes separated with ';':\n"); r_cons_show_cursor (R_TRUE); r_cons_flush (); r_cons_set_raw (R_FALSE); strcpy (buf, "wa "); r_line_set_prompt (":> "); if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0'; if (*buf) { if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, R_TRUE); if (curset) r_core_seek (core, core->offset - cursor, 1); } r_cons_show_cursor (R_FALSE); r_cons_set_raw (R_TRUE); break; case 'i': case 'I': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_show_cursor (R_TRUE); r_cons_flush (); r_cons_set_raw (0); if (ch=='I') { strcpy (buf, "wow "); r_line_set_prompt ("insert hexpair block: "); if (r_cons_fgets (buf+4, sizeof (buf)-3, 0, NULL) <0) buf[0]='\0'; char *p = strdup (buf); int cur = core->print->cur; if (cur>=core->blocksize) cur = core->print->cur-1; snprintf (buf, sizeof (buf), "%s @ $$0!%i", p, core->blocksize-cursor); r_core_cmd (core, buf, 0); free (p); break; } if (core->print->col==2) { strcpy (buf, "w "); r_line_set_prompt ("insert string: "); if (r_cons_fgets (buf+2, sizeof (buf)-3, 0, NULL) <0) buf[0]='\0'; } else { strcpy (buf, "wx "); r_line_set_prompt ("insert hex: "); if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0) buf[0]='\0'; } if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, 1); if (curset) r_core_seek (core, core->offset - cursor, 1); r_cons_set_raw (1); r_cons_show_cursor (R_FALSE); break; case 'e': r_core_visual_config (core); break; case 'M': r_core_visual_mounts (core); break; case 't': r_core_visual_trackflags (core); break; case 'x': { int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_printf ("XREFS:\n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf ("\t[%i] %s XREF 0x%08"PFMT64x" (%s)\n", count, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } } } else xrefs = NULL;