int gb_set_reg_profile(emu *e) { int ret = r_anal_set_reg_profile (e->anal); e->reg = e->anal->reg; r_reg_set_value (e->reg, r_reg_get (e->reg,"mpc",-1), ((RBinAddr *) r_list_get_n (r_bin_get_entries (e->bin), 0))->offset); r_reg_set_value (e->reg, r_reg_get (e->reg,"sp",-1), 0xfffe); r_reg_set_value (e->reg, r_reg_get (e->reg,"af",-1), 0x01b0); r_reg_set_value (e->reg, r_reg_get (e->reg,"bc",-1), 0x0013); r_reg_set_value (e->reg, r_reg_get (e->reg,"de",-1), 0x00d8); r_reg_set_value (e->reg, r_reg_get (e->reg,"hl",-1), 0x014d); r_reg_set_value (e->reg, r_reg_get (e->reg,"ime",-1), R_TRUE); return ret; }
static int disassemble (RAsm *a, RAsmOp *opstruct, const ut8 *buf, int len) { RList *interned_table = NULL; RList *shared = NULL; RList *cobjs = NULL; RBin *bin = a->binb.bin; ut64 pc = a->pc; RBinPlugin *plugin = bin && bin->cur && bin->cur->o ? bin->cur->o->plugin : NULL; if (plugin) { if (!strcmp (plugin->name, "pyc")) { shared = bin->cur->o->bin_obj; } } cobjs = r_list_get_n (shared, 0); interned_table = r_list_get_n (shared, 1); int r = r_pyc_disasm (opstruct, buf, cobjs, interned_table, pc); opstruct->size = r; return r; }
static pyc_object *get_ref_object(RBuffer *buffer) { pyc_object *ret; pyc_object *obj; bool error = false; ut32 index = get_ut32 (buffer, &error); if (error || index >= r_list_length (refs)) return NULL; obj = r_list_get_n (refs, index); if (!obj) return NULL; ret = copy_object (obj); if (!ret) free (obj); return ret; }
int omap_remap(void *stream, int address) { SOmapStream *omap_stream = (SOmapStream *) stream; SOmapEntry *omap_entry = 0; RListIter *it = 0; int i = 0; int pos = 0; int len = 0; if (!omap_stream) { return address; } len = r_list_length(omap_stream->omap_entries); if (omap_stream->froms == 0) { omap_stream->froms = (unsigned int *) malloc(4 * len); it = r_list_iterator(omap_stream->omap_entries); while (r_list_iter_next(it)) { omap_entry = (SOmapEntry *) r_list_iter_get(it); omap_stream->froms[i] = omap_entry->from; i++; } } // mb (len -1) ??? pos = binary_search(omap_stream->froms, address, 0, (len)); if (omap_stream->froms[pos] != address) { pos -= 1; } omap_entry = (SOmapEntry *) r_list_get_n(omap_stream->omap_entries, pos); if (!omap_entry) { return -1; } if (omap_entry->to == 0) { return omap_entry->to; } else { return omap_entry->to + (address - omap_entry->from); } }
static int gdbr_parse_target_xml(libgdbr_t *g, char *xml_data, ut64 len) { char *regstr, *flagstr, *tmp, *profile = NULL, pc_alias[64], flag_bits[65]; RList *flags, *regs; RListIter *iter; gdbr_xml_flags_t *tmpflag; gdbr_xml_reg_t *tmpreg; ut64 profile_len = 0, profile_max_len, regnum = 0, regoff = 0; pc_alias[0] = '\0'; gdb_reg_t *arch_regs = NULL; if (_resolve_arch (g, xml_data) < 0) { return -1; } if (!(flagstr = strstr (xml_data, "<feature"))) { return -1; } regstr = flagstr; if (!(flags = _extract_flags (flagstr))) { return -1; } if (!(regs = _extract_regs (regstr, flags, pc_alias))) { r_list_free (flags); return -1; } if (!(arch_regs = malloc (sizeof (gdb_reg_t) * (r_list_length (regs) + 1)))) { goto exit_err; } // approximate per-reg size estimates profile_max_len = r_list_length (regs) * 128 + r_list_length (flags) * 128; if (!(profile = malloc (profile_max_len))) { goto exit_err; } r_list_foreach (regs, iter, tmpreg) { if (!tmpreg) { continue; } // regsize > 64 not supported by r2 currently if (tmpreg->size > 8) { regoff += tmpreg->size; continue; } memcpy (arch_regs[regnum].name, tmpreg->name, sizeof (tmpreg->name)); arch_regs[regnum].size = tmpreg->size; arch_regs[regnum].offset = regoff; if (profile_len + 128 >= profile_max_len) { if (!(tmp = realloc (profile, profile_max_len + 512))) { goto exit_err; } profile = tmp; profile_max_len += 512; } flag_bits[0] = '\0'; tmpflag = NULL; if (tmpreg->flagnum < r_list_length (flags)) { tmpflag = r_list_get_n (flags, tmpreg->flagnum); _write_flag_bits (flag_bits, tmpflag); } profile_len += snprintf (profile + profile_len, 128, "%s\t%s\t" ".%u\t%"PFMT64d"\t0\t%s\n", tmpreg->type, tmpreg->name, tmpreg->size * 8, regoff, flag_bits); // TODO write flag subregisters if (tmpflag) { int i; for (i = 0; i < tmpflag->num_fields; i++) { if (profile_len + 128 >= profile_max_len) { if (!(tmp = realloc (profile, profile_max_len + 512))) { goto exit_err; } profile = tmp; profile_max_len += 512; } profile_len += snprintf (profile + profile_len, 128, "gpr\t%s\t" ".%u\t.%"PFMT64d"\t0\n", tmpflag->fields[i].name, tmpflag->fields[i].sz, tmpflag->fields[i].bit_num + (regoff * 8)); } } regnum++; regoff += tmpreg->size; } // Difficult to parse these out from xml. So manually added from gdb's xml files switch (g->target.arch) { case R_SYS_ARCH_ARM: switch (g->target.bits) { case 32: if (!(profile = r_str_prefix (profile, "=PC r15\n" "=SP r14\n" // XXX "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" ))) { goto exit_err; } break; case 64: if (!(profile = r_str_prefix (profile, "=PC pc\n" "=SP sp\n" "=BP x29\n" "=A0 x0\n" "=A1 x1\n" "=A2 x2\n" "=A3 x3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN x8\n" ))) { goto exit_err; } } break; break; case R_SYS_ARCH_X86: switch (g->target.bits) { case 32: if (!(profile = r_str_prefix (profile, "=PC eip\n" "=SP esp\n" "=BP ebp\n"))) { goto exit_err; } break; case 64: if (!(profile = r_str_prefix (profile, "=PC rip\n" "=SP rsp\n" "=BP rbp\n"))) { goto exit_err; } } break; case R_SYS_ARCH_MIPS: if (!(profile = r_str_prefix (profile, "=PC pc\n" "=SP r29\n"))) { goto exit_err; } break; default: // TODO others if (*pc_alias) { if (!(profile = r_str_prefix (profile, pc_alias))) { goto exit_err; } } } // Special case for MIPS, since profile doesn't separate 32/64 bit MIPS if (g->target.arch == R_SYS_ARCH_MIPS) { if (arch_regs && arch_regs[0].size == 8) { g->target.bits = 64; } } r_list_free (flags); r_list_free (regs); free (g->target.regprofile); if (profile) { g->target.regprofile = strdup (profile); free (profile); } g->target.valid = true; g->registers = arch_regs; return 0; exit_err: r_list_free (flags); r_list_free (regs); free (profile); free (arch_regs); return -1; }
static int cmd_seek(void *data, const char *input) { RCore *core = (RCore *) data; char *cmd, *p; ut64 off; if (!*input) { r_cons_printf ("0x%"PFMT64x "\n", core->offset); return 0; } char *ptr; if ((ptr = strstr (input, "+.")) != NULL) { char *dup = strdup (input); dup[ptr - input] = '\x00'; off = r_num_math (core->num, dup + 1); core->offset = off; free (dup); } const char *inputnum = strchr (input, ' '); { const char *u_num = inputnum? inputnum + 1: input + 1; off = r_num_math (core->num, u_num); if (*u_num == '-') { off = -off; } } int sign = 1; if (input[0] == ' ') { switch (input[1]) { case '-': sign = -1; /* pass thru */ case '+': input++; break; } } bool silent = false; if (*input == 's') { silent = true; input++; if (*input == '?') { const char *help_message[] = { "Usage: ss", "", " # Seek silently (not recorded in the seek history)", "s?", "", "Works with all s subcommands", NULL }; r_core_cmd_help (core, help_message); return 0; } } switch (*input) { case 'r': if (input[1] && input[2]) { seek_to_register (core, input + 2, silent); } else { eprintf ("|Usage| 'sr PC' seek to program counter register\n"); } break; case 'C': if (input[1] == '*') { r_core_cmd0 (core, "C*~^\"CC"); } else if (input[1] == ' ') { typedef struct { ut64 addr; char *str; } MetaCallback; int count = 0; MetaCallback cb = { 0, NULL }; ut64 addr; char key[128]; const char *val, *comma; char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0); char *str, *next, *cur = list; if (list) { for (;;) { cur = sdb_anext (cur, &next); addr = sdb_atoi (cur); snprintf (key, sizeof (key) - 1, "meta.C.0x%"PFMT64x, addr); val = sdb_const_get (core->anal->sdb_meta, key, 0); if (val) { comma = strchr (val, ','); if (comma) { str = (char *) sdb_decode (comma + 1, 0); if (strstr (str, input + 2)) { r_cons_printf ("0x%08"PFMT64x " %s\n", addr, str); count++; cb.addr = addr; free (cb.str); cb.str = str; } else { free (str); } } } else { eprintf ("sdb_const_get key not found '%s'\n", key); } if (!next) { break; } cur = next; } } switch (count) { case 0: eprintf ("No matching comments\n"); break; case 1: off = cb.addr; if (!silent) { r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print)); } r_core_seek (core, off, 1); r_core_block_read (core); break; default: eprintf ("Too many results\n"); break; } free (cb.str); } else { const char *help_msg[] = { "Usage:", "sC", "Comment grep", "sC", "*", "List all comments", "sC", " str", "Seek to the first comment matching 'str'", NULL }; r_core_cmd_help (core, help_msg); } break; case ' ': if (!silent) { r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print)); } r_core_seek (core, off * sign, 1); r_core_block_read (core); break; case '/': { const char *pfx = r_config_get (core->config, "search.prefix"); ut64 from = r_config_get_i (core->config, "search.from"); // kwidx cfg var is ignored int kwidx = core->search->n_kws; // (int)r_config_get_i (core->config, "search.kwidx")-1; if (kwidx < 0) { kwidx = 0; } switch (input[1]) { case ' ': case 'v': case 'V': case 'w': case 'W': case 'z': case 'm': case 'c': case 'A': case 'e': case 'E': case 'i': case 'R': case 'r': case '/': case 'x': r_config_set_i (core->config, "search.from", core->offset + 1); r_config_set_i (core->config, "search.count", 1); r_core_cmdf (core, "s+1; %s; s-1; s %s%d_0; f-%s%d_0", input, pfx, kwidx, pfx, kwidx, pfx, kwidx); r_config_set_i (core->config, "search.from", from); r_config_set_i (core->config, "search.count", 0); break; case '?': eprintf ("Usage: s/.. arg.\n"); r_cons_printf ("/?\n"); break; default: eprintf ("unknown search method\n"); break; } } break; case '.': for (input++; *input == '.'; input++) { ; } r_core_seek_base (core, input); break; case 'j': // sj { RList /*<ut64 *>*/ *addrs = r_list_newf (free); RList /*<char *>*/ *names = r_list_newf (free); RList *list = r_io_sundo_list (core->io, '!'); ut64 lsz = 0; ut64 i; RListIter *iter; RIOUndos *undo; if (list) { r_list_foreach (list, iter, undo) { char *name = NULL; core->flags->space_strict = true; RFlagItem *f = r_flag_get_at (core->flags, undo->off, true); core->flags->space_strict = false; if (f) { if (f->offset != undo->off) { name = r_str_newf ("%s + %d\n", f->name, (int)(undo->off- f->offset)); } else { name = strdup (f->name); } } if (!name) { name = strdup (""); } ut64 *val = malloc (sizeof (ut64)); if (!val) { free (name); break; } *val = undo->off; r_list_append (addrs, val); r_list_append (names, strdup (name)); lsz++; free (name); } r_list_free (list); } r_cons_printf ("["); for (i = 0; i < lsz; ++i) { ut64 *addr = r_list_get_n (addrs, i); const char *name = r_list_get_n (names, i); // XXX(should the "name" field be optional? That might make // a bit more sense. r_cons_printf ("{\"offset\":%"PFMT64d",\"symbol\":\"%s\"}", *addr, name); if (i != lsz - 1) { r_cons_printf (","); } } r_cons_printf ("]\n"); r_list_free (addrs); r_list_free (names); } break; case '*': case '=': case '!': { RList *list = r_io_sundo_list (core->io, input[0]); RListIter *iter; RIOUndos *undo; if (list) { r_list_foreach (list, iter, undo) { char *name = NULL; core->flags->space_strict = true; RFlagItem *f = r_flag_get_at (core->flags, undo->off, true); core->flags->space_strict = false; if (f) { if (f->offset != undo->off) { name = r_str_newf ("%s + %d\n", f->name, (int)(undo->off- f->offset)); } else { name = strdup (f->name); } } if (!name) { name = strdup (""); } r_cons_printf ("0x%"PFMT64x" %s\n", undo->off, name); free (name); } r_list_free (list); } }
/////////////////////////////////////////////////////////////////////////////// // TODO: need refactor static void print_types(R_PDB *pdb, int mode) { ELeafType lt = eLF_MAX; char *command_field = 0; char *name_field = 0; char *flags_format_field = 0; // format for struct char **members_name_field = 0; char *type = 0; int members_amount = 0; int i = 0; int pos = 0; char sym = ' '; int is_first = 1; char *name = NULL; int val = 0; int offset = 0; SType *t = 0; STypeInfo *tf = 0; RListIter *it = 0, *it2 = 0; RList *plist = pdb->pdb_streams, *ptmp = NULL; STpiStream *tpi_stream = r_list_get_n (plist, ePDB_STREAM_TPI); if (!tpi_stream) { eprintf ("there is no tpi stream in current pdb\n"); return; } if (mode == 'j') { pdb->cb_printf ("{\"%s\":[","types"); } it = r_list_iterator(tpi_stream->types); while (r_list_iter_next(it)) { pos = 0; i = 0; members_amount = 0; val = 0; t = (SType *) r_list_iter_get(it); tf = &t->type_data; lt = tf->leaf_type; if ((tf->leaf_type == eLF_STRUCTURE) || (tf->leaf_type == eLF_UNION) || (tf->leaf_type == eLF_ENUM)) { if (tf->is_fwdref) { tf->is_fwdref (tf, &val); if (val == 1) { continue; } } if ((mode == 'j') && (is_first == 0)) { pdb->cb_printf (","); } is_first = 0; if (tf->get_name) { tf->get_name (tf, &name); } // val for STRUCT or UNION mean size if (tf->get_val) { tf->get_val (tf, &val); } if (tf->get_members) { tf->get_members (tf, &ptmp); } //pdb->cb_printf ("%s: size 0x%x\n", name, val); switch (mode) { case 'd': pdb->cb_printf ("%s: size 0x%x\n", name, val); break; case 'r': build_command_field (lt, &command_field); build_name_field (name, &name_field); if (!alloc_format_flag_and_member_fields (ptmp, &flags_format_field, &members_amount, &members_name_field)) { goto err; } break; case 'j': switch (lt) { case eLF_ENUM: pdb->cb_printf ("{\"type\":\"%s\", \"name\":\"%s\",\"%s\":[", "enum", name , "enums"); break; case eLF_STRUCTURE: case eLF_UNION: pdb->cb_printf("{\"type\":\"%s\",\"name\":\"%s\",\"%s\":[", "structure", name, "members"); break; default: continue; } break; } it2 = r_list_iterator (ptmp); while (r_list_iter_next (it2)) { if ((mode == 'j') && (i)) { pdb->cb_printf (","); } tf = (STypeInfo *) r_list_iter_get(it2); if (tf->get_name) { tf->get_name (tf, &name); } if (tf->get_val) { tf->get_val (tf, &offset); } else { offset = 0; } if (tf->get_print_type) { tf->get_print_type (tf, &type); } switch (mode) { case 'd': pdb->cb_printf (" 0x%x: %s type:", offset, name); pdb->cb_printf ("%s\n", type); break; case 'r': if (!build_flags_format_and_members_field(pdb, lt, name, type, i, &pos, offset, flags_format_field, members_name_field)) { R_FREE (type); goto err; } break; case 'j': // JSON switch (lt) { case eLF_ENUM: pdb->cb_printf ("{\"%s\":\"%s\",\"%s\":%d}", "enum_name", name, "enum_val", offset); break; case eLF_STRUCTURE: case eLF_UNION: pdb->cb_printf ("{\"%s\":\"%s\",\"%s\":\"%s\",\"%s\":%d}", "member_type", type + strlen("(member)") + 1, "member_name", name, "offset", offset); break; default: break; } break; } R_FREE (type); i++; } if (mode == 'r') { pdb->cb_printf ("%s %s ", command_field, name_field); if (lt != eLF_ENUM) { pdb->cb_printf ("%s ", flags_format_field); } else { pdb->cb_printf ("%c ", '{'); } sym = (lt == eLF_ENUM) ? ',' : ' '; for (i = 0; i < members_amount; i++) { pdb->cb_printf ("%s", members_name_field[i]); if ((i + 1) != members_amount) { pdb->cb_printf ("%c", sym); } } if (lt == eLF_ENUM) { pdb->cb_printf (" };\"\n"); } else { pdb->cb_printf ("\n"); } } if (mode == 'j') { pdb->cb_printf ("]}"); } err: if (mode == 'r') { R_FREE (command_field); R_FREE(name_field); R_FREE(flags_format_field); for (i = 0; i < members_amount; i++) { R_FREE (members_name_field[i]); } R_FREE (members_name_field); } } } if (mode == 'j') { pdb->cb_printf ("]}"); } }
static void print_gvars(R_PDB *pdb, ut64 img_base, int format) { SStreamParseFunc *omap = 0, *sctns = 0, *sctns_orig = 0 , *gsym = 0, *tmp = 0; SIMAGE_SECTION_HEADER *sctn_header = 0; SGDATAStream *gsym_data_stream = 0; SPEStream *pe_stream = 0; SGlobal *gdata = 0; RListIter *it = 0; RList *l = 0; int is_first = 1; l = pdb->pdb_streams2; it = r_list_iterator (l); while (r_list_iter_next (it)) { tmp = (SStreamParseFunc *) r_list_iter_get(it); switch (tmp->type) { case ePDB_STREAM_SECT__HDR_ORIG: sctns_orig = tmp; break; case ePDB_STREAM_SECT_HDR: sctns = tmp; break; case ePDB_STREAM_OMAP_FROM_SRC: omap = tmp; break; case ePDB_STREAM_GSYM: gsym = tmp; break; default: break; } } if (!gsym) { eprintf ("there is no global symbols in current pdb\n"); return; } if (format == 'j') { pdb->cb_printf ("{\"%s\":[","gvars"); } gsym_data_stream = (SGDATAStream *) gsym->stream; if ((omap != 0) && (sctns_orig != 0)) { pe_stream = (SPEStream *) sctns_orig->stream; } else { pe_stream = (SPEStream *) sctns->stream; } it = r_list_iterator (gsym_data_stream->globals_list); while (r_list_iter_next (it)) { gdata = (SGlobal *) r_list_iter_get (it); sctn_header = r_list_get_n (pe_stream->sections_hdrs, (gdata->segment -1)); if (sctn_header) { char *name = r_name_filter2 (gdata->name.name); switch (format) { case 2: case 'j': // JSON if (!is_first) { pdb->cb_printf (","); } pdb->cb_printf ("{\"%s\":%d,\"%s\":%d,\"%s\":\"%s\",\"%s\":\"%s\"}", "address", (ut64)(img_base + omap_remap((omap) ? (omap->stream) : 0, gdata->offset + sctn_header->virtual_address)), "symtype", gdata->symtype, "section_name", sctn_header->name, "gdata_name", name); break; case 1: case '*': case 'r': pdb->cb_printf ("f pdb.%s = 0x%"PFMT64x" # %d %s\n", name, (ut64)(img_base + omap_remap((omap) ? (omap->stream) : 0, gdata->offset + sctn_header->virtual_address)), gdata->symtype, sctn_header->name); break; case 'd': default: pdb->cb_printf ("0x%08"PFMT64x" %d %s %s\n", (ut64) (img_base + omap_remap((omap) ? (omap->stream) : 0, gdata->offset + sctn_header->virtual_address)), gdata->symtype, sctn_header->name, gdata->name.name); break; } // TODO: implement MSVC C++ name demangle free (name); } else { eprintf ("Skipping %s, segment %d does not exist\n", gdata->name.name, (gdata->segment -1)); } is_first = 0; } if (format == 'j') { pdb->cb_printf ("]}"); } }