From b79f9005601a6aa538cdb6c865016ec8fc667575 Mon Sep 17 00:00:00 2001 From: basstorm Date: Mon, 23 Aug 2021 15:57:27 +0800 Subject: [PATCH] Use new `rz_buf_read` API --- librz/bin/pdb/dbi.c | 143 ++++++---- librz/bin/pdb/dbi.h | 24 +- librz/bin/pdb/gdata.c | 31 +- librz/bin/pdb/omap.c | 10 +- librz/bin/pdb/pdb.c | 168 +++++++---- librz/bin/pdb/stream_pe.c | 36 +-- librz/bin/pdb/tpi.c | 583 ++++++++++++++++++++++++++++---------- 7 files changed, 694 insertions(+), 301 deletions(-) diff --git a/librz/bin/pdb/dbi.c b/librz/bin/pdb/dbi.c index b1b6946be9d..1f2c41d1baa 100644 --- a/librz/bin/pdb/dbi.c +++ b/librz/bin/pdb/dbi.c @@ -15,40 +15,39 @@ RZ_IPI void rz_bin_pdb_free_dbi_stream(DbiStream *stream) { rz_list_free(stream->ex_hdrs); } -static void parse_dbi_stream_header(DbiStream *s, RzBuffer *buf) { - s->hdr.version_signature = rz_buf_read_le32(buf); - s->hdr.version_header = rz_buf_read_le32(buf); - s->hdr.age = rz_buf_read_le32(buf); - s->hdr.global_stream_index = rz_buf_read_le16(buf); - s->hdr.build_number = rz_buf_read_le16(buf); - s->hdr.public_stream_index = rz_buf_read_le16(buf); - s->hdr.pdb_dll_version = rz_buf_read_le16(buf); - s->hdr.sym_record_stream = rz_buf_read_le16(buf); - s->hdr.pdb_dll_rbld = rz_buf_read_le16(buf); - s->hdr.mod_info_size = rz_buf_read_le32(buf); - s->hdr.section_contribution_size = rz_buf_read_le32(buf); - s->hdr.section_map_size = rz_buf_read_le32(buf); - s->hdr.source_info_size = rz_buf_read_le32(buf); - s->hdr.type_server_map_size = rz_buf_read_le32(buf); - s->hdr.mfc_type_server_index = rz_buf_read_le32(buf); - s->hdr.optional_dbg_header_size = rz_buf_read_le32(buf); - s->hdr.ec_substream_size = rz_buf_read_le32(buf); - s->hdr.flags = rz_buf_read_le16(buf); - s->hdr.machine = rz_buf_read_le16(buf); - s->hdr.padding = rz_buf_read_le32(buf); +static bool parse_dbi_stream_header(DbiStream *s, RzBuffer *buf) { + return rz_buf_read_le32(buf, &s->hdr.version_signature) && + rz_buf_read_le32(buf, &s->hdr.version_header) && + rz_buf_read_le32(buf, &s->hdr.age) && + rz_buf_read_le16(buf, &s->hdr.global_stream_index) && + rz_buf_read_le16(buf, &s->hdr.build_number) && + rz_buf_read_le16(buf, &s->hdr.public_stream_index) && + rz_buf_read_le16(buf, &s->hdr.pdb_dll_version) && + rz_buf_read_le16(buf, &s->hdr.sym_record_stream) && + rz_buf_read_le16(buf, &s->hdr.pdb_dll_rbld) && + rz_buf_read_le32(buf, &s->hdr.mod_info_size) && + rz_buf_read_le32(buf, &s->hdr.section_contribution_size) && + rz_buf_read_le32(buf, &s->hdr.section_map_size) && + rz_buf_read_le32(buf, &s->hdr.source_info_size) && + rz_buf_read_le32(buf, &s->hdr.type_server_map_size) && + rz_buf_read_le32(buf, &s->hdr.mfc_type_server_index) && + rz_buf_read_le32(buf, &s->hdr.optional_dbg_header_size) && + rz_buf_read_le32(buf, &s->hdr.ec_substream_size) && + rz_buf_read_le16(buf, &s->hdr.flags) && + rz_buf_read_le16(buf, &s->hdr.machine) && + rz_buf_read_le32(buf, &s->hdr.padding); } -static ut32 parse_dbi_stream_section_entry(DbiStreamExHdr *hdr, RzBuffer *buf) { - hdr->SectionContr.Section = rz_buf_read_le16(buf); - *(ut16 *)hdr->SectionContr.Padding1 = rz_buf_read_le16(buf); - hdr->SectionContr.Offset = rz_buf_read_le32(buf); - hdr->SectionContr.Size = rz_buf_read_le32(buf); - hdr->SectionContr.Characteristics = rz_buf_read_le32(buf); - hdr->SectionContr.ModuleIndex = rz_buf_read_le16(buf); - *(ut16 *)hdr->SectionContr.Padding2 = rz_buf_read_le16(buf); - hdr->SectionContr.DataCrc = rz_buf_read_le32(buf); - hdr->SectionContr.RelocCrc = rz_buf_read_le32(buf); - return sizeof(hdr->SectionContr); +static bool parse_dbi_stream_section_entry(DbiStreamExHdr *hdr, RzBuffer *buf) { + return rz_buf_read_le16(buf, &hdr->sec_con.Section) && + rz_buf_read_le16(buf, &hdr->sec_con.Padding1) && + rz_buf_read_le32(buf, &hdr->sec_con.Offset) && + rz_buf_read_le32(buf, &hdr->sec_con.Size) && + rz_buf_read_le32(buf, &hdr->sec_con.Characteristics) && + rz_buf_read_le16(buf, &hdr->sec_con.ModuleIndex) && + rz_buf_read_le16(buf, &hdr->sec_con.Padding2) && + rz_buf_read_le32(buf, &hdr->sec_con.DataCrc) && + rz_buf_read_le32(buf, &hdr->sec_con.RelocCrc); } static bool parse_dbi_stream_ex_header(DbiStream *s, RzBuffer *buf) { @@ -64,22 +63,35 @@ static bool parse_dbi_stream_ex_header(DbiStream *s, RzBuffer *buf) { if (!hdr) { return false; } - hdr->unknown = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &hdr->unknown)) { + return false; + } read_len += sizeof(ut32); - read_len += parse_dbi_stream_section_entry(hdr, buf); - hdr->Flags = rz_buf_read_le16(buf); - hdr->ModuleSymStream = rz_buf_read_le16(buf); + if (!parse_dbi_stream_section_entry(hdr, buf)) { + return false; + } + read_len += sizeof(SectionContr); + if (!rz_buf_read_le16(buf, &hdr->Flags) || + !rz_buf_read_le16(buf, &hdr->ModuleSymStream)) { + return false; + } read_len += sizeof(ut16) * 2; - hdr->SymByteSize = rz_buf_read_le32(buf); - hdr->C11ByteSize = rz_buf_read_le32(buf); - hdr->C13ByteSize = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &hdr->SymByteSize) || + !rz_buf_read_le32(buf, &hdr->C11ByteSize) || + !rz_buf_read_le32(buf, &hdr->C13ByteSize)) { + return false; + } read_len += sizeof(ut32) * 3; - hdr->SourceFileCount = rz_buf_read_le16(buf); - *(ut16 *)hdr->Padding = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &hdr->SourceFileCount) || + !rz_buf_read_le16(buf, &hdr->Padding)) { + return false; + } read_len += sizeof(ut16) * 2; - hdr->Unused2 = rz_buf_read_le32(buf); - hdr->SourceFileNameIndex = rz_buf_read_le32(buf); - hdr->PdbFilePathNameIndex = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &hdr->Unused2) || + !rz_buf_read_le32(buf, &hdr->SourceFileNameIndex) || + !rz_buf_read_le32(buf, &hdr->PdbFilePathNameIndex)) { + return false; + } read_len += sizeof(ut32) * 3; hdr->ModuleName = rz_buf_get_string(buf, rz_buf_tell(buf)); @@ -105,18 +117,21 @@ static bool parse_dbi_stream_ex_header(DbiStream *s, RzBuffer *buf) { return true; } -static void parse_dbi_dbg_header(DbiStream *s, RzBuffer *buf) { - s->dbg_hdr.sn_fpo = rz_buf_read_le16(buf); - s->dbg_hdr.sn_exception = rz_buf_read_le16(buf); - s->dbg_hdr.sn_fixup = rz_buf_read_le16(buf); - s->dbg_hdr.sn_omap_to_src = rz_buf_read_le16(buf); - s->dbg_hdr.sn_omap_from_src = rz_buf_read_le16(buf); - s->dbg_hdr.sn_section_hdr = rz_buf_read_le16(buf); - s->dbg_hdr.sn_token_rid_map = rz_buf_read_le16(buf); - s->dbg_hdr.sn_xdata = rz_buf_read_le16(buf); - s->dbg_hdr.sn_pdata = rz_buf_read_le16(buf); - s->dbg_hdr.sn_new_fpo = rz_buf_read_le16(buf); - s->dbg_hdr.sn_section_hdr_orig = rz_buf_read_le16(buf); +static bool parse_dbi_dbg_header(DbiStream *s, RzBuffer *buf) { + if (!rz_buf_read_le16(buf, &s->dbg_hdr.sn_fpo) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_exception) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_fixup) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_omap_to_src) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_omap_from_src) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_section_hdr) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_token_rid_map) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_xdata) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_pdata) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_new_fpo) || + !rz_buf_read_le16(buf, &s->dbg_hdr.sn_section_hdr_orig)) { + return false; + } + return true; } RZ_IPI bool parse_dbi_stream(RzPdb *pdb, MsfStream *stream) { @@ -127,15 +142,17 @@ RZ_IPI bool parse_dbi_stream(RzPdb *pdb, MsfStream *stream) { DbiStream *s = pdb->s_dbi; RzBuffer *buf = stream->stream_data; // parse header - parse_dbi_stream_header(s, buf); - parse_dbi_stream_ex_header(s, buf); + if (!parse_dbi_stream_header(s, buf) || !parse_dbi_stream_ex_header(s, buf)) { + return false; + } + // skip these streams - ut64 seek = s->hdr.section_contribution_size + - s->hdr.section_map_size + - s->hdr.source_info_size + - s->hdr.type_server_map_size + + ut64 seek = s->hdr.section_contribution_size + s->hdr.section_map_size + + s->hdr.source_info_size + s->hdr.type_server_map_size + s->hdr.ec_substream_size; rz_buf_seek(buf, rz_buf_tell(buf) + seek, RZ_BUF_SET); - parse_dbi_dbg_header(s, buf); + if (!parse_dbi_dbg_header(s, buf)) { + return false; + } return true; } diff --git a/librz/bin/pdb/dbi.h b/librz/bin/pdb/dbi.h index 5f3a367e843..0a1f481bdfb 100644 --- a/librz/bin/pdb/dbi.h +++ b/librz/bin/pdb/dbi.h @@ -36,19 +36,21 @@ typedef struct dbi_stream_header_t { ut32 padding; } DbiStreamHdr; +typedef struct SectionContribEntry { + ut16 Section; + char Padding1[2]; + st32 Offset; + st32 Size; + ut32 Characteristics; + ut16 ModuleIndex; + char Padding2[2]; + ut32 DataCrc; + ut32 RelocCrc; +} SectionContr; + typedef struct dbi_stream_ex_header_t { ut32 unknown; - struct SectionContribEntry { - ut16 Section; - char Padding1[2]; - st32 Offset; - st32 Size; - ut32 Characteristics; - ut16 ModuleIndex; - char Padding2[2]; - ut32 DataCrc; - ut32 RelocCrc; - } SectionContr; + SectionContr sec_con; ut16 Flags; ut16 ModuleSymStream; ut32 SymByteSize; diff --git a/librz/bin/pdb/gdata.c b/librz/bin/pdb/gdata.c index eab91378c76..8d359674d92 100644 --- a/librz/bin/pdb/gdata.c +++ b/librz/bin/pdb/gdata.c @@ -4,11 +4,15 @@ #include "pdb.h" -static void parse_gdata_global(GDataGlobal *global, RzBuffer *buf, ut32 *read_len) { - global->symtype = rz_buf_read_le32(buf); - global->offset = rz_buf_read_le32(buf); +static bool parse_gdata_global(GDataGlobal *global, RzBuffer *buf, ut32 *read_len) { + if (!rz_buf_read_le32(buf, &global->symtype) || + !rz_buf_read_le32(buf, &global->offset)) { + return false; + } *read_len += sizeof(ut32) * 2; - global->segment = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &global->segment)) { + return false; + } *read_len += sizeof(ut16); if (global->leaf_type == 0x110E) { global->name = rz_buf_get_string(buf, rz_buf_tell(buf)); @@ -17,7 +21,9 @@ static void parse_gdata_global(GDataGlobal *global, RzBuffer *buf, ut32 *read_le rz_buf_seek(buf, rz_buf_tell(buf) + len, RZ_BUF_SET); *read_len += len; } else { - global->name_len = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &global->name_len)) { + return false; + } *read_len += sizeof(ut8); } if ((*read_len % 4)) { @@ -25,6 +31,7 @@ static void parse_gdata_global(GDataGlobal *global, RzBuffer *buf, ut32 *read_le rz_buf_seek(buf, rz_buf_tell(buf) + remain, RZ_BUF_SET); read_len += remain; } + return true; } RZ_IPI bool parse_gdata_stream(RzPdb *pdb, MsfStream *stream) { @@ -41,12 +48,17 @@ RZ_IPI bool parse_gdata_stream(RzPdb *pdb, MsfStream *stream) { ut16 len; while (true) { ut32 read_len = 0; - len = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &len)) { + break; + } read_len += sizeof(ut16); if (len == 0 || len == UT16_MAX) { break; } - ut16 leaf_type = rz_buf_read_le16(buf); + ut16 leaf_type; + if (!rz_buf_read_le16(buf, &leaf_type)) { + return false; + } read_len += sizeof(ut16); if (leaf_type == 0x110E || leaf_type == 0x1009) { GDataGlobal *global = RZ_NEW0(GDataGlobal); @@ -54,7 +66,10 @@ RZ_IPI bool parse_gdata_stream(RzPdb *pdb, MsfStream *stream) { goto skip; } global->leaf_type = leaf_type; - parse_gdata_global(global, buf, &read_len); + if (!parse_gdata_global(global, buf, &read_len)) { + RZ_FREE(global); + return false; + } rz_list_append(s->global_list, global); continue; } diff --git a/librz/bin/pdb/omap.c b/librz/bin/pdb/omap.c index a8d88769204..e2098c860e4 100644 --- a/librz/bin/pdb/omap.c +++ b/librz/bin/pdb/omap.c @@ -23,8 +23,10 @@ RZ_IPI bool parse_omap_stream(RzPdb *pdb, MsfStream *stream) { rz_list_free(s->entries); return false; } - entry->from = rz_buf_read_le32(buf); - entry->to = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &entry->from) || + !rz_buf_read_le32(buf, &entry->to)) { + return false; + } read_len += sizeof(ut32) * 2; rz_list_append(s->entries, entry); } @@ -35,9 +37,7 @@ RZ_IPI void free_omap_stream(OmapStream *stream) { OmapEntry *entry; RzListIter *it; - rz_list_foreach (stream->entries, it, entry) { - RZ_FREE(entry); - } + rz_list_foreach (stream->entries, it, entry) { RZ_FREE(entry); } rz_list_free(stream->entries); } diff --git a/librz/bin/pdb/pdb.c b/librz/bin/pdb/pdb.c index 8cf2ddfd23c..ad384cb116a 100644 --- a/librz/bin/pdb/pdb.c +++ b/librz/bin/pdb/pdb.c @@ -10,11 +10,12 @@ /** * \brief Prints out types in a default format "idpi" command - * + * * \param pdb pdb structure for printing function * \param types List of types */ -static void print_types_regular(RzTypeDB *db, const RzPdb *pdb, const RzList *types) { +static void print_types_regular(RzTypeDB *db, const RzPdb *pdb, + const RzList *types) { rz_return_if_fail(pdb); if (!types) { eprintf("there is nothing to print!\n"); @@ -28,7 +29,8 @@ static void print_types_regular(RzTypeDB *db, const RzPdb *pdb, const RzList *ty rz_strbuf_appendf(buf, "struct %s { \n", type->name); RzTypeStructMember *memb; rz_vector_foreach(&type->struct_data.members, memb) { - char *declaration = rz_type_identifier_declaration_as_string(db, memb->type, memb->name); + char *declaration = rz_type_identifier_declaration_as_string( + db, memb->type, memb->name); if (memb->type->kind == RZ_TYPE_KIND_CALLABLE) { rz_strbuf_appendf(buf, "\t%s \n", declaration); } else { @@ -43,7 +45,8 @@ static void print_types_regular(RzTypeDB *db, const RzPdb *pdb, const RzList *ty rz_strbuf_appendf(buf, "enum %s { \n", type->name); RzTypeEnumCase *cas; rz_vector_foreach(&type->enum_data.cases, cas) { - rz_strbuf_appendf(buf, "\t%s = 0x%" PFMT64x ", \n", cas->name, cas->val); + rz_strbuf_appendf(buf, "\t%s = 0x%" PFMT64x ", \n", cas->name, + cas->val); } rz_strbuf_append(buf, " }\n"); break; @@ -52,7 +55,8 @@ static void print_types_regular(RzTypeDB *db, const RzPdb *pdb, const RzList *ty rz_strbuf_appendf(buf, "union %s { \n", type->name); RzTypeUnionMember *memb; rz_vector_foreach(&type->union_data.members, memb) { - char *declaration = rz_type_identifier_declaration_as_string(db, memb->type, memb->name); + char *declaration = rz_type_identifier_declaration_as_string( + db, memb->type, memb->name); rz_strbuf_appendf(buf, "\t%s %s; \n", declaration, memb->name); free(declaration); } @@ -69,11 +73,12 @@ static void print_types_regular(RzTypeDB *db, const RzPdb *pdb, const RzList *ty /** * \brief Prints out types in a json format - "idpij" command - * + * * \param pdb pdb structure for printing function * \param types List of types */ -static void print_types_json(RzTypeDB *db, const RzPdb *pdb, PJ *pj, const RzList *types) { +static void print_types_json(RzTypeDB *db, const RzPdb *pdb, PJ *pj, + const RzList *types) { rz_return_if_fail(pdb && types && pj); RzListIter *it; @@ -134,11 +139,12 @@ static void print_types_json(RzTypeDB *db, const RzPdb *pdb, PJ *pj, const RzLis /** * \brief Prints out all the type information in regular,json or pf format - * + * * \param pdb PDB information * \param mode printing mode */ -RZ_API void rz_bin_pdb_print_types(RzTypeDB *db, const RzPdb *pdb, PJ *pj, const int mode) { +RZ_API void rz_bin_pdb_print_types(RzTypeDB *db, const RzPdb *pdb, PJ *pj, + const int mode) { TpiStream *stream = pdb->s_tpi; if (!stream) { @@ -146,12 +152,17 @@ RZ_API void rz_bin_pdb_print_types(RzTypeDB *db, const RzPdb *pdb, PJ *pj, const return; } switch (mode) { - case 'd': print_types_regular(db, pdb, stream->print_type); return; - case 'j': print_types_json(db, pdb, pj, stream->print_type); return; + case 'd': + print_types_regular(db, pdb, stream->print_type); + return; + case 'j': + print_types_json(db, pdb, pj, stream->print_type); + return; } } -RZ_API void rz_bin_pdb_print_gvars(RzPdb *pdb, ut64 img_base, PJ *pj, int format) { +RZ_API void rz_bin_pdb_print_gvars(RzPdb *pdb, ut64 img_base, PJ *pj, + int format) { PeImageSectionHeader *sctn_header = 0; GDataStream *gsym_data_stream = 0; PeStream *pe_stream = 0; @@ -177,15 +188,21 @@ RZ_API void rz_bin_pdb_print_gvars(RzPdb *pdb, ut64 img_base, PJ *pj, int format switch (format) { case 'j': // JSON pj_o(pj); - pj_kN(pj, "address", (img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address))); + pj_kN(pj, "address", + (img_base + + omap_remap(omap_stream, + gdata->offset + sctn_header->virtual_address))); pj_kN(pj, "symtype", gdata->symtype); pj_ks(pj, "section_name", sctn_header->name); pj_ks(pj, "gdata_name", name); pj_end(pj); break; case 'd': - rz_cons_printf("0x%08" PFMT64x " %d %.*s %s\n", - (ut64)(img_base + omap_remap(omap_stream, gdata->offset + sctn_header->virtual_address)), + rz_cons_printf( + "0x%08" PFMT64x " %d %.*s %s\n", + (ut64)(img_base + + omap_remap(omap_stream, + gdata->offset + sctn_header->virtual_address)), gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name, name); break; default: @@ -207,17 +224,20 @@ static bool parse_pdb_stream(RzPdb *pdb, MsfStream *stream) { pdb->s_pdb = RZ_NEW0(PdbStream); PdbStream *s = pdb->s_pdb; RzBuffer *buf = stream->stream_data; - s->hdr.version = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &s->hdr.version) || + !rz_buf_read_le32(buf, &s->hdr.signature) || + !rz_buf_read_le32(buf, &s->hdr.age) || + !rz_buf_read_le32(buf, &s->hdr.unique_id.data1) || + !rz_buf_read_le16(buf, &s->hdr.unique_id.data2) || + !rz_buf_read_le16(buf, &s->hdr.unique_id.data3) || + !rz_buf_read_le64(buf, &s->hdr.unique_id.data4)) { + return false; + } + if (s->hdr.version != VC70) { RZ_LOG_ERROR("Error Unsupported PDB version.\n"); return false; } - s->hdr.signature = rz_buf_read_le32(buf); - s->hdr.age = rz_buf_read_le32(buf); - s->hdr.unique_id.data1 = rz_buf_read_le32(buf); - s->hdr.unique_id.data2 = rz_buf_read_le16(buf); - s->hdr.unique_id.data3 = rz_buf_read_le16(buf); - *(ut64 *)s->hdr.unique_id.data4 = rz_buf_read_le64(buf); return true; } @@ -229,26 +249,44 @@ static bool parse_streams(RzPdb *pdb) { case PDB_STREAM_ROOT: break; case PDB_STREAM_PDB: - parse_pdb_stream(pdb, ms); + if (!parse_pdb_stream(pdb, ms)) { + RZ_LOG_ERROR("Parse pdb stream failed."); + return false; + } break; case PDB_STREAM_TPI: - parse_tpi_stream(pdb, ms); + if (!parse_tpi_stream(pdb, ms)) { + RZ_LOG_ERROR("Parse tpi stream failed."); + return false; + } break; case PDB_STREAM_DBI: - parse_dbi_stream(pdb, ms); + if (!parse_dbi_stream(pdb, ms)) { + RZ_LOG_ERROR("Parse dbi stream failed."); + return false; + } break; default: { if (!pdb->s_dbi) { break; } if (ms->stream_idx == pdb->s_dbi->hdr.sym_record_stream) { - parse_gdata_stream(pdb, ms); + if (!parse_gdata_stream(pdb, ms)) { + RZ_LOG_ERROR("Parse gdata stream failed."); + return false; + } } else if (ms->stream_idx == pdb->s_dbi->dbg_hdr.sn_section_hdr || ms->stream_idx == pdb->s_dbi->dbg_hdr.sn_section_hdr_orig) { - parse_pe_stream(pdb, ms); + if (!parse_pe_stream(pdb, ms)) { + RZ_LOG_ERROR("Parse pe stream failed."); + return false; + } } else if (ms->stream_idx == pdb->s_dbi->dbg_hdr.sn_omap_to_src || ms->stream_idx == pdb->s_dbi->dbg_hdr.sn_omap_from_src) { - parse_omap_stream(pdb, ms); + if (!parse_omap_stream(pdb, ms)) { + RZ_LOG_ERROR("Parse omap stream failed."); + return false; + } } break; } @@ -294,19 +332,28 @@ static RzList *pdb7_extract_streams(RzPdb *pdb, MsfStreamDirectory *msd) { } stream->stream_idx = i; stream->stream_size = msd->StreamSizes[i]; - stream->blocks_num = count_blocks(stream->stream_size, pdb->super_block->block_size); + stream->blocks_num = + count_blocks(stream->stream_size, pdb->super_block->block_size); if (!stream->stream_size) { stream->stream_data = NULL; rz_list_append(streams, stream); continue; } - ut8 *stream_data = (ut8 *)malloc(stream->blocks_num * pdb->super_block->block_size); + ut8 *stream_data = + (ut8 *)malloc(stream->blocks_num * pdb->super_block->block_size); for (size_t j = 0; j < stream->blocks_num; j++) { - ut32 block_idx = rz_buf_read_le32(msd->sd); - rz_buf_seek(pdb->buf, block_idx * pdb->super_block->block_size, RZ_BUF_SET); - rz_buf_read(pdb->buf, stream_data + j * pdb->super_block->block_size, pdb->super_block->block_size); + ut32 block_idx; + if (!rz_buf_read_le32(msd->sd, &block_idx)) { + rz_list_free(streams); + return NULL; + } + rz_buf_seek(pdb->buf, block_idx * pdb->super_block->block_size, + RZ_BUF_SET); + rz_buf_read(pdb->buf, stream_data + j * pdb->super_block->block_size, + pdb->super_block->block_size); } - stream->stream_data = rz_buf_new_with_bytes(stream_data, stream->stream_size); + stream->stream_data = + rz_buf_new_with_bytes(stream_data, stream->stream_size); if (!stream->stream_data) { RZ_FREE(stream_data); rz_list_free(streams); @@ -324,18 +371,24 @@ static RzList *pdb7_extract_streams(RzPdb *pdb, MsfStreamDirectory *msd) { static MsfStreamDirectory *pdb7_extract_msf_stream_directory(RzPdb *pdb) { // Get block map - ut32 block_num = count_blocks(pdb->super_block->num_directory_bytes, pdb->super_block->block_size); + ut32 block_num = count_blocks(pdb->super_block->num_directory_bytes, + pdb->super_block->block_size); if (!block_num) { RZ_LOG_ERROR("Error block map size.\n"); goto error; } - rz_buf_seek(pdb->buf, pdb->super_block->block_size * pdb->super_block->block_map_addr, RZ_BUF_SET); + rz_buf_seek(pdb->buf, + pdb->super_block->block_size * pdb->super_block->block_map_addr, + RZ_BUF_SET); ut32 *block_map = (ut32 *)malloc(sizeof(ut32) * block_num); if (!block_map) { goto error_memory; } for (size_t i = 0; i < block_num; i++) { - ut32 block_idx = rz_buf_read_le32(pdb->buf); + ut32 block_idx; + if (!rz_buf_read_le32(pdb->buf, &block_idx)) { + goto error; + } if (block_idx > pdb->super_block->num_blocks) { RZ_LOG_ERROR("Error block index.\n"); goto error; @@ -350,8 +403,10 @@ static MsfStreamDirectory *pdb7_extract_msf_stream_directory(RzPdb *pdb) { goto error_memory; } for (size_t i = 0; i < block_num; i++) { - rz_buf_seek(pdb->buf, block_map[i] * pdb->super_block->block_size, RZ_BUF_SET); - rz_buf_read(pdb->buf, stream_directory + i * pdb->super_block->block_size, pdb->super_block->block_size); + rz_buf_seek(pdb->buf, block_map[i] * pdb->super_block->block_size, + RZ_BUF_SET); + rz_buf_read(pdb->buf, stream_directory + i * pdb->super_block->block_size, + pdb->super_block->block_size); } RzBuffer *sd = rz_buf_new_with_bytes(stream_directory, stream_directory_len); if (!sd) { @@ -365,7 +420,10 @@ static MsfStreamDirectory *pdb7_extract_msf_stream_directory(RzPdb *pdb) { if (!msd) { goto error_memory; } - msd->NumStreams = rz_buf_read_le32(sd); + if (!rz_buf_read_le32(sd, &msd->NumStreams)) { + RZ_FREE(msd); + goto error; + } msd->StreamSizes = (ut32 *)malloc(msd->NumStreams * sizeof(ut32)); msd->sd = sd; if (!msd->StreamSizes) { @@ -374,13 +432,19 @@ static MsfStreamDirectory *pdb7_extract_msf_stream_directory(RzPdb *pdb) { } ut32 total_blocks = 0; for (size_t i = 0; i < msd->NumStreams; i++) { - ut32 stream_size = rz_buf_read_le32(sd); + ut32 stream_size; + if (!rz_buf_read_le32(sd, &stream_size)) { + RZ_FREE(msd); + goto error; + } msd->StreamSizes[i] = stream_size; ut32 blocks = count_blocks(stream_size, pdb->super_block->block_size); total_blocks += blocks; } - // NumStreams StreamsSizes StreamsBlockMap - ut32 msd_size = sizeof(ut32) + msd->NumStreams * sizeof(ut32) + total_blocks * sizeof(ut32); + // NumStreams + // StreamsSizes StreamsBlockMap + ut32 msd_size = sizeof(ut32) + msd->NumStreams * sizeof(ut32) + + total_blocks * sizeof(ut32); if (msd_size != pdb->super_block->num_directory_bytes) { RZ_LOG_ERROR("Error stream directory size.\n"); RZ_FREE(msd); @@ -411,7 +475,8 @@ static bool pdb7_parse(RzPdb *pdb) { return false; } -RZ_API RZ_OWN RzPdb *rz_bin_pdb_parse_from_file(RZ_NONNULL const char *filename) { +RZ_API RZ_OWN RzPdb * +rz_bin_pdb_parse_from_file(RZ_NONNULL const char *filename) { RzBuffer *buf = rz_buf_new_slurp(filename); if (!buf) { eprintf("%s: Error reading file \"%s\"\n", __FUNCTION__, filename); @@ -433,13 +498,14 @@ RZ_API RZ_OWN RzPdb *rz_bin_pdb_parse_from_buf(RZ_NONNULL RzBuffer *buf) { RZ_LOG_ERROR("PDB Signature Error!\n"); goto error; } - pdb->super_block->block_size = rz_buf_read_le32(pdb->buf); - pdb->super_block->free_block_map_block = rz_buf_read_le32(pdb->buf); - pdb->super_block->num_blocks = rz_buf_read_le32(pdb->buf); - pdb->super_block->num_directory_bytes = rz_buf_read_le32(pdb->buf); - pdb->super_block->unknown = rz_buf_read_le32(pdb->buf); - pdb->super_block->block_map_addr = rz_buf_read_le32(pdb->buf); - + if (!rz_buf_read_le32(pdb->buf, &pdb->super_block->block_size) || + !rz_buf_read_le32(pdb->buf, &pdb->super_block->free_block_map_block) || + !rz_buf_read_le32(pdb->buf, &pdb->super_block->num_blocks) || + !rz_buf_read_le32(pdb->buf, &pdb->super_block->num_directory_bytes) || + !rz_buf_read_le32(pdb->buf, &pdb->super_block->unknown) || + !rz_buf_read_le32(pdb->buf, &pdb->super_block->block_map_addr)) { + goto error; + } ut64 bufsize = buf->methods->get_size(buf); // length of whole PDB file bool valid = pdb->super_block->num_blocks > 0 && diff --git a/librz/bin/pdb/stream_pe.c b/librz/bin/pdb/stream_pe.c index edf4c7875a0..02020386414 100644 --- a/librz/bin/pdb/stream_pe.c +++ b/librz/bin/pdb/stream_pe.c @@ -4,20 +4,21 @@ #include "pdb.h" -static void parse_image_header(PeImageSectionHeader *hdr, RzBuffer *buf) { - char *name = rz_buf_get_nstring(buf, rz_buf_tell(buf), PDB_SIZEOF_SECTION_NAME); +static bool parse_image_header(PeImageSectionHeader *hdr, RzBuffer *buf) { + char *name = + rz_buf_get_nstring(buf, rz_buf_tell(buf), PDB_SIZEOF_SECTION_NAME); rz_str_cpy(hdr->name, name); RZ_FREE(name); rz_buf_seek(buf, rz_buf_tell(buf) + PDB_SIZEOF_SECTION_NAME, RZ_BUF_SET); - hdr->misc.physical_address = rz_buf_read_le32(buf); - hdr->virtual_address = rz_buf_read_le32(buf); - hdr->size_of_raw_data = rz_buf_read_le32(buf); - hdr->pointer_to_raw_data = rz_buf_read_le32(buf); - hdr->pointer_to_relocations = rz_buf_read_le32(buf); - hdr->pointer_to_line_numbers = rz_buf_read_le32(buf); - hdr->number_of_relocations = rz_buf_read_le16(buf); - hdr->number_of_line_numbers = rz_buf_read_le16(buf); - hdr->charactestics = rz_buf_read_le32(buf); + return rz_buf_read_le32(buf, &hdr->misc.physical_address) && + rz_buf_read_le32(buf, &hdr->virtual_address) && + rz_buf_read_le32(buf, &hdr->size_of_raw_data) && + rz_buf_read_le32(buf, &hdr->pointer_to_raw_data) && + rz_buf_read_le32(buf, &hdr->pointer_to_relocations) && + rz_buf_read_le32(buf, &hdr->pointer_to_line_numbers) && + rz_buf_read_le16(buf, &hdr->number_of_relocations) && + rz_buf_read_le16(buf, &hdr->number_of_line_numbers) && + rz_buf_read_le32(buf, &hdr->charactestics); } RZ_IPI bool parse_pe_stream(RzPdb *pdb, MsfStream *stream) { @@ -28,7 +29,7 @@ RZ_IPI bool parse_pe_stream(RzPdb *pdb, MsfStream *stream) { RzBuffer *buf = stream->stream_data; PeStream *s = pdb->s_pe; if (!s->sections_hdrs) { - s->sections_hdrs = rz_list_new(); + s->sections_hdrs = rz_list_newf(free); } ut32 size = rz_buf_size(buf); ut32 read_len = 0; @@ -38,17 +39,16 @@ RZ_IPI bool parse_pe_stream(RzPdb *pdb, MsfStream *stream) { rz_list_free(s->sections_hdrs); return false; } - parse_image_header(hdr, buf); + if (!parse_image_header(hdr, buf)) { + rz_list_free(s->sections_hdrs); + return false; + } + read_len += sizeof(PeImageSectionHeader); rz_list_append(s->sections_hdrs, hdr); } return true; } RZ_IPI void free_pe_stream(PeStream *stream) { - RzListIter *it; - PeImageSectionHeader *hdr; - rz_list_foreach (stream->sections_hdrs, it, hdr) { - RZ_FREE(hdr); - } rz_list_free(stream->sections_hdrs); }; diff --git a/librz/bin/pdb/tpi.c b/librz/bin/pdb/tpi.c index 6f84974d405..4fa67dbdca8 100644 --- a/librz/bin/pdb/tpi.c +++ b/librz/bin/pdb/tpi.c @@ -6,13 +6,14 @@ static bool is_simple_type(TpiStream *stream, ut32 idx) { /* https://llvm.org/docs/PDB/TpiStream.html#type-indices - .---------------------------.------.----------. - | Unused | Mode | Kind | - '---------------------------'------'----------' - |+32 |+12 |+8 |+0 - */ + .---------------------------.------.----------. + | Unused | Mode | Kind | + '---------------------------'------'----------' + |+32 |+12 |+8 |+0 + */ return idx < stream->header.TypeIndexBegin; - // return ((value & 0x00000000FFF00) <= 0x700 && (value & 0x00000000000FF) < 0x80); + // return ((value & 0x00000000FFF00) <= 0x700 && (value & 0x00000000000FF) < + // 0x80); } int tpi_type_node_cmp(const void *incoming, const RBNode *in_tree, void *user) { @@ -59,22 +60,22 @@ RZ_API char *rz_bin_pdb_calling_convention_as_string(TpiCallingConvention idx) { static TpiSimpleTypeMode get_simple_type_mode(ut32 type) { /* https://llvm.org/docs/PDB/TpiStream.html#type-indices - .---------------------------.------.----------. - | Unused | Mode | Kind | - '---------------------------'------'----------' - |+32 |+12 |+8 |+0 - */ + .---------------------------.------.----------. + | Unused | Mode | Kind | + '---------------------------'------'----------' + |+32 |+12 |+8 |+0 + */ // because mode is only number between 0-7, 1 byte is enough return (type & 0x00000000F0000); } static TpiSimpleTypeKind get_simple_type_kind(ut32 type) { /* https://llvm.org/docs/PDB/TpiStream.html#type-indices - .---------------------------.------.----------. - | Unused | Mode | Kind | - '---------------------------'------'----------' - |+32 |+12 |+8 |+0 - */ + .---------------------------.------.----------. + | Unused | Mode | Kind | + '---------------------------'------'----------' + |+32 |+12 |+8 |+0 + */ return (type & 0x00000000000FF); } @@ -277,7 +278,8 @@ RZ_IPI TpiType *parse_simple_type(TpiStream *stream, ut32 idx) { } simple_type->type = rz_strbuf_get(buf); // We just insert once - rz_rbtree_insert(&stream->types, &type->type_index, &type->rb, tpi_type_node_cmp, NULL); + rz_rbtree_insert(&stream->types, &type->type_index, &type->rb, + tpi_type_node_cmp, NULL); return type; } @@ -306,7 +308,7 @@ static ut64 get_numeric_val(Tpi_Type_Numeric *numeric) { } /** * \brief Return true if type is forward definition - * + * * \param t TpiType * \return bool */ @@ -346,24 +348,28 @@ RZ_API RzList *rz_bin_pdb_get_type_members(TpiStream *stream, TpiType *t) { return lf->substructs; } case LF_UNION: { - tmp = rz_bin_pdb_get_type_by_index(stream, ((Tpi_LF_Union *)t->type_data)->field_list); + tmp = rz_bin_pdb_get_type_by_index( + stream, ((Tpi_LF_Union *)t->type_data)->field_list); Tpi_LF_FieldList *lf_union = tmp ? tmp->type_data : NULL; return lf_union ? lf_union->substructs : NULL; } case LF_STRUCTURE: case LF_CLASS: { - tmp = rz_bin_pdb_get_type_by_index(stream, ((Tpi_LF_Structure *)t->type_data)->field_list); + tmp = rz_bin_pdb_get_type_by_index( + stream, ((Tpi_LF_Structure *)t->type_data)->field_list); Tpi_LF_FieldList *lf_struct = tmp ? tmp->type_data : NULL; return lf_struct ? lf_struct->substructs : NULL; } case LF_STRUCTURE_19: case LF_CLASS_19: { - tmp = rz_bin_pdb_get_type_by_index(stream, ((Tpi_LF_Structure_19 *)t->type_data)->field_list); + tmp = rz_bin_pdb_get_type_by_index( + stream, ((Tpi_LF_Structure_19 *)t->type_data)->field_list); Tpi_LF_FieldList *lf_struct19 = tmp ? tmp->type_data : NULL; return lf_struct19 ? lf_struct19->substructs : NULL; } case LF_ENUM: { - tmp = rz_bin_pdb_get_type_by_index(stream, ((Tpi_LF_Enum *)t->type_data)->field_list); + tmp = rz_bin_pdb_get_type_by_index( + stream, ((Tpi_LF_Enum *)t->type_data)->field_list); Tpi_LF_FieldList *lf_enum = tmp ? tmp->type_data : NULL; return lf_enum ? lf_enum->substructs : NULL; } @@ -611,7 +617,10 @@ static void free_tpi_stream(TpiStream *stream) { static void skip_padding(RzBuffer *buf, ut16 len, ut16 *read_len) { while (*read_len < len) { - ut8 byt = rz_buf_read8(buf); + ut8 byt; + if (!rz_buf_read8(buf, &byt)) { + break; + } if ((byt & 0xf0) == 0xf0) { *read_len += 1; } else { @@ -623,7 +632,10 @@ static void skip_padding(RzBuffer *buf, ut16 len, ut16 *read_len) { static bool has_non_padding(RzBuffer *buf, ut16 len, ut16 *read_len) { while (*read_len < len) { - ut8 byt = rz_buf_read8(buf); + ut8 byt; + if (!rz_buf_read8(buf, &byt)) { + break; + } rz_buf_seek(buf, rz_buf_tell(buf) - 1, RZ_BUF_SET); if ((byt & 0xf0) != 0xf0) { return true; @@ -633,62 +645,93 @@ static bool has_non_padding(RzBuffer *buf, ut16 len, ut16 *read_len) { return false; } -static void parse_type_numeric(RzBuffer *buf, Tpi_Type_Numeric *numeric, ut16 *read_len) { +static bool parse_type_numeric(RzBuffer *buf, Tpi_Type_Numeric *numeric, + ut16 *read_len) { numeric->data = 0; numeric->is_integer = true; - numeric->type_index = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &numeric->type_index)) { + return false; + } *read_len += sizeof(ut16); switch (numeric->type_index) { case LF_CHAR: numeric->data = RZ_NEW0(st8); - *(st8 *)numeric->data = rz_buf_read8(buf); + if (!rz_buf_read8(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(st8); break; case LF_SHORT: numeric->data = RZ_NEW0(st16); - *(st16 *)numeric->data = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(st16); break; case LF_USHORT: numeric->data = RZ_NEW0(ut16); - *(ut16 *)numeric->data = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(ut16); break; case LF_LONG: numeric->data = RZ_NEW0(st32); - *(st32 *)numeric->data = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(st32); break; case LF_ULONG: numeric->data = RZ_NEW0(ut32); - *(ut32 *)numeric->data = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(ut32); break; case LF_QUADWORD: numeric->data = RZ_NEW0(st64); - *(st64 *)numeric->data = rz_buf_read_le64(buf); + if (!rz_buf_read_le64(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(st64); break; case LF_UQUADWORD: numeric->data = RZ_NEW0(ut64); - *(ut64 *)numeric->data = rz_buf_read_le64(buf); + if (!rz_buf_read_le64(buf, numeric->data)) { + RZ_FREE(numeric->data); + return false; + } *read_len += sizeof(ut64); break; default: if (numeric->type_index >= 0x8000) { numeric->is_integer = false; - RZ_LOG_ERROR("%s: Skipping unsupported type (%d)\n", __FUNCTION__, numeric->type_index); - return; + RZ_LOG_ERROR("%s: Skipping unsupported type (%d)\n", __FUNCTION__, + numeric->type_index); + return false; } numeric->data = RZ_NEW0(ut16); *(ut16 *)(numeric->data) = numeric->type_index; + return true; } + return true; } -static void parse_type_string(RzBuffer *buf, Tpi_Type_String *str, ut16 len, ut16 *read_len) { +static void parse_type_string(RzBuffer *buf, Tpi_Type_String *str, ut16 len, + ut16 *read_len) { ut16 size = 0; while (*read_len < len) { - ut8 byt = rz_buf_read8(buf); + ut8 byt; + if (!rz_buf_read8(buf, &byt)) { + break; + } *(read_len) += 1; size++; if (!byt) { @@ -706,15 +749,22 @@ static void parse_type_string(RzBuffer *buf, Tpi_Type_String *str, ut16 len, ut1 } } -static Tpi_LF_Enumerate *parse_type_enumerate(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_Enumerate *parse_type_enumerate(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_Enumerate *enumerate = RZ_NEW0(Tpi_LF_Enumerate); if (!enumerate) { return NULL; } - enumerate->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &enumerate->fldattr.fldattr)) { + RZ_FREE(enumerate); + return NULL; + } *read_len += sizeof(ut16); - parse_type_numeric(buf, &enumerate->enum_value, read_len); + if (!parse_type_numeric(buf, &enumerate->enum_value, read_len)) { + RZ_FREE(enumerate); + return NULL; + } if (!enumerate->enum_value.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&enumerate->enum_value); @@ -726,60 +776,91 @@ static Tpi_LF_Enumerate *parse_type_enumerate(RzBuffer *buf, ut16 len, ut16 *rea return enumerate; } -static Tpi_LF_NestType *parse_type_nesttype(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_NestType *parse_type_nesttype(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_NestType *nest = RZ_NEW0(Tpi_LF_NestType); if (!nest) { return NULL; } - nest->pad = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &nest->pad)) { + RZ_FREE(nest); + return NULL; + } *read_len += sizeof(ut16); - nest->index = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &nest->index)) { + RZ_FREE(nest); + return NULL; + } *read_len += sizeof(ut32); parse_type_string(buf, &nest->name, len, read_len); skip_padding(buf, len, read_len); return nest; } -static Tpi_LF_VFuncTab *parse_type_vfunctab(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_VFuncTab *parse_type_vfunctab(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_VFuncTab *vftab = RZ_NEW0(Tpi_LF_VFuncTab); if (!vftab) { return NULL; } - vftab->pad = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &vftab->pad)) { + RZ_FREE(vftab); + return NULL; + } *read_len += sizeof(ut16); - vftab->index = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &vftab->index)) { + RZ_FREE(vftab); + return NULL; + } *read_len += sizeof(ut32); return vftab; } -static Tpi_LF_Method *parse_type_method(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_Method *parse_type_method(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_Method *method = RZ_NEW0(Tpi_LF_Method); if (!method) { return NULL; } - method->count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &method->count)) { + RZ_FREE(method); + return NULL; + } *read_len += sizeof(ut16); - method->mlist = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &method->mlist)) { + RZ_FREE(method); + return NULL; + } *read_len += sizeof(ut32); parse_type_string(buf, &method->name, len, read_len); skip_padding(buf, len, read_len); return method; } -static Tpi_LF_Member *parse_type_member(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_Member *parse_type_member(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_Member *member = RZ_NEW0(Tpi_LF_Member); if (!member) { return NULL; } - member->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &member->fldattr.fldattr)) { + RZ_FREE(member); + return NULL; + } *read_len += sizeof(ut16); - member->index = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &member->index)) { + RZ_FREE(member); + return NULL; + } *read_len += sizeof(ut32); - parse_type_numeric(buf, &member->offset, read_len); + if (!parse_type_numeric(buf, &member->offset, read_len)) { + RZ_FREE(member); + return NULL; + } if (!member->offset.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&member->offset); @@ -791,34 +872,51 @@ static Tpi_LF_Member *parse_type_member(RzBuffer *buf, ut16 len, ut16 *read_len) return member; } -static Tpi_LF_StaticMember *parse_type_staticmember(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_StaticMember *parse_type_staticmember(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_StaticMember *member = RZ_NEW0(Tpi_LF_StaticMember); if (!member) { return NULL; } - member->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &member->fldattr.fldattr)) { + RZ_FREE(member); + return NULL; + } *read_len += sizeof(ut16); - member->index = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &member->index)) { + RZ_FREE(member); + return NULL; + } *read_len += sizeof(ut32); parse_type_string(buf, &member->name, len, read_len); skip_padding(buf, len, read_len); return member; } -static Tpi_LF_OneMethod *parse_type_onemethod(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_OneMethod *parse_type_onemethod(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_OneMethod *onemethod = RZ_NEW0(Tpi_LF_OneMethod); if (!onemethod) { return NULL; } - onemethod->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &onemethod->fldattr.fldattr)) { + RZ_FREE(onemethod); + return NULL; + } *read_len += sizeof(ut16); - onemethod->index = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &onemethod->index)) { + RZ_FREE(onemethod); + return NULL; + } *read_len += sizeof(ut32); onemethod->offset_in_vtable = 0; - if (onemethod->fldattr.bits.mprop == MTintro || onemethod->fldattr.bits.mprop == MTpureintro) { - onemethod->offset_in_vtable = rz_buf_read_le32(buf); + if (onemethod->fldattr.bits.mprop == MTintro || + onemethod->fldattr.bits.mprop == MTpureintro) { + if (!rz_buf_read_le32(buf, &onemethod->offset_in_vtable)) { + RZ_FREE(onemethod); + } *read_len += sizeof(ut32); } parse_type_string(buf, &onemethod->name, len, read_len); @@ -826,17 +924,27 @@ static Tpi_LF_OneMethod *parse_type_onemethod(RzBuffer *buf, ut16 len, ut16 *rea return onemethod; } -static Tpi_LF_BClass *parse_type_bclass(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_BClass *parse_type_bclass(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_BClass *bclass = RZ_NEW0(Tpi_LF_BClass); if (!bclass) { return NULL; } - bclass->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &bclass->fldattr.fldattr)) { + RZ_FREE(bclass); + return NULL; + } *read_len += sizeof(ut16); - bclass->index = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &bclass->index)) { + RZ_FREE(bclass); + return NULL; + } *read_len += sizeof(ut32); - parse_type_numeric(buf, &bclass->offset, read_len); + if (!parse_type_numeric(buf, &bclass->offset, read_len)) { + RZ_FREE(bclass); + return NULL; + } if (!bclass->offset.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&bclass->offset); @@ -847,17 +955,27 @@ static Tpi_LF_BClass *parse_type_bclass(RzBuffer *buf, ut16 len, ut16 *read_len) return bclass; } -static Tpi_LF_VBClass *parse_type_vbclass(RzBuffer *buf, ut16 len, ut16 *read_len) { +static Tpi_LF_VBClass *parse_type_vbclass(RzBuffer *buf, ut16 len, + ut16 *read_len) { rz_return_val_if_fail(buf, NULL); Tpi_LF_VBClass *bclass = RZ_NEW0(Tpi_LF_VBClass); if (!bclass) { return NULL; } - bclass->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &bclass->fldattr.fldattr)) { + RZ_FREE(bclass); + return NULL; + } *read_len += sizeof(ut16); - bclass->direct_vbclass_idx = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &bclass->direct_vbclass_idx)) { + RZ_FREE(bclass); + return NULL; + } *read_len += sizeof(ut32); - bclass->vb_pointer_idx = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &bclass->vb_pointer_idx)) { + RZ_FREE(bclass); + return NULL; + } *read_len += sizeof(ut32); parse_type_numeric(buf, &bclass->vb_pointer_offset, read_len); if (!bclass->vb_pointer_offset.is_integer) { @@ -897,7 +1015,11 @@ static Tpi_LF_FieldList *parse_type_fieldlist(RzBuffer *buf, ut16 len) { } type->length = 0; type->type_index = 0; - type->leaf_type = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &type->leaf_type)) { + RZ_FREE(type); + rz_list_free(fieldlist); + return NULL; + } read_len += sizeof(ut16); switch (type->leaf_type) { case LF_ENUMERATE: @@ -929,7 +1051,8 @@ static Tpi_LF_FieldList *parse_type_fieldlist(RzBuffer *buf, ut16 len) { type->type_data = parse_type_staticmember(buf, len, &read_len); break; default: - RZ_LOG_ERROR("%s: Unsupported leaf type 0x%" PFMT32x "\n", __FUNCTION__, type->leaf_type); + RZ_LOG_ERROR("%s: Unsupported leaf type 0x%" PFMT32x "\n", __FUNCTION__, + type->leaf_type); RZ_FREE(type); rz_list_free(fieldlist->substructs); goto error; @@ -954,13 +1077,25 @@ static Tpi_LF_Enum *parse_type_enum(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); // include leaf_type - _enum->count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &_enum->count)) { + RZ_FREE(_enum); + return NULL; + } read_bytes += sizeof(ut16); - _enum->prop.cv_property = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &_enum->prop.cv_property)) { + RZ_FREE(_enum); + return NULL; + } read_bytes += sizeof(ut16); - _enum->utype = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &_enum->utype)) { + RZ_FREE(_enum); + return NULL; + } read_bytes += sizeof(ut32); - _enum->field_list = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &_enum->field_list)) { + RZ_FREE(_enum); + return NULL; + } read_bytes += sizeof(ut32); parse_type_string(buf, &_enum->name, len, &read_bytes); if (has_non_padding(buf, len, &read_bytes)) { @@ -977,17 +1112,35 @@ static Tpi_LF_Structure *parse_type_struct(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - structure->count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &structure->count)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut16); - structure->prop.cv_property = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &structure->prop.cv_property)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut16); - structure->field_list = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &structure->field_list)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut32); - structure->derived = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &structure->derived)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut32); - structure->vshape = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &structure->vshape)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut32); - parse_type_numeric(buf, &structure->size, &read_bytes); + if (!parse_type_numeric(buf, &structure->size, &read_bytes)) { + RZ_FREE(structure); + return NULL; + } if (!structure->size.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&structure->size); @@ -1009,19 +1162,40 @@ static Tpi_LF_Structure_19 *parse_type_struct_19(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - structure->prop.cv_property = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &structure->prop.cv_property)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut16); - structure->unknown = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &structure->unknown)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut16); - structure->field_list = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &structure->field_list)) { + RZ_FREE(structure); + return NULL; + } + read_bytes += sizeof(ut32); + if (!rz_buf_read_le32(buf, &structure->derived)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut32); - structure->derived = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &structure->vshape)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut32); - structure->vshape = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &structure->unknown1)) { + RZ_FREE(structure); + return NULL; + } read_bytes += sizeof(ut32); - structure->unknown1 = rz_buf_read_le16(buf); - read_bytes += sizeof(ut16); - parse_type_numeric(buf, &structure->size, &read_bytes); + if (!parse_type_numeric(buf, &structure->size, &read_bytes)) { + RZ_FREE(structure); + return NULL; + } if (!structure->size.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&structure->size); @@ -1043,9 +1217,15 @@ static Tpi_LF_Pointer *parse_type_pointer(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - pointer->utype = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &pointer->utype)) { + RZ_FREE(pointer); + return NULL; + } read_bytes += sizeof(ut32); - pointer->ptr_attr.ptr_attr = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &pointer->ptr_attr.ptr_attr)) { + RZ_FREE(pointer); + return NULL; + } read_bytes += sizeof(ut32); skip_padding(buf, len, &read_bytes); return pointer; @@ -1058,11 +1238,20 @@ static Tpi_LF_Array *parse_type_array(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - array->element_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &array->element_type)) { + RZ_FREE(array); + return NULL; + } read_bytes += sizeof(ut32); - array->index_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &array->index_type)) { + RZ_FREE(array); + return NULL; + } read_bytes += sizeof(ut32); - parse_type_numeric(buf, &array->size, &read_bytes); + if (!parse_type_numeric(buf, &array->size, &read_bytes)) { + RZ_FREE(array); + return NULL; + } if (!array->size.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&array->size); @@ -1081,9 +1270,15 @@ static Tpi_LF_Modifier *parse_type_modifier(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - modifier->modified_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &modifier->modified_type)) { + RZ_FREE(modifier); + return NULL; + } read_bytes += sizeof(ut32); - modifier->umodifier.modifier = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &modifier->umodifier.modifier)) { + RZ_FREE(modifier); + return NULL; + } read_bytes += sizeof(ut16); skip_padding(buf, len, &read_bytes); return modifier; @@ -1096,7 +1291,10 @@ static Tpi_LF_Arglist *parse_type_arglist(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - arglist->count = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &arglist->count)) { + RZ_FREE(arglist); + return NULL; + } read_bytes += sizeof(ut32); arglist->arg_type = (ut32 *)malloc(sizeof(ut32) * arglist->count); if (!arglist->arg_type) { @@ -1105,7 +1303,11 @@ static Tpi_LF_Arglist *parse_type_arglist(RzBuffer *buf, ut16 len) { return NULL; } for (size_t i = 0; i < arglist->count; i++) { - arglist->arg_type[i] = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &arglist->arg_type[i])) { + RZ_FREE(arglist->arg_type); + RZ_FREE(arglist); + return NULL; + } read_bytes += sizeof(ut32); } skip_padding(buf, len, &read_bytes); @@ -1120,21 +1322,45 @@ static Tpi_LF_MFcuntion *parse_type_mfunction(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - mfunc->return_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &mfunc->return_type)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut32); - mfunc->class_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &mfunc->class_type)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut32); - mfunc->this_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &mfunc->this_type)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut32); - mfunc->call_conv = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &mfunc->call_conv)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut8); - mfunc->func_attr.funcattr = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &mfunc->func_attr.funcattr)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut8); - mfunc->parm_count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &mfunc->parm_count)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut16); - mfunc->arglist = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &mfunc->arglist)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut32); - mfunc->this_adjust = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &mfunc->this_adjust)) { + RZ_FREE(mfunc); + return NULL; + } read_bytes += sizeof(ut32); skip_padding(buf, len, &read_bytes); return mfunc; @@ -1157,15 +1383,36 @@ static Tpi_LF_MethodList *parse_type_methodlist(RzBuffer *buf, ut16 len) { if (!member) { continue; } - member->fldattr.fldattr = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &member->fldattr.fldattr)) { + RZ_FREE(member); + rz_list_free(mlist->members); + RZ_FREE(mlist); + return NULL; + } read_bytes += sizeof(ut16); - member->pad = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &member->pad)) { + RZ_FREE(member); + rz_list_free(mlist->members); + RZ_FREE(mlist); + return NULL; + } read_bytes += sizeof(ut16); - member->type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &member->type)) { + RZ_FREE(member); + rz_list_free(mlist->members); + RZ_FREE(mlist); + return NULL; + } read_bytes += sizeof(ut32); member->optional_offset = 0; - if (member->fldattr.bits.mprop == MTintro || member->fldattr.bits.mprop == MTpureintro) { - member->optional_offset = rz_buf_read_le32(buf); + if (member->fldattr.bits.mprop == MTintro || + member->fldattr.bits.mprop == MTpureintro) { + if (!rz_buf_read_le32(buf, &member->optional_offset)) { + RZ_FREE(member); + rz_list_free(mlist->members); + RZ_FREE(mlist); + return NULL; + } read_bytes += sizeof(ut32); } rz_list_append(mlist->members, member); @@ -1185,15 +1432,30 @@ static Tpi_LF_Procedure *parse_type_procedure(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - proc->return_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &proc->return_type)) { + RZ_FREE(proc); + return NULL; + } read_bytes += sizeof(ut32); - proc->call_conv = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &proc->call_conv)) { + RZ_FREE(proc); + return NULL; + } read_bytes += sizeof(ut8); - proc->func_attr.funcattr = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &proc->func_attr.funcattr)) { + RZ_FREE(proc); + return NULL; + } read_bytes += sizeof(ut8); - proc->parm_count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &proc->parm_count)) { + RZ_FREE(proc); + return NULL; + } read_bytes += sizeof(ut16); - proc->arg_list = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &proc->arg_list)) { + RZ_FREE(proc); + return NULL; + } read_bytes += sizeof(ut32); skip_padding(buf, len, &read_bytes); return proc; @@ -1206,13 +1468,24 @@ static Tpi_LF_Union *parse_type_union(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - unin->count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &unin->count)) { + RZ_FREE(unin); + return NULL; + } read_bytes += sizeof(ut16); - unin->prop.cv_property = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &unin->prop.cv_property)) { + RZ_FREE(unin); + return NULL; + } read_bytes += sizeof(ut16); - unin->field_list = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &unin->field_list)) { + RZ_FREE(unin); + return NULL; + } read_bytes += sizeof(ut32); - parse_type_numeric(buf, &unin->size, &read_bytes); + if (!parse_type_numeric(buf, &unin->size, &read_bytes)) { + RZ_FREE(unin); + } if (!unin->size.is_integer) { RZ_LOG_ERROR("Integer expected!\n"); free_snumeric(&unin->size); @@ -1235,11 +1508,20 @@ static Tpi_LF_Bitfield *parse_type_bitfield(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - bf->base_type = rz_buf_read_le32(buf); + if (!rz_buf_read_le32(buf, &bf->base_type)) { + RZ_FREE(bf); + return NULL; + } read_bytes += sizeof(ut32); - bf->length = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &bf->length)) { + RZ_FREE(bf); + return NULL; + } read_bytes += sizeof(ut8); - bf->position = rz_buf_read8(buf); + if (!rz_buf_read8(buf, &bf->position)) { + RZ_FREE(bf); + return NULL; + } read_bytes += sizeof(ut8); skip_padding(buf, len, &read_bytes); return bf; @@ -1252,7 +1534,10 @@ static Tpi_LF_Vtshape *parse_type_vtshape(RzBuffer *buf, ut16 len) { return NULL; } ut16 read_bytes = sizeof(ut16); - vt->count = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &vt->count)) { + RZ_FREE(vt); + return NULL; + } read_bytes += sizeof(ut16); ut16 size = (4 * vt->count + (vt->count % 2) * 4) / 8; vt->vt_descriptors = (char *)malloc(size); @@ -1271,8 +1556,12 @@ static bool parse_tpi_types(RzBuffer *buf, TpiType *type) { if (!buf || !type) { return false; } - type->length = rz_buf_read_le16(buf); - type->leaf_type = rz_buf_read_le16(buf); + if (!rz_buf_read_le16(buf, &type->length)) { + return false; + } + if (!rz_buf_read_le16(buf, &type->leaf_type)) { + return false; + } switch (type->leaf_type) { case LF_FIELDLIST: type->type_data = parse_type_fieldlist(buf, type->length); @@ -1319,32 +1608,33 @@ static bool parse_tpi_types(RzBuffer *buf, TpiType *type) { type->type_data = parse_type_vtshape(buf, type->length); break; default: - RZ_LOG_ERROR("%s: unsupported leaf type: 0x%" PFMT32x "\n", __FUNCTION__, type->leaf_type); + RZ_LOG_ERROR("%s: unsupported leaf type: 0x%" PFMT32x "\n", __FUNCTION__, + type->leaf_type); return false; } return true; } -static void parse_tpi_stream_header(TpiStream *s, RzBuffer *buf) { - s->header.Version = rz_buf_read_le32(buf); - s->header.HeaderSize = rz_buf_read_le32(buf); - s->header.TypeIndexBegin = rz_buf_read_le32(buf); - s->header.TypeIndexEnd = rz_buf_read_le32(buf); - s->header.TypeRecordBytes = rz_buf_read_le32(buf); +static bool parse_tpi_stream_header(TpiStream *s, RzBuffer *buf) { + return rz_buf_read_le32(buf, &s->header.Version) && + rz_buf_read_le32(buf, &s->header.HeaderSize) && + rz_buf_read_le32(buf, &s->header.TypeIndexBegin) && + rz_buf_read_le32(buf, &s->header.TypeIndexEnd) && + rz_buf_read_le32(buf, &s->header.TypeRecordBytes) && - s->header.HashStreamIndex = rz_buf_read_le16(buf); - s->header.HashAuxStreamIndex = rz_buf_read_le16(buf); - s->header.HashKeySize = rz_buf_read_le32(buf); - s->header.NumHashBuckets = rz_buf_read_le32(buf); + rz_buf_read_le16(buf, &s->header.HashStreamIndex) && + rz_buf_read_le16(buf, &s->header.HashAuxStreamIndex) && + rz_buf_read_le32(buf, &s->header.HashKeySize) && + rz_buf_read_le32(buf, &s->header.NumHashBuckets) && - s->header.HashValueBufferOffset = rz_buf_read_le32(buf); - s->header.HashValueBufferLength = rz_buf_read_le32(buf); + rz_buf_read_le32(buf, &s->header.HashValueBufferOffset) && + rz_buf_read_le32(buf, &s->header.HashValueBufferLength) && - s->header.IndexOffsetBufferOffset = rz_buf_read_le32(buf); - s->header.IndexOffsetBufferLength = rz_buf_read_le32(buf); + rz_buf_read_le32(buf, &s->header.IndexOffsetBufferOffset) && + rz_buf_read_le32(buf, &s->header.IndexOffsetBufferLength) && - s->header.HashAdjBufferOffset = rz_buf_read_le32(buf); - s->header.HashAdjBufferLength = rz_buf_read_le32(buf); + rz_buf_read_le32(buf, &s->header.HashAdjBufferOffset) && + rz_buf_read_le32(buf, &s->header.HashAdjBufferLength); } RZ_IPI bool parse_tpi_stream(RzPdb *pdb, MsfStream *stream) { @@ -1359,7 +1649,9 @@ RZ_IPI bool parse_tpi_stream(RzPdb *pdb, MsfStream *stream) { TpiStream *s = pdb->s_tpi; s->types = NULL; RzBuffer *buf = stream->stream_data; - parse_tpi_stream_header(s, buf); + if (!parse_tpi_stream_header(s, buf)) { + return false; + } if (s->header.HeaderSize != sizeof(TpiStreamHeader)) { RZ_LOG_ERROR("Corrupted TPI stream.\n"); return false; @@ -1376,7 +1668,8 @@ RZ_IPI bool parse_tpi_stream(RzPdb *pdb, MsfStream *stream) { RZ_FREE(type); continue; } - rz_rbtree_insert(&s->types, &type->type_index, &type->rb, tpi_type_node_cmp, NULL); + rz_rbtree_insert(&s->types, &type->type_index, &type->rb, tpi_type_node_cmp, + NULL); } return true; }