R_API void r_debug_map_list(RDebug *dbg, ut64 addr, int rad) { RListIter *iter = r_list_iterator (dbg->maps); if (rad) { while (r_list_iter_next (iter)) { RDebugMap *map = r_list_iter_get (iter); dbg->printf ("f map.%s.%s 0x%08"PFMT64x" 0x%08"PFMT64x"\n", map->name, r_str_rwx_i (map->perm), map->addr_end - map->addr, map->addr); } iter = r_list_iterator (dbg->maps_user); while (r_list_iter_next (iter)) { RDebugMap *map = r_list_iter_get (iter); dbg->printf ("f map.%s.%s 0x%08"PFMT64x" 0x%08"PFMT64x"\n", map->name, r_str_rwx_i (map->perm), map->addr_end - map->addr, map->addr); } } else { while (r_list_iter_next (iter)) { RDebugMap *map = r_list_iter_get (iter); dbg->printf ("sys 0x%08"PFMT64x" %c 0x%08"PFMT64x" %c %s %s\n", map->addr, (addr>=map->addr && addr<=map->addr_end)?'*':'-', map->addr_end, map->user?'u':'s', r_str_rwx_i (map->perm), map->name); } iter = r_list_iterator (dbg->maps_user); while (r_list_iter_next (iter)) { RDebugMap *map = r_list_iter_get (iter); dbg->printf ("usr 0x%08"PFMT64x" - 0x%08"PFMT64x" %c %x %s\n", map->addr, map->addr_end, map->user?'u':'s', map->perm, map->name); } } }
int alloc_format_flag_and_member_fields(RList *ptmp, char **flags_format_field, int *members_amount, char ***members_name_field) { int i = 0; RListIter *it2 = 0; int size = 0; it2 = r_list_iterator(ptmp); while (r_list_iter_next(it2)) { (void)r_list_iter_get(it2); *members_amount = *members_amount + 1; } if (!*members_amount) { return 0; } *flags_format_field = (char *) malloc(*members_amount + 1); memset(*flags_format_field, 0, *members_amount + 1); size = sizeof *members_name_field * (*members_amount); *members_name_field = (char **) malloc(size); for(i = 0; i < *members_amount; i++) { (*members_name_field)[i] = 0; } return 1; }
/* XXX Use r_list_destroy? */ R_API void r_debug_map_list_free(RList *maps) { RListIter *iter = r_list_iterator (maps); while (r_list_iter_next (iter)) { RDebugMap *map = r_list_iter_get (iter); r_debug_map_free (map); } r_list_free (maps); }
R_API RDebugMap *r_debug_map_get(RDebug *dbg, ut64 addr) { RDebugMap *ret = NULL; RListIter *iter = r_list_iterator (dbg->maps); while (r_list_iter_next (iter)) { RDebugMap *map = r_list_iter_get (iter); if (addr >= map->addr && addr <= map->addr_end) { ret = map; break; } } return ret; }
static void free_dbi_stream(void *stream) { SDbiStream *t = (SDbiStream *) stream; SDBIExHeader *dbi_ex_header = 0; RListIter *it = r_list_iterator(t->dbiexhdrs); while (r_list_iter_next(it)) { dbi_ex_header = (SDBIExHeader *) r_list_iter_get(it); free(dbi_ex_header->modName.name); free(dbi_ex_header->objName.name); free(dbi_ex_header); } r_list_free(t->dbiexhdrs); }
void free_omap_stream(void *stream) { SOmapStream *omap_stream = (SOmapStream *) stream; RListIter *it = 0; SOmapEntry *omap_entry = 0; it = r_list_iterator(omap_stream->omap_entries); while (r_list_iter_next(it)) { omap_entry = (SOmapEntry *) r_list_iter_get(it); free(omap_entry); } r_list_free(omap_stream->omap_entries); }
void free_pe_stream(void *stream) { SPEStream *pe_stream = (SPEStream *) stream; SIMAGE_SECTION_HEADER *sctn_header = 0; RListIter *it = 0; it = r_list_iterator(pe_stream->sections_hdrs); while (r_list_iter_next(it)) { sctn_header = (SIMAGE_SECTION_HEADER *) r_list_iter_get(it); free(sctn_header); } r_list_free(pe_stream->sections_hdrs); }
void free_fpo_new_stream(void *stream) { SFPONewStream *fpo_stream = (SFPONewStream *) stream; RListIter *it = 0; SFPO_DATA_V2 *fpo_data = 0; it = r_list_iterator(fpo_stream->fpo_data_list); while (r_list_iter_next(it)) { fpo_data = (SFPO_DATA_V2 *) r_list_iter_get(it); free(fpo_data); } r_list_free(fpo_stream->fpo_data_list); }
static void find_indx_in_list(RList *l, int index, SStreamParseFunc **res) { SStreamParseFunc *stream_parse_func = 0; RListIter *it = 0; *res = 0; it = r_list_iterator(l); while (r_list_iter_next(it)) { stream_parse_func = (SStreamParseFunc *) r_list_iter_get(it); if (index == stream_parse_func->indx) { *res = stream_parse_func; return; } } }
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); } }
/////////////////////////////////////////////////////////////////////////////// // 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 finish_pdb_parse(R_PDB *pdb) { R_PDB7_ROOT_STREAM *p = pdb->root_stream; RListIter *it; SPage *page = 0; if (!p) { return; } it = r_list_iterator (p->streams_list); while (r_list_iter_next (it)) { page = (SPage *) r_list_iter_get (it); free (page->stream_pages); page->stream_pages = 0; free (page); page = 0; } r_list_free (p->streams_list); p->streams_list = 0; free (p); p = 0; // end of free of R_PDB7_ROOT_STREAM // TODO: maybe create some kind of destructor? // free of pdb->pdb_streams // SParsedPDBStream *parsed_pdb_stream = 0; SPDBInfoStream *pdb_info_stream = 0; STpiStream *tpi_stream = 0; SDbiStream *dbi_stream = 0; SStreamParseFunc *stream_parse_func; R_PDB_STREAM *pdb_stream = 0; int i = 0; it = r_list_iterator (pdb->pdb_streams); while (r_list_iter_next(it)) { switch (i) { case 1: pdb_info_stream = (SPDBInfoStream *) r_list_iter_get(it); pdb_info_stream->free_(pdb_info_stream); free(pdb_info_stream); break; case 2: tpi_stream = (STpiStream *) r_list_iter_get(it); tpi_stream->free_(tpi_stream); free (tpi_stream); break; case 3: dbi_stream = (SDbiStream *) r_list_iter_get(it); dbi_stream->free_(dbi_stream); free (dbi_stream); break; default: find_indx_in_list(pdb->pdb_streams2, i, &stream_parse_func); if (stream_parse_func) { break; } pdb_stream = (R_PDB_STREAM *) r_list_iter_get(it); pdb_stream->free_(pdb_stream); free (pdb_stream); break; } i++; } r_list_free (pdb->pdb_streams); // enf of free of pdb->pdb_streams // start of free pdb->pdb_streams2 it = r_list_iterator(pdb->pdb_streams2); while (r_list_iter_next (it)) { stream_parse_func = (SStreamParseFunc *) r_list_iter_get(it); if (stream_parse_func->free) { stream_parse_func->free(stream_parse_func->stream); free(stream_parse_func->stream); } free (stream_parse_func); } r_list_free (pdb->pdb_streams2); // end of free pdb->streams2 free (pdb->stream_map); free (pdb->buf); // fclose(pdb->fp); // printf("finish_pdb_parse()\n"); }
static int pdb_read_root(R_PDB *pdb) { int i = 0; RList *pList = pdb->pdb_streams; R_PDB7_ROOT_STREAM *root_stream = pdb->root_stream; R_PDB_STREAM *pdb_stream = 0; SPDBInfoStream *pdb_info_stream = 0; STpiStream *tpi_stream = 0; R_STREAM_FILE stream_file; RListIter *it; SPage *page = 0; SStreamParseFunc *stream_parse_func = 0; it = r_list_iterator (root_stream->streams_list); while (r_list_iter_next (it)) { page = (SPage*) r_list_iter_get (it); init_r_stream_file (&stream_file, pdb->buf, (int *)page->stream_pages, page->num_pages/*root_stream->pdb_stream.pages_amount*/, page->stream_size, root_stream->pdb_stream.page_size); switch (i) { //TODO: rewrite for style like for streams from dbg stream // look default case ePDB_STREAM_PDB: pdb_info_stream = R_NEW0 (SPDBInfoStream); if (!pdb_info_stream) return 0; pdb_info_stream->free_ = free_info_stream; parse_pdb_info_stream (pdb_info_stream, &stream_file); r_list_append (pList, pdb_info_stream); break; case ePDB_STREAM_TPI: tpi_stream = R_NEW0 (STpiStream); if (!tpi_stream) return 0; init_tpi_stream (tpi_stream); if (!parse_tpi_stream (tpi_stream, &stream_file)) { free (tpi_stream); return 0; } r_list_append(pList, tpi_stream); break; case ePDB_STREAM_DBI: { SDbiStream *dbi_stream = R_NEW0 (SDbiStream); if (!dbi_stream) return 0; init_dbi_stream (dbi_stream); parse_dbi_stream (dbi_stream, &stream_file); r_list_append (pList, dbi_stream); pdb->pdb_streams2 = r_list_new (); fill_list_for_stream_parsing (pdb->pdb_streams2, dbi_stream); break; } default: find_indx_in_list (pdb->pdb_streams2, i, &stream_parse_func); if (stream_parse_func) { if (stream_parse_func->parse_stream) { stream_parse_func->parse_stream (stream_parse_func->stream, &stream_file); break; } } pdb_stream = R_NEW0 (R_PDB_STREAM); if (!pdb_stream) return 0; init_r_pdb_stream (pdb_stream, pdb->buf, (int *)page->stream_pages, root_stream->pdb_stream.pages_amount, i, page->stream_size, root_stream->pdb_stream.page_size); r_list_append (pList, pdb_stream); break; } if (stream_file.error) { return 0; } i++; } return 1; }
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 ("]}"); } }