diff --git a/librz/bin/format/mdmp/mdmp.c b/librz/bin/format/mdmp/mdmp.c index 42bafe52d8..064c14b878 100644 --- a/librz/bin/format/mdmp/mdmp.c +++ b/librz/bin/format/mdmp/mdmp.c @@ -8,10 +8,10 @@ // XXX: this is a random number, no idea how long it should be. #define COMMENTS_SIZE 32 -ut64 rz_bin_mdmp_get_paddr(struct rz_bin_mdmp_obj *obj, ut64 vaddr) { +ut64 rz_bin_mdmp_get_paddr(MiniDmpObj *obj, ut64 vaddr) { /* FIXME: Will only resolve exact matches, probably no need to fix as ** this function will become redundant on the optimisation stage */ - struct minidump_memory_descriptor64 *memory; + MiniDmpMemDescr64 *memory; ut64 index, paddr = 0; RzListIter *it; @@ -27,8 +27,8 @@ ut64 rz_bin_mdmp_get_paddr(struct rz_bin_mdmp_obj *obj, ut64 vaddr) { return paddr; } -struct minidump_memory_info *rz_bin_mdmp_get_mem_info(struct rz_bin_mdmp_obj *obj, ut64 vaddr) { - struct minidump_memory_info *mem_info; +MiniDmpMemInfo *rz_bin_mdmp_get_mem_info(MiniDmpObj *obj, ut64 vaddr) { + MiniDmpMemInfo *mem_info; RzListIter *it; if (!obj) { @@ -44,8 +44,8 @@ struct minidump_memory_info *rz_bin_mdmp_get_mem_info(struct rz_bin_mdmp_obj *ob return NULL; } -ut32 rz_bin_mdmp_get_perm(struct rz_bin_mdmp_obj *obj, ut64 vaddr) { - struct minidump_memory_info *mem_info; +ut32 rz_bin_mdmp_get_perm(MiniDmpObj *obj, ut64 vaddr) { + MiniDmpMemInfo *mem_info; if (!(mem_info = rz_bin_mdmp_get_mem_info(obj, vaddr))) { /* if there is no mem info in the dump, assume default permission */ @@ -98,7 +98,7 @@ static void rz_bin_mdmp_free_pe64_bin(struct Pe64_rz_bin_mdmp_pe_bin *pe_bin) { free(pe_bin); } -void rz_bin_mdmp_free(struct rz_bin_mdmp_obj *obj) { +void rz_bin_mdmp_free(MiniDmpObj *obj) { if (!obj) { return; } @@ -132,7 +132,7 @@ void rz_bin_mdmp_free(struct rz_bin_mdmp_obj *obj) { return; } -static void rz_bin_mdmp_init_parsing(struct rz_bin_mdmp_obj *obj) { +static void mdmp_obj_sdb_init(MiniDmpObj *obj) { /* TODO: Handle unions, can we? */ /* FIXME: Why are we getting struct missing errors when it finds them */ sdb_set(obj->kv, "mdmp_mem_state.cparse", @@ -349,80 +349,29 @@ static void rz_bin_mdmp_init_parsing(struct rz_bin_mdmp_obj *obj) { sdb_set(obj->kv, "mdmp_string.format", "dZ Length Buffer", 0); } -static bool read_hdr(RzBuffer *b, struct minidump_header *hdr) { - st64 tmp = rz_buf_tell(b); - if (tmp < 0) { - return false; - } - - if (rz_buf_seek(b, 0, RZ_BUF_SET) < 0) { - return false; - } - - bool result = true; - - ut32 signature = 0; - if (!rz_buf_read_le32(b, &signature)) { - result = false; - } - hdr->signature = signature; - - ut32 version = 0; - if (!rz_buf_read_le32(b, &version)) { - result = false; - } - hdr->version = version; - - ut32 number_of_streams = 0; - if (!rz_buf_read_le32(b, &number_of_streams)) { - result = false; - } - hdr->number_of_streams = number_of_streams; - - ut32 stream_directory_rva = 0; - if (!rz_buf_read_le32(b, &stream_directory_rva)) { - result = false; - } - hdr->stream_directory_rva = stream_directory_rva; - - ut32 check_sum = 0; - if (!rz_buf_read_le32(b, &check_sum)) { - result = false; - } - hdr->check_sum = check_sum; - - ut32 reserved = 0; - if (!rz_buf_read_le32(b, &reserved)) { - result = false; - } - hdr->reserved = reserved; - - ut64 flags = 0; - if (!rz_buf_read_le64(b, &flags)) { - result = false; - } - hdr->flags = flags; - - if (rz_buf_seek(b, tmp, RZ_BUF_SET) < 0) { - return false; - } - - return result; +static bool mdmp_read_header(RzBuffer *b, MiniDmpHeader *hdr) { + ut64 offset = 0; + return rz_buf_read_le32_offset(b, &offset, &hdr->signature) && + rz_buf_read_le32_offset(b, &offset, &hdr->version) && + rz_buf_read_le32_offset(b, &offset, &hdr->number_of_streams) && + rz_buf_read_le32_offset(b, &offset, &hdr->stream_directory_rva) && + rz_buf_read_le32_offset(b, &offset, &hdr->check_sum) && + rz_buf_read_le32_offset(b, &offset, &hdr->reserved) && + rz_buf_read_le64_offset(b, &offset, &hdr->flags); } -static bool rz_bin_mdmp_init_hdr(struct rz_bin_mdmp_obj *obj) { - obj->hdr = RZ_NEW(struct minidump_header); - if (!obj->hdr) { +static bool rz_bin_mdmp_init_hdr(MiniDmpObj *obj) { + obj->hdr = RZ_NEW(MiniDmpHeader); + if (!obj->hdr || !mdmp_read_header(obj->b, obj->hdr)) { return false; } - read_hdr(obj->b, obj->hdr); if (obj->hdr->number_of_streams == 0) { RZ_LOG_WARN("No streams present!\n"); return false; } - if (obj->hdr->stream_directory_rva < sizeof(struct minidump_header)) { + if (obj->hdr->stream_directory_rva < sizeof(MiniDmpHeader)) { RZ_LOG_ERROR("RVA for directory resides in the header!\n"); return false; } @@ -443,242 +392,252 @@ static bool rz_bin_mdmp_init_hdr(struct rz_bin_mdmp_obj *obj) { return true; } -static bool read_module_aux(RzBuffer *b, ut64 addr, struct minidump_module *module) { - ut64 base_of_image; - if (!rz_buf_read_le64(b, &base_of_image)) { +#define mdmp_read_module_list(b, addr, list) rz_buf_read_le32_at(b, addr, list.number_of_modules) +#define mdmp_read_thread_list(b, addr, list) rz_buf_read_le32_at(b, addr, list.number_of_threads) +#define mdmp_read_memory_list32(b, addr, list) rz_buf_read_le32_at(b, addr, list.number_of_memory_ranges) + +static bool mdmp_read_memory_list64(RzBuffer *b, ut64 addr, MiniDmpMemList64 *list) { + ut64 offset = addr; + return rz_buf_read_le64_offset(b, &offset, &list->number_of_memory_ranges) && + rz_buf_read_le64_offset(b, &offset, &list->base_rva); +} + +static bool mdmp_read_location_descriptor32(RzBuffer *b, ut64 *offset, MiniDmpLocDescr32 *desc) { + return rz_buf_read_le32_offset(b, offset, &desc->data_size) && + rz_buf_read_le32_offset(b, offset, &desc->rva); +} + +static bool mdmp_read_memory_descriptor32(RzBuffer *b, ut64 *offset, MiniDmpMemDescr32 *desc) { + return rz_buf_read_le64_offset(b, offset, &desc->start_of_memory_range) && + mdmp_read_location_descriptor32(b, offset, &desc->memory); +} + +static bool mdmp_read_memory_descriptor64(RzBuffer *b, ut64 *offset, MiniDmpMemDescr64 *desc) { + return rz_buf_read_le64_offset(b, offset, &desc->start_of_memory_range) && + rz_buf_read_le64_offset(b, offset, &desc->data_size); +} + +static bool mdmp_read_thread_ex(RzBuffer *b, ut64 *offset, MiniDmpThreadEx *th) { + return rz_buf_read_le32_offset(b, offset, &th->thread_id) && + rz_buf_read_le32_offset(b, offset, &th->suspend_count) && + rz_buf_read_le32_offset(b, offset, &th->priority_class) && + rz_buf_read_le32_offset(b, offset, &th->priority) && + rz_buf_read_le64_offset(b, offset, &th->teb) && + mdmp_read_memory_descriptor32(b, offset, &th->stack) && + mdmp_read_location_descriptor32(b, offset, &th->thread_context) && + mdmp_read_memory_descriptor32(b, offset, &th->backing_store); +} + +static bool mdmp_read_vs_fixedfileinfo(RzBuffer *b, ut64 *offset, VSFixedFileInfo *info) { + return rz_buf_read_le32_offset(b, offset, &info->dw_signature) && + rz_buf_read_le32_offset(b, offset, &info->dw_struc_version) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_version_ms) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_version_ls) && + rz_buf_read_le32_offset(b, offset, &info->dw_product_version_ms) && + rz_buf_read_le32_offset(b, offset, &info->dw_product_version_ls) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_flags_mask) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_flags) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_os) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_type) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_subtype) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_date_ms) && + rz_buf_read_le32_offset(b, offset, &info->dw_file_date_ls); +} + +static bool mdmp_read_module(RzBuffer *b, ut64 *offset, MiniDmpModule *module) { + return rz_buf_read_le64_offset(b, offset, &module->base_of_image) && + rz_buf_read_le32_offset(b, offset, &module->size_of_image) && + rz_buf_read_le32_offset(b, offset, &module->check_sum) && + rz_buf_read_le32_offset(b, offset, &module->time_date_stamp) && + rz_buf_read_le32_offset(b, offset, &module->module_name_rva) && + mdmp_read_vs_fixedfileinfo(b, offset, &module->version_info) && + mdmp_read_location_descriptor32(b, offset, &module->cv_record) && + mdmp_read_location_descriptor32(b, offset, &module->misc_record) && + rz_buf_read_le64_offset(b, offset, &module->reserved_0) && + rz_buf_read_le64_offset(b, offset, &module->reserved_1); +} + +static bool mdmp_read_exception(RzBuffer *b, ut64 *offset, MiniDmpException *exc) { + return rz_buf_read_le32_offset(b, offset, &exc->exception_code) && + rz_buf_read_le32_offset(b, offset, &exc->exception_flags) && + rz_buf_read_le64_offset(b, offset, &exc->exception_record) && + rz_buf_read_le64_offset(b, offset, &exc->exception_address) && + rz_buf_read_le32_offset(b, offset, &exc->number_parameters) && + rz_buf_read_le32_offset(b, offset, &exc->__unused_alignment) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[0]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[1]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[2]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[3]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[4]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[5]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[6]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[7]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[8]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[9]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[10]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[11]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[12]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[13]) && + rz_buf_read_le64_offset(b, offset, &exc->exception_information[14]); +} + +static bool mdmp_read_exception_stream(RzBuffer *b, ut64 *offset, MiniDmpExcStream *stream) { + return rz_buf_read_le32_offset(b, offset, &stream->thread_id) && + rz_buf_read_le32_offset(b, offset, &stream->__alignment) && + mdmp_read_exception(b, offset, &stream->exception_record) && + mdmp_read_location_descriptor32(b, offset, &stream->thread_context); +} + +static bool mdmp_read_function_table_stream(RzBuffer *b, ut64 addr, MiniDmpFuncTableStream *stream) { + ut64 offset = addr; + return rz_buf_read_le32_offset(b, &offset, &stream->size_of_header) && + rz_buf_read_le32_offset(b, &offset, &stream->size_of_descriptor) && + rz_buf_read_le32_offset(b, &offset, &stream->size_of_native_descriptor) && + rz_buf_read_le32_offset(b, &offset, &stream->size_of_function_entry) && + rz_buf_read_le32_offset(b, &offset, &stream->number_of_descriptors) && + rz_buf_read_le32_offset(b, &offset, &stream->size_of_align_pad); +} + +static bool mdmp_read_handle_data_stream(RzBuffer *b, ut64 addr, MiniDmpHandleDataStream *stream) { + ut64 offset = addr; + return rz_buf_read_le32_offset(b, &offset, &stream->size_of_header) && + rz_buf_read_le32_offset(b, &offset, &stream->size_of_descriptor) && + rz_buf_read_le32_offset(b, &offset, &stream->number_of_descriptors) && + rz_buf_read_le32_offset(b, &offset, &stream->reserved); +} + +static bool mdmp_read_memory_info_list(RzBuffer *b, ut64 *offset, MiniDmpMemInfoList *list) { + return rz_buf_read_le32_offset(b, offset, &list->size_of_header) && + rz_buf_read_le32_offset(b, offset, &list->size_of_entry) && + rz_buf_read_le64_offset(b, offset, &list->number_of_entries); +} + +static bool mdmp_read_memory_info(RzBuffer *b, ut64 *offset, MiniDmpMemInfo *info) { + return rz_buf_read_le64_offset(b, offset, &info->base_address) && + rz_buf_read_le64_offset(b, offset, &info->allocation_base) && + rz_buf_read_le32_offset(b, offset, &info->allocation_protect) && + rz_buf_read_le32_offset(b, offset, &info->__alignment_1) && + rz_buf_read_le64_offset(b, offset, &info->region_size) && + rz_buf_read_le32_offset(b, offset, &info->state) && + rz_buf_read_le32_offset(b, offset, &info->protect) && + rz_buf_read_le32_offset(b, offset, &info->type) && + rz_buf_read_le32_offset(b, offset, &info->__alignment_2); +} + +static bool mdmp_read_misc_info(RzBuffer *b, ut64 addr, MiniDmpMiscInfo *info) { + ut64 offset = addr; + return rz_buf_read_le32_offset(b, &offset, &info->size_of_info) && + rz_buf_read_le32_offset(b, &offset, &info->flags_1) && + rz_buf_read_le32_offset(b, &offset, &info->process_id) && + rz_buf_read_le32_offset(b, &offset, &info->process_create_time) && + rz_buf_read_le32_offset(b, &offset, &info->process_user_time) && + rz_buf_read_le32_offset(b, &offset, &info->process_kernel_time); +} + +static bool mdmp_read_system_info(RzBuffer *b, ut64 addr, MiniDmpSysInfo *info) { + ut64 offset = addr; + + return rz_buf_read_le16_offset(b, &offset, &info->processor_architecture) && + rz_buf_read_le16_offset(b, &offset, &info->processor_level) && + rz_buf_read_le16_offset(b, &offset, &info->processor_revision) && + rz_buf_read8_offset(b, &offset, &info->number_of_processors) && + rz_buf_read8_offset(b, &offset, &info->product_type) && + rz_buf_read_le32_offset(b, &offset, &info->major_version) && + rz_buf_read_le32_offset(b, &offset, &info->minor_version) && + rz_buf_read_le32_offset(b, &offset, &info->build_number) && + rz_buf_read_le32_offset(b, &offset, &info->platform_id) && + rz_buf_read_le32_offset(b, &offset, &info->csd_version_rva) && + rz_buf_read_le32_offset(b, &offset, &info->reserved_1) && + rz_buf_read_le64_offset(b, &offset, &info->cpu.other_cpu_info.processor_features[0]) && + rz_buf_read_le64_offset(b, &offset, &info->cpu.other_cpu_info.processor_features[1]); +} + +static bool mdmp_read_thread_info(RzBuffer *b, ut64 *offset, MiniDmpThreadInfo *info) { + return rz_buf_read_le32_offset(b, offset, &info->thread_id) && + rz_buf_read_le32_offset(b, offset, &info->dump_flags) && + rz_buf_read_le32_offset(b, offset, &info->dump_error) && + rz_buf_read_le32_offset(b, offset, &info->exit_status) && + rz_buf_read_le64_offset(b, offset, &info->create_time) && + rz_buf_read_le64_offset(b, offset, &info->exit_time) && + rz_buf_read_le64_offset(b, offset, &info->kernel_time) && + rz_buf_read_le64_offset(b, offset, &info->user_time) && + rz_buf_read_le64_offset(b, offset, &info->start_address) && + rz_buf_read_le64_offset(b, offset, &info->affinity); +} + +static bool mdmp_read_thread_info_list(RzBuffer *b, ut64 *offset, MiniDmpThreadInfoList *list) { + return rz_buf_read_le32_offset(b, offset, &list->size_of_header) && + rz_buf_read_le32_offset(b, offset, &list->size_of_entry) && + rz_buf_read_le32_offset(b, offset, &list->number_of_entries); +} + +static bool mdmp_read_token_info(RzBuffer *b, ut64 *offset, MiniDmpTokenInfo *info) { + return rz_buf_read_le32_offset(b, offset, &info->token_size) && + rz_buf_read_le32_offset(b, offset, &info->token_id) && + rz_buf_read_le64_offset(b, offset, &info->token_handle); +} + +static bool mdmp_read_token_info_list(RzBuffer *b, ut64 *offset, MiniDmpTokenInfoList *list) { + return rz_buf_read_le32_offset(b, offset, &list->size_of_list) && + rz_buf_read_le32_offset(b, offset, &list->number_of_entries) && + rz_buf_read_le32_offset(b, offset, &list->list_header_size) && + rz_buf_read_le32_offset(b, offset, &list->element_header_size); +} + +static bool mdmp_read_unloaded_module(RzBuffer *b, ut64 *offset, MiniDmpUnloadedModule *module) { + return rz_buf_read_le64_offset(b, offset, &module->base_of_image) && + rz_buf_read_le32_offset(b, offset, &module->size_of_image) && + rz_buf_read_le32_offset(b, offset, &module->check_sum) && + rz_buf_read_le32_offset(b, offset, &module->time_date_stamp) && + rz_buf_read_le32_offset(b, offset, &module->module_name_rva); +} + +static bool mdmp_read_unloaded_module_list(RzBuffer *b, ut64 *offset, MiniDmpUnloadedModuleList *list) { + return rz_buf_read_le32_offset(b, offset, &list->size_of_header) && + rz_buf_read_le32_offset(b, offset, &list->size_of_entry) && + rz_buf_read_le32_offset(b, offset, &list->number_of_entries); +} + +static bool mdmp_read_avrf_backtrace_information(RzBuffer *b, ut64 *offset, AVRFBacktraceInfo *info) { + if (!rz_buf_read_le32_offset(b, offset, &info->depth) || + !rz_buf_read_le32_offset(b, offset, &info->index)) { return false; } - module->base_of_image = base_of_image; - - ut32 size_of_image; - if (!rz_buf_read_le32(b, &size_of_image)) { - return false; + for (size_t i = 0; i < AVRF_MAX_TRACES; ++i) { + if (!rz_buf_read_le64_offset(b, offset, &info->return_addresses[i])) { + return false; + } } - module->size_of_image = size_of_image; - - ut32 check_sum; - if (!rz_buf_read_le32(b, &check_sum)) { - return false; - } - module->check_sum = check_sum; - - ut32 time_date_stamp; - if (!rz_buf_read_le32(b, &time_date_stamp)) { - return false; - } - module->time_date_stamp = time_date_stamp; - - ut32 module_name_rva; - if (!rz_buf_read_le32(b, &module_name_rva)) { - return false; - } - module->module_name_rva = module_name_rva; - - ut32 dw_signature; - if (!rz_buf_read_le32(b, &dw_signature)) { - return false; - } - module->version_info.dw_signature = dw_signature; - - ut32 dw_struc_version; - if (!rz_buf_read_le32(b, &dw_struc_version)) { - return false; - } - module->version_info.dw_struc_version = dw_struc_version; - - ut32 dw_file_version_ms; - if (!rz_buf_read_le32(b, &dw_file_version_ms)) { - return false; - } - module->version_info.dw_file_version_ms = dw_file_version_ms; - - ut32 dw_file_version_ls; - if (!rz_buf_read_le32(b, &dw_file_version_ls)) { - return false; - } - module->version_info.dw_file_version_ls = dw_file_version_ls; - - ut32 dw_product_version_ms; - if (!rz_buf_read_le32(b, &dw_product_version_ms)) { - return false; - } - module->version_info.dw_product_version_ms = dw_product_version_ms; - - ut32 dw_product_version_ls; - if (!rz_buf_read_le32(b, &dw_product_version_ls)) { - return false; - } - module->version_info.dw_product_version_ls = dw_product_version_ls; - - ut32 dw_file_flags_mask; - if (!rz_buf_read_le32(b, &dw_file_flags_mask)) { - return false; - } - module->version_info.dw_file_flags_mask = dw_file_flags_mask; - - ut32 dw_file_flags; - if (!rz_buf_read_le32(b, &dw_file_flags)) { - return false; - } - module->version_info.dw_file_flags = dw_file_flags; - - ut32 dw_file_os; - if (!rz_buf_read_le32(b, &dw_file_os)) { - return false; - } - module->version_info.dw_file_os = dw_file_os; - - ut32 dw_file_type; - if (!rz_buf_read_le32(b, &dw_file_type)) { - return false; - } - module->version_info.dw_file_type = dw_file_type; - - ut32 dw_file_subtype; - if (!rz_buf_read_le32(b, &dw_file_subtype)) { - return false; - } - module->version_info.dw_file_subtype = dw_file_subtype; - - ut32 dw_file_date_ms; - if (!rz_buf_read_le32(b, &dw_file_date_ms)) { - return false; - } - module->version_info.dw_file_date_ms = dw_file_date_ms; - - ut32 dw_file_date_ls; - if (!rz_buf_read_le32(b, &dw_file_date_ls)) { - return false; - } - module->version_info.dw_file_date_ls = dw_file_date_ls; - - ut32 cv_record_data_size; - if (!rz_buf_read_le32(b, &cv_record_data_size)) { - return false; - } - module->cv_record.data_size = cv_record_data_size; - - ut32 cv_record_rva; - if (!rz_buf_read_le32(b, &cv_record_rva)) { - return false; - } - module->cv_record.rva = cv_record_rva; - - ut32 misc_record_data_size; - if (!rz_buf_read_le32(b, &misc_record_data_size)) { - return false; - } - module->misc_record.data_size = misc_record_data_size; - - ut32 misc_record_rva; - if (!rz_buf_read_le32(b, &misc_record_rva)) { - return false; - } - module->misc_record.rva = misc_record_rva; - - ut64 reserved_0; - if (!rz_buf_read_le64(b, &reserved_0)) { - return false; - } - module->reserved_0 = reserved_0; - - ut64 reserved_1; - if (!rz_buf_read_le64(b, &reserved_1)) { - return false; - } - module->reserved_1 = reserved_1; - return true; } -static bool read_module(RzBuffer *b, ut64 addr, struct minidump_module *module) { - st64 tmp = rz_buf_tell(b); - if (tmp < 0) { - return false; - } - - if (rz_buf_seek(b, addr, RZ_BUF_SET) < 0) { - return false; - } - - bool result = read_module_aux(b, addr, module); - - if (rz_buf_seek(b, tmp, RZ_BUF_SET) < 0) { - return false; - } - - return result; +static bool mdmp_read_avrf_handle_operation(RzBuffer *b, ut64 *offset, AVRFHandleOp *op) { + return rz_buf_read_le64_offset(b, offset, &op->handle) && + rz_buf_read_le32_offset(b, offset, &op->process_id) && + rz_buf_read_le32_offset(b, offset, &op->thread_id) && + rz_buf_read_le32_offset(b, offset, &op->operation_type) && + rz_buf_read_le32_offset(b, offset, &op->spare_0) && + mdmp_read_avrf_backtrace_information(b, offset, &op->back_trace_information); } -static bool read_memory64_list(RzBuffer *b, ut64 addr, struct minidump_memory64_list *memory64_list) { - st64 tmp = rz_buf_tell(b); - if (tmp < 0) { - return false; - } - - if (rz_buf_seek(b, addr, RZ_BUF_SET) < 0) { - return false; - } - - ut64 number_of_memory_ranges; - if (!rz_buf_read_le64(b, &number_of_memory_ranges)) { - return false; - } - memory64_list->number_of_memory_ranges = number_of_memory_ranges; - - ut64 base_rva; - if (!rz_buf_read_le64(b, &base_rva)) { - return false; - } - memory64_list->base_rva = base_rva; - - if (rz_buf_seek(b, tmp, RZ_BUF_SET) < 0) { - return false; - } - - return true; +static bool mdmp_read_handle_operation_list(RzBuffer *b, ut64 *offset, MiniDmpHandleOpList *list) { + return rz_buf_read_le32_offset(b, offset, &list->size_of_header) && + rz_buf_read_le32_offset(b, offset, &list->size_of_entry) && + rz_buf_read_le32_offset(b, offset, &list->number_of_entries) && + rz_buf_read_le32_offset(b, offset, &list->reserved); } -static bool read_desc(RzBuffer *b, ut64 addr, struct minidump_memory_descriptor64 *desc) { - st64 tmp = rz_buf_tell(b); - if (tmp < 0) { - return false; - } - - if (rz_buf_seek(b, addr, RZ_BUF_SET) < 0) { - return false; - } - - ut64 start_of_memory_range; - if (!rz_buf_read_le64(b, &start_of_memory_range)) { - return false; - } - desc->start_of_memory_range = start_of_memory_range; - - ut64 data_size; - if (!rz_buf_read_le64(b, &data_size)) { - return false; - } - desc->data_size = data_size; - - if (rz_buf_seek(b, tmp, RZ_BUF_SET) < 0) { - return false; - } - - return true; -} - -static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct minidump_directory *entry) { - struct minidump_handle_operation_list handle_operation_list; - struct minidump_memory_list memory_list; - struct minidump_memory64_list memory64_list; - struct minidump_memory_info_list memory_info_list; - struct minidump_module_list module_list; - struct minidump_thread_list thread_list; - struct minidump_thread_ex_list thread_ex_list; - struct minidump_thread_info_list thread_info_list; - struct minidump_token_info_list token_info_list; - struct minidump_unloaded_module_list unloaded_module_list; +static bool mdmp_init_directory_entry(MiniDmpObj *obj, MiniDmpDir *entry) { + MiniDmpHandleOpList handle_operation_list = { 0 }; + MiniDmpMemList32 memory_list = { 0 }; + MiniDmpMemList64 memory64_list = { 0 }; + MiniDmpMemInfoList memory_info_list = { 0 }; + MiniDmpModuleList module_list = { 0 }; + MiniDmpThreadList thread_list = { 0 }; + MiniDmpThreadExList thread_ex_list = { 0 }; + MiniDmpThreadInfoList thread_info_list = { 0 }; + MiniDmpTokenInfoList token_info_list = { 0 }; + MiniDmpUnloadedModuleList unloaded_module_list = { 0 }; ut64 offset; int i, r; @@ -689,12 +648,9 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct return false; } - ut32 number_of_modules; - switch (entry->stream_type) { case THREAD_LIST_STREAM: - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&thread_list, sizeof(thread_list)); - if (r != sizeof(thread_list)) { + if (!mdmp_read_thread_list(obj->b, entry->location.rva, &thread_list)) { break; } @@ -714,10 +670,9 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct /* TODO: Not yet fully parsed or utilised */ break; case MODULE_LIST_STREAM: - if (!rz_buf_read_le32_at(obj->b, entry->location.rva, &number_of_modules)) { + if (!mdmp_read_module_list(obj->b, entry->location.rva, &module_list)) { break; } - module_list.number_of_modules = number_of_modules; sdb_set(obj->kv, "mdmp_module.format", "qddtd???qq " "BaseOfImage SizeOfImage CheckSum " @@ -737,20 +692,19 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct offset = entry->location.rva + sizeof(module_list); for (i = 0; i < module_list.number_of_modules; i++) { - struct minidump_module *module = RZ_NEW(struct minidump_module); + MiniDmpModule *module = RZ_NEW(MiniDmpModule); if (!module) { break; } - if (!read_module(obj->b, offset, module)) { + if (!mdmp_read_module(obj->b, &offset, module) || + !rz_list_append(obj->streams.modules, module)) { + free(module); break; } - rz_list_append(obj->streams.modules, module); - offset += sizeof(*module); } break; case MEMORY_LIST_STREAM: - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&memory_list, sizeof(memory_list)); - if (r != sizeof(memory_list)) { + if (!mdmp_read_memory_list32(obj->b, entry->location.rva, &memory_list)) { break; } @@ -763,29 +717,24 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct memory_list.number_of_memory_ranges), 0); - offset = entry->location.rva + sizeof(memory_list); + offset = entry->location.rva + sizeof(MiniDmpModuleList); for (i = 0; i < memory_list.number_of_memory_ranges; i++) { - struct minidump_memory_descriptor *desc = RZ_NEW(struct minidump_memory_descriptor); - if (!desc) { + MiniDmpMemDescr32 *desc = RZ_NEW(MiniDmpMemDescr32); + if (!desc || + !mdmp_read_memory_descriptor32(obj->b, &offset, desc) || + !rz_list_append(obj->streams.memories, desc)) { + free(desc); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)desc, sizeof(*desc)); - if (r != sizeof(*desc)) { - break; - } - rz_list_append(obj->streams.memories, desc); - offset += sizeof(*desc); } break; case EXCEPTION_STREAM: /* TODO: Not yet fully parsed or utilised */ - obj->streams.exception = RZ_NEW(struct minidump_exception_stream); - if (!obj->streams.exception) { - break; - } - - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)obj->streams.exception, sizeof(*obj->streams.exception)); - if (r != sizeof(*obj->streams.exception)) { + obj->streams.exception = RZ_NEW(MiniDmpExcStream); + offset = entry->location.rva; + if (!obj->streams.exception || + !mdmp_read_exception_stream(obj->b, &offset, obj->streams.exception)) { + RZ_FREE(obj->streams.exception); break; } @@ -806,15 +755,12 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct break; case SYSTEM_INFO_STREAM: - obj->streams.system_info = RZ_NEW(struct minidump_system_info); - if (!obj->streams.system_info) { + obj->streams.system_info = RZ_NEW(MiniDmpSysInfo); + if (!obj->streams.system_info || + !mdmp_read_system_info(obj->b, entry->location.rva, obj->streams.system_info)) { + RZ_FREE(obj->streams.system_info); break; } - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)obj->streams.system_info, sizeof(*obj->streams.system_info)); - if (r != sizeof(*obj->streams.system_info)) { - break; - } - sdb_num_set(obj->kv, "mdmp_system_info.offset", entry->location.rva, 0); /* TODO: We need E as a byte! */ @@ -829,8 +775,7 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct break; case THREAD_EX_LIST_STREAM: /* TODO: Not yet fully parsed or utilised */ - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&thread_ex_list, sizeof(thread_ex_list)); - if (r != sizeof(thread_ex_list)) { + if (!mdmp_read_thread_list(obj->b, entry->location.rva, &thread_ex_list)) { break; } @@ -848,22 +793,19 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct thread_ex_list.number_of_threads), 0); - offset = entry->location.rva + sizeof(thread_ex_list); + offset = entry->location.rva + sizeof(MiniDmpThreadExList); for (i = 0; i < thread_ex_list.number_of_threads; i++) { - struct minidump_thread_ex *thread = RZ_NEW(struct minidump_thread_ex); - if (!thread) { + MiniDmpThreadEx *thread = RZ_NEW(MiniDmpThreadEx); + if (!thread || + !mdmp_read_thread_ex(obj->b, &offset, thread) || + !rz_list_append(obj->streams.ex_threads, thread)) { + free(thread); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)thread, sizeof(*thread)); - if (r != sizeof(*thread)) { - break; - } - rz_list_append(obj->streams.ex_threads, thread); - offset += sizeof(*thread); } break; case MEMORY_64_LIST_STREAM: - if (!read_memory64_list(obj->b, entry->location.rva, &memory64_list)) { + if (!mdmp_read_memory_list64(obj->b, entry->location.rva, &memory64_list)) { break; } @@ -877,15 +819,15 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct 0); obj->streams.memories64.base_rva = memory64_list.base_rva; - offset = entry->location.rva + sizeof(memory64_list); + offset = entry->location.rva + sizeof(MiniDmpMemList64); for (i = 0; i < memory64_list.number_of_memory_ranges; i++) { - struct minidump_memory_descriptor64 *desc = RZ_NEW(struct minidump_memory_descriptor64); - if (!desc) { + MiniDmpMemDescr64 *desc = RZ_NEW(MiniDmpMemDescr64); + if (!desc || + !mdmp_read_memory_descriptor64(obj->b, &offset, desc) || + !rz_list_append(obj->streams.memories64.memories, desc)) { + free(desc); break; } - read_desc(obj->b, offset, desc); - rz_list_append(obj->streams.memories64.memories, desc); - offset += sizeof(*desc); } break; case COMMENT_STREAM_A: @@ -924,12 +866,10 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct break; case HANDLE_DATA_STREAM: /* TODO: Not yet fully parsed or utilised */ - obj->streams.handle_data = RZ_NEW(struct minidump_handle_data_stream); - if (!obj->streams.handle_data) { - break; - } - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)obj->streams.handle_data, sizeof(*obj->streams.handle_data)); - if (r != sizeof(*obj->streams.handle_data)) { + obj->streams.handle_data = RZ_NEW(MiniDmpHandleDataStream); + if (!obj->streams.handle_data || + !mdmp_read_handle_data_stream(obj->b, entry->location.rva, obj->streams.handle_data)) { + RZ_FREE(obj->streams.handle_data); break; } @@ -942,12 +882,10 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct break; case FUNCTION_TABLE_STREAM: /* TODO: Not yet fully parsed or utilised */ - obj->streams.function_table = RZ_NEW(struct minidump_function_table_stream); - if (!obj->streams.function_table) { - break; - } - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)obj->streams.function_table, sizeof(*obj->streams.function_table)); - if (r != sizeof(*obj->streams.function_table)) { + obj->streams.function_table = RZ_NEW(MiniDmpFuncTableStream); + if (!obj->streams.function_table || + !mdmp_read_function_table_stream(obj->b, entry->location.rva, obj->streams.function_table)) { + RZ_FREE(obj->streams.function_table); break; } @@ -960,8 +898,8 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct break; case UNLOADED_MODULE_LIST_STREAM: /* TODO: Not yet fully parsed or utilised */ - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&unloaded_module_list, sizeof(unloaded_module_list)); - if (r != sizeof(unloaded_module_list)) { + offset = entry->location.rva; + if (!mdmp_read_unloaded_module_list(obj->b, &offset, &unloaded_module_list)) { break; } @@ -975,28 +913,22 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct "SizeOfHeader SizeOfEntry NumberOfEntries", 0); - offset = entry->location.rva + sizeof(unloaded_module_list); for (i = 0; i < unloaded_module_list.number_of_entries; i++) { - struct minidump_unloaded_module *module = RZ_NEW(struct minidump_unloaded_module); - if (!module) { + MiniDmpUnloadedModule *module = RZ_NEW(MiniDmpUnloadedModule); + if (!module || + !mdmp_read_unloaded_module(obj->b, &offset, module) || + !rz_list_append(obj->streams.unloaded_modules, module)) { + free(module); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)module, sizeof(*module)); - if (r != sizeof(*module)) { - break; - } - rz_list_append(obj->streams.unloaded_modules, module); - offset += sizeof(*module); } break; case MISC_INFO_STREAM: /* TODO: Not yet fully parsed or utilised */ - obj->streams.misc_info.misc_info_1 = RZ_NEW(struct minidump_misc_info); - if (!obj->streams.misc_info.misc_info_1) { - break; - } - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)obj->streams.misc_info.misc_info_1, sizeof(*obj->streams.misc_info.misc_info_1)); - if (r != sizeof(*obj->streams.misc_info.misc_info_1)) { + obj->streams.misc_info.misc_info_1 = RZ_NEW(MiniDmpMiscInfo); + if (!obj->streams.misc_info.misc_info_1 || + !mdmp_read_misc_info(obj->b, entry->location.rva, obj->streams.misc_info.misc_info_1)) { + RZ_FREE(obj->streams.misc_info.misc_info_1); break; } @@ -1013,8 +945,8 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct break; case MEMORY_INFO_LIST_STREAM: - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&memory_info_list, sizeof(memory_info_list)); - if (r != sizeof(memory_info_list)) { + offset = entry->location.rva; + if (!mdmp_read_memory_info_list(obj->b, &offset, &memory_info_list)) { break; } @@ -1032,24 +964,20 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct memory_info_list.number_of_entries), 0); - offset = entry->location.rva + sizeof(memory_info_list); for (i = 0; i < memory_info_list.number_of_entries; i++) { - struct minidump_memory_info *info = RZ_NEW(struct minidump_memory_info); - if (!info) { + MiniDmpMemInfo *info = RZ_NEW(MiniDmpMemInfo); + if (!info || + !mdmp_read_memory_info(obj->b, &offset, info) || + !rz_list_append(obj->streams.memory_infos, info)) { + free(info); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)info, sizeof(*info)); - if (r != sizeof(*info)) { - break; - } - rz_list_append(obj->streams.memory_infos, info); - offset += sizeof(*info); } break; case THREAD_INFO_LIST_STREAM: /* TODO: Not yet fully parsed or utilised */ - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&thread_info_list, sizeof(thread_info_list)); - if (r != sizeof(thread_info_list)) { + offset = entry->location.rva; + if (!mdmp_read_thread_info_list(obj->b, &offset, &thread_info_list)) { break; } @@ -1063,24 +991,20 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct "SizeOfHeader SizeOfEntry NumberOfEntries", 0); - offset = entry->location.rva + sizeof(thread_info_list); for (i = 0; i < thread_info_list.number_of_entries; i++) { - struct minidump_thread_info *info = RZ_NEW(struct minidump_thread_info); - if (!info) { + MiniDmpThreadInfo *info = RZ_NEW(MiniDmpThreadInfo); + if (!info || + !mdmp_read_thread_info(obj->b, &offset, info) || + !rz_list_append(obj->streams.thread_infos, info)) { + free(info); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)info, sizeof(*info)); - if (r != sizeof(*info)) { - break; - } - rz_list_append(obj->streams.thread_infos, info); - offset += sizeof(*info); } break; case HANDLE_OPERATION_LIST_STREAM: /* TODO: Not yet fully parsed or utilised */ - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&handle_operation_list, sizeof(handle_operation_list)); - if (r != sizeof(handle_operation_list)) { + offset = entry->location.rva; + if (!mdmp_read_handle_operation_list(obj->b, &offset, &handle_operation_list)) { break; } @@ -1090,25 +1014,21 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct "SizeOfHeader SizeOfEntry NumberOfEntries Reserved", 0); - offset = entry->location.rva + sizeof(handle_operation_list); for (i = 0; i < handle_operation_list.number_of_entries; i++) { - struct avrf_handle_operation *op = RZ_NEW(struct avrf_handle_operation); - if (!op) { + AVRFHandleOp *op = RZ_NEW(AVRFHandleOp); + if (!op || + !mdmp_read_avrf_handle_operation(obj->b, &offset, op) || + !rz_list_append(obj->streams.operations, op)) { + free(op); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)op, sizeof(*op)); - if (r != sizeof(*op)) { - break; - } - rz_list_append(obj->streams.operations, op); - offset += sizeof(*op); } break; case TOKEN_STREAM: /* TODO: Not fully parsed or utilised */ - r = rz_buf_read_at(obj->b, entry->location.rva, (ut8 *)&token_info_list, sizeof(token_info_list)); - if (r != sizeof(token_info_list)) { + offset = entry->location.rva; + if (!mdmp_read_token_info_list(obj->b, &offset, &token_info_list)) { break; } @@ -1122,18 +1042,14 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct "TokenListSize TokenListEntries ListHeaderSize ElementHeaderSize", 0); - offset = entry->location.rva + sizeof(token_info_list); for (i = 0; i < token_info_list.number_of_entries; i++) { - struct minidump_token_info *info = RZ_NEW(struct minidump_token_info); - if (!info) { + MiniDmpTokenInfo *info = RZ_NEW(MiniDmpTokenInfo); + if (!info || + !mdmp_read_token_info(obj->b, &offset, info) || + !rz_list_append(obj->streams.token_infos, info)) { + free(info); break; } - r = rz_buf_read_at(obj->b, offset, (ut8 *)info, sizeof(*info)); - if (r != sizeof(*info)) { - break; - } - rz_list_append(obj->streams.token_infos, info); - offset += sizeof(*info); } break; @@ -1152,45 +1068,14 @@ static bool rz_bin_mdmp_init_directory_entry(struct rz_bin_mdmp_obj *obj, struct return true; } -static bool read_entry(RzBuffer *b, ut64 addr, struct minidump_directory *entry) { - st64 tmp = rz_buf_tell(b); - if (tmp < 0) { - return false; - } - - if (rz_buf_seek(b, addr, RZ_BUF_SET) < 0) { - return false; - } - - ut32 stream_type; - if (!rz_buf_read_le32(b, &stream_type)) { - return false; - } - entry->stream_type = stream_type; - - ut32 data_size; - if (!rz_buf_read_le32(b, &data_size)) { - return false; - } - entry->location.data_size = data_size; - - ut32 rva; - if (!rz_buf_read_le32(b, &rva)) { - return false; - } - entry->location.rva = rva; - - if (rz_buf_seek(b, tmp, RZ_BUF_SET) < 0) { - return false; - } - - return true; +static bool mdmp_read_directory(MiniDmpObj *obj, ut64 addr, MiniDmpDir *entry) { + ut64 offset = addr; + return rz_buf_read_le32_offset(obj->b, &offset, &entry->stream_type) && + mdmp_read_location_descriptor32(obj->b, &offset, &entry->location) && + mdmp_init_directory_entry(obj, entry); } -static bool rz_bin_mdmp_init_directory(struct rz_bin_mdmp_obj *obj) { - ut32 i; - struct minidump_directory entry; - +static bool rz_bin_mdmp_init_directory(MiniDmpObj *obj) { sdb_num_set(obj->kv, "mdmp_directory.offset", obj->hdr->stream_directory_rva, 0); sdb_set(obj->kv, "mdmp_directory.format", "[4]E? " @@ -1200,18 +1085,17 @@ static bool rz_bin_mdmp_init_directory(struct rz_bin_mdmp_obj *obj) { ut64 rvadir = obj->hdr->stream_directory_rva; ut64 bytes_left = rvadir < obj->size ? obj->size - rvadir : 0; - size_t max_entries = RZ_MIN(obj->hdr->number_of_streams, bytes_left / sizeof(struct minidump_directory)); + size_t max_entries = RZ_MIN(obj->hdr->number_of_streams, bytes_left / sizeof(MiniDmpDir)); if (max_entries < obj->hdr->number_of_streams) { RZ_LOG_ERROR("Number of streams = %u is greater than is supportable by bin size\n", obj->hdr->number_of_streams); } /* Parse each entry in the directory */ - for (i = 0; i < max_entries; i++) { - ut32 delta = i * sizeof(struct minidump_directory); - if (read_entry(obj->b, rvadir + delta, &entry)) { - if (!rz_bin_mdmp_init_directory_entry(obj, &entry)) { - return false; - } + for (ut32 i = 0; i < max_entries; i++) { + ut32 delta = i * sizeof(MiniDmpDir); + MiniDmpDir entry = { 0 }; + if (!mdmp_read_directory(obj, rvadir + delta, &entry)) { + return false; } } @@ -1303,10 +1187,10 @@ static int check_pe64_buf(RzBuffer *buf, ut64 length) { return ret; } -static bool rz_bin_mdmp_init_pe_bins(struct rz_bin_mdmp_obj *obj) { +static bool rz_bin_mdmp_init_pe_bins(MiniDmpObj *obj) { bool dup; ut64 paddr; - struct minidump_module *module; + MiniDmpModule *module; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin, *pe32_dup; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin, *pe64_dup; RzBuffer *buf; @@ -1369,8 +1253,8 @@ static bool rz_bin_mdmp_init_pe_bins(struct rz_bin_mdmp_obj *obj) { return true; } -static int rz_bin_mdmp_init(struct rz_bin_mdmp_obj *obj) { - rz_bin_mdmp_init_parsing(obj); +static int rz_bin_mdmp_init(MiniDmpObj *obj) { + mdmp_obj_sdb_init(obj); if (!rz_bin_mdmp_init_hdr(obj)) { RZ_LOG_ERROR("Failed to initialise header\n"); @@ -1390,8 +1274,8 @@ static int rz_bin_mdmp_init(struct rz_bin_mdmp_obj *obj) { return true; } -struct rz_bin_mdmp_obj *rz_bin_mdmp_new_buf(RzBuffer *buf) { - struct rz_bin_mdmp_obj *obj = RZ_NEW0(struct rz_bin_mdmp_obj); +MiniDmpObj *rz_bin_mdmp_new_buf(RzBuffer *buf) { + MiniDmpObj *obj = RZ_NEW0(MiniDmpObj); if (!obj) { return NULL; } diff --git a/librz/bin/format/mdmp/mdmp.h b/librz/bin/format/mdmp/mdmp.h index 7731dbb7d7..5588c915f6 100644 --- a/librz/bin/format/mdmp/mdmp.h +++ b/librz/bin/format/mdmp/mdmp.h @@ -14,22 +14,22 @@ #include "mdmp_pe.h" #include "mdmp_pe64.h" -struct rz_bin_mdmp_obj { - struct minidump_header *hdr; +typedef struct minidump_object_t { + MiniDmpHeader *hdr; /* Encountered streams */ struct minidump_streams { ut8 *comments_a; ut8 *comments_w; - struct minidump_exception_stream *exception; - struct minidump_function_table_stream *function_table; - struct minidump_handle_data_stream *handle_data; - struct minidump_system_info *system_info; + MiniDmpExcStream *exception; + MiniDmpFuncTableStream *function_table; + MiniDmpHandleDataStream *handle_data; + MiniDmpSysInfo *system_info; union { - struct minidump_misc_info *misc_info_1; - struct minidump_misc_info_2 *misc_info_2; + MiniDmpMiscInfo *misc_info_1; + MiniDmpMiscInfo2 *misc_info_2; } misc_info; /* Lists */ @@ -56,12 +56,12 @@ struct rz_bin_mdmp_obj { size_t size; ut8 endian; Sdb *kv; -}; +} MiniDmpObj; -struct rz_bin_mdmp_obj *rz_bin_mdmp_new_buf(RzBuffer *buf); -void rz_bin_mdmp_free(struct rz_bin_mdmp_obj *obj); -ut64 rz_bin_mdmp_get_paddr(struct rz_bin_mdmp_obj *obj, ut64 vaddr); -ut32 rz_bin_mdmp_get_perm(struct rz_bin_mdmp_obj *obj, ut64 vaddr); -struct minidump_memory_info *rz_bin_mdmp_get_mem_info(struct rz_bin_mdmp_obj *obj, ut64 vaddr); +MiniDmpObj *rz_bin_mdmp_new_buf(RzBuffer *buf); +void rz_bin_mdmp_free(MiniDmpObj *obj); +ut64 rz_bin_mdmp_get_paddr(MiniDmpObj *obj, ut64 vaddr); +ut32 rz_bin_mdmp_get_perm(MiniDmpObj *obj, ut64 vaddr); +MiniDmpMemInfo *rz_bin_mdmp_get_mem_info(MiniDmpObj *obj, ut64 vaddr); #endif /* MDMP_H */ diff --git a/librz/bin/format/mdmp/mdmp_specs.h b/librz/bin/format/mdmp/mdmp_specs.h index 638bce06aa..5f5bc73439 100644 --- a/librz/bin/format/mdmp/mdmp_specs.h +++ b/librz/bin/format/mdmp/mdmp_specs.h @@ -194,560 +194,493 @@ typedef enum thread_write_flags_t { } thread_write_flags; /* Contains header information for the minidump file. */ -RZ_PACKED( - struct minidump_header { - ut32 signature; - ut32 version; - ut32 number_of_streams; - rva_t stream_directory_rva; - ut32 check_sum; +typedef struct minidump_header_t { + ut32 signature; + ut32 version; + ut32 number_of_streams; + rva_t stream_directory_rva; + ut32 check_sum; - union { - ut32 reserved; - ut32 time_date_stamp; - }; + union { + ut32 reserved; + ut32 time_date_stamp; + }; - ut64 flags; - }); + ut64 flags; +} MiniDmpHeader; /* Contains information describing the location of a data stream within a * minidump file. */ -RZ_PACKED( - struct minidump_location_descriptor { - ut32 data_size; - rva_t rva; - }); +typedef struct minidump_location_descriptor32_t { + ut32 data_size; + rva_t rva; +} MiniDmpLocDescr32; /* Contains information describing the location of a data stream within a * minidump file. */ -RZ_PACKED( - struct minidump_location_descriptor64 { - ut64 data_size; - rva64_t rva; - }); +typedef struct minidump_location_descriptor64_t { + ut64 data_size; + rva64_t rva; +} MiniDmpLocDescr64; /* Describes a range of memory. */ -RZ_PACKED( - struct minidump_memory_descriptor { - ut64 start_of_memory_range; - struct minidump_location_descriptor memory; - }); +typedef struct minidump_memory_descriptor32_t { + ut64 start_of_memory_range; + MiniDmpLocDescr32 memory; +} MiniDmpMemDescr32; /* Describes a range of memory. */ -RZ_PACKED( - struct minidump_memory_descriptor64 { - ut64 start_of_memory_range; - ut64 data_size; - }); +typedef struct minidump_memory_descriptor64_t { + ut64 start_of_memory_range; + ut64 data_size; +} MiniDmpMemDescr64; /* Contains the information needed to access a specific data stream in a minidump file. */ -RZ_PACKED( - struct minidump_directory { - ut32 stream_type; - struct minidump_location_descriptor location; - }); +typedef struct minidump_directory_t { + ut32 stream_type; + MiniDmpLocDescr32 location; +} MiniDmpDir; /* Contains exception information. */ -RZ_PACKED( - struct minidump_exception { - ut32 exception_code; - ut32 exception_flags; - ut64 exception_record; - ut64 exception_address; - ut32 number_parameters; - ut32 __unused_alignment; - ut64 exception_information[EXCEPTION_MAXIMUM_PARAMETERS]; - }); +typedef struct minidump_exception_t { + ut32 exception_code; + ut32 exception_flags; + ut64 exception_record; + ut64 exception_address; + ut32 number_parameters; + ut32 __unused_alignment; + ut64 exception_information[EXCEPTION_MAXIMUM_PARAMETERS]; +} MiniDmpException; /* Contains exception information. */ -RZ_PACKED( - struct minidump_exception_stream { - ut32 thread_id; - ut32 __alignment; +typedef struct minidump_exception_stream_t { + ut32 thread_id; + ut32 __alignment; - struct minidump_exception exception_record; - struct minidump_location_descriptor thread_context; - }); + MiniDmpException exception_record; + MiniDmpLocDescr32 thread_context; +} MiniDmpExcStream; /* Describes an exception. */ -RZ_PACKED( - struct minidump_exception_record { - ut32 exception_code; - ut32 exception_flags; +typedef struct minidump_exception_record_t { + ut32 exception_code; + ut32 exception_flags; - struct minidump_exception_record *exception_record; + struct minidump_exception_record_t *exception_record; - void *exception_address; - ut32 number_parameters; - void /*ULONG_PTR*/ *exception_information[EXCEPTION_MAXIMUM_PARAMETERS]; - }); + void *exception_address; + ut32 number_parameters; + void /*ULONG_PTR*/ *exception_information[EXCEPTION_MAXIMUM_PARAMETERS]; +} MiniDmpExcRecord; /* unused */ /* Contains an exception record with a machine-independent description of an * exception and a context record with a machine-dependent description of the * processor context at the time of the exception. */ -RZ_PACKED( - struct minidump_exception_pointers { - struct minidump_exception_record exception_record; - void /* struct context */ *context_record; - }); +typedef struct minidump_exception_pointers_t { + MiniDmpExcRecord exception_record; + void /* struct context */ *context_record; +} MiniDmpExcPointers; /* unused */ /* Contains the exception information written to the minidump file by the * MiniDumpWriteDump function. */ -RZ_PACKED( - struct minidump_exception_information { - ut32 thread_id; - - struct minidump_exception_pointers *exception_pointers; - - ut8 /*bool*/ client_pointers; - }); +typedef struct minidump_exception_information_t { + ut32 thread_id; + MiniDmpExcPointers *exception_pointers; + ut8 /*bool*/ client_pointers; +} MiniDmpExcInfo; /* unused */ /* Represents a function table stream. */ -RZ_PACKED( - struct minidump_function_table_descriptor { - ut64 minimum_address; - ut64 maximum_address; - ut64 base_address; - ut32 entry_count; - ut32 size_of_align_pad; - }); +typedef struct minidump_function_table_descriptor_t { + ut64 minimum_address; + ut64 maximum_address; + ut64 base_address; + ut32 entry_count; + ut32 size_of_align_pad; +} MiniDmpFuncTableDescr; /* unused */ /* Represents the header for the function table stream. */ -RZ_PACKED( - struct minidump_function_table_stream { - ut32 size_of_header; - ut32 size_of_descriptor; - ut32 size_of_native_descriptor; - ut32 size_of_function_entry; - ut32 number_of_descriptors; - ut32 size_of_align_pad; - }); +typedef struct minidump_function_table_stream_t { + ut32 size_of_header; + ut32 size_of_descriptor; + ut32 size_of_native_descriptor; + ut32 size_of_function_entry; + ut32 number_of_descriptors; + ut32 size_of_align_pad; +} MiniDmpFuncTableStream; /* Represents the header for a handle data stream. */ -RZ_PACKED( - struct minidump_handle_data_stream { - ut32 size_of_header; - ut32 size_of_descriptor; - ut32 number_of_descriptors; - ut32 reserved; - }); +typedef struct minidump_handle_data_stream_t { + ut32 size_of_header; + ut32 size_of_descriptor; + ut32 number_of_descriptors; + ut32 reserved; +} MiniDmpHandleDataStream; /* Contains the state of an individual system handle at the time the minidump * was written. */ -RZ_PACKED( - struct minidump_handle_descriptor { - ut64 handle; - rva_t type_name_rva; - rva_t object_name_rva; - ut32 attributes; - ut32 granted_access; - ut32 handle_count; - ut32 pointer_count; - }); +typedef struct minidump_handle_descriptor_t { + ut64 handle; + rva_t type_name_rva; + rva_t object_name_rva; + ut32 attributes; + ut32 granted_access; + ut32 handle_count; + ut32 pointer_count; +} MiniDmpHandleDescr; /* unused */ /* Contains the state of an individual system handle at the time the minidump * was written. */ -RZ_PACKED( - struct minidump_handle_descriptor_2 { - ut64 handle; - rva_t type_name_rva; - rva_t object_name_rva; - ut32 attributes; - ut32 granted_access; - ut32 handle_count; - ut32 pointer_count; - rva_t object_info_rva; - ut32 reserved_0; - }); +typedef struct minidump_handle_descriptor_2_t { + ut64 handle; + rva_t type_name_rva; + rva_t object_name_rva; + ut32 attributes; + ut32 granted_access; + ut32 handle_count; + ut32 pointer_count; + rva_t object_info_rva; + ut32 reserved_0; +} MiniDmpHandleDescr2; /* unused */ /* Contains object-specific information for a handle. */ -RZ_PACKED( - struct minidump_handle_object_information { - rva_t next_info_rva; - ut32 info_type; - ut32 size_of_info; - }); +typedef struct minidump_handle_object_information_t { + rva_t next_info_rva; + ut32 info_type; + ut32 size_of_info; +} MiniDmpHandleObjInfo; /* unused */ /* Contains a list of memory ranges. */ -RZ_PACKED( - struct minidump_memory_list { - ut32 number_of_memory_ranges; - struct minidump_memory_descriptor memory_ranges[]; - }); +typedef struct minidump_memory_list32_t { + ut32 number_of_memory_ranges; +} MiniDmpMemList32; /* Contains a list of memory ranges. */ -RZ_PACKED( - struct minidump_memory64_list { - ut64 number_of_memory_ranges; - rva64_t base_rva; - struct minidump_memory_descriptor64 memory_ranges[]; - }); +typedef struct minidump_memory_list64_t { + ut64 number_of_memory_ranges; + rva64_t base_rva; +} MiniDmpMemList64; /* Describes a region of memory. */ -RZ_PACKED( - struct minidump_memory_info { - ut64 base_address; - ut64 allocation_base; - ut32 allocation_protect; - ut32 __alignment_1; - ut64 region_size; - ut32 state; - ut32 protect; - ut32 type; - ut32 __alignment_2; - }); +typedef struct minidump_memory_info_t { + ut64 base_address; + ut64 allocation_base; + ut32 allocation_protect; + ut32 __alignment_1; + ut64 region_size; + ut32 state; + ut32 protect; + ut32 type; + ut32 __alignment_2; +} MiniDmpMemInfo; /* Contains a list of memory regions. */ -RZ_PACKED( - struct minidump_memory_info_list { - ut32 size_of_header; - ut32 size_of_entry; - ut64 number_of_entries; - struct minidump_memory_info entries[]; - }); +typedef struct minidump_memory_info_list_t { + ut32 size_of_header; + ut32 size_of_entry; + ut64 number_of_entries; +} MiniDmpMemInfoList; /* Contains a variety of information. */ -RZ_PACKED( - struct minidump_misc_info { - ut32 size_of_info; - ut32 flags_1; - ut32 process_id; - ut32 process_create_time; - ut32 process_user_time; - ut32 process_kernel_time; - }); +typedef struct minidump_misc_info_t { + ut32 size_of_info; + ut32 flags_1; + ut32 process_id; + ut32 process_create_time; + ut32 process_user_time; + ut32 process_kernel_time; +} MiniDmpMiscInfo; /* Represents information in the miscellaneous information stream. */ -RZ_PACKED( - struct minidump_misc_info_2 { - ut32 size_of_info; - ut32 flags_1; - ut32 process_id; - ut32 process_create_time; - ut32 process_user_time; - ut32 process_kernel_time; - ut32 processor_max_mhz; - ut32 processor_current_mhz; - ut32 processor_mhz_limit; - ut32 processor_max_idle_state; - ut32 processor_current_idle_state; - }); +typedef struct minidump_misc_info_2_t { + ut32 size_of_info; + ut32 flags_1; + ut32 process_id; + ut32 process_create_time; + ut32 process_user_time; + ut32 process_kernel_time; + ut32 processor_max_mhz; + ut32 processor_current_mhz; + ut32 processor_mhz_limit; + ut32 processor_max_idle_state; + ut32 processor_current_idle_state; +} MiniDmpMiscInfo2; /* unused */ /* Contains version information for a file. This information is language and * code page independent. */ -RZ_PACKED( - struct vs_fixedfileinfo { - ut32 dw_signature; - ut32 dw_struc_version; - ut32 dw_file_version_ms; - ut32 dw_file_version_ls; - ut32 dw_product_version_ms; - ut32 dw_product_version_ls; - ut32 dw_file_flags_mask; - ut32 dw_file_flags; - ut32 dw_file_os; - ut32 dw_file_type; - ut32 dw_file_subtype; - ut32 dw_file_date_ms; - ut32 dw_file_date_ls; - }); +typedef struct vs_fixedfileinfo_t { + ut32 dw_signature; + ut32 dw_struc_version; + ut32 dw_file_version_ms; + ut32 dw_file_version_ls; + ut32 dw_product_version_ms; + ut32 dw_product_version_ls; + ut32 dw_file_flags_mask; + ut32 dw_file_flags; + ut32 dw_file_os; + ut32 dw_file_type; + ut32 dw_file_subtype; + ut32 dw_file_date_ms; + ut32 dw_file_date_ls; +} VSFixedFileInfo; /* Contains information for a specific module. */ -RZ_PACKED( - struct minidump_module { - ut64 base_of_image; - ut32 size_of_image; - ut32 check_sum; - ut32 time_date_stamp; - rva_t module_name_rva; +typedef struct minidump_module_t { + ut64 base_of_image; + ut32 size_of_image; + ut32 check_sum; + ut32 time_date_stamp; + rva_t module_name_rva; - struct vs_fixedfileinfo version_info; - struct minidump_location_descriptor cv_record; - struct minidump_location_descriptor misc_record; + VSFixedFileInfo version_info; + MiniDmpLocDescr32 cv_record; + MiniDmpLocDescr32 misc_record; - ut64 reserved_0; - ut64 reserved_1; - }); + ut64 reserved_0; + ut64 reserved_1; +} MiniDmpModule; /* Contains a list of modules. */ -RZ_PACKED( - struct minidump_module_list { - ut32 number_of_modules; - struct minidump_module modules[]; - }); - -/* Describes a string. */ -RZ_PACKED( - struct minidump_string { - ut32 length; - ut16 *buffer; - }); +typedef struct minidump_module_list_t { + ut32 number_of_modules; +} MiniDmpModuleList; /* Contains processor and operating system information. */ -RZ_PACKED( - struct minidump_system_info { - ut16 processor_architecture; - ut16 processor_level; - ut16 processor_revision; +typedef struct minidump_system_info_t { + ut16 processor_architecture; + ut16 processor_level; + ut16 processor_revision; - union { - ut16 reserved_0; - struct { - ut8 number_of_processors; - ut8 product_type; - }; + union { + ut16 reserved_0; + struct { + ut8 number_of_processors; + ut8 product_type; }; + }; - ut32 major_version; - ut32 minor_version; - ut32 build_number; - ut32 platform_id; - rva_t csd_version_rva; + ut32 major_version; + ut32 minor_version; + ut32 build_number; + ut32 platform_id; + rva_t csd_version_rva; - union { - ut32 reserved_1; - struct { - ut16 suite_mask; - ut16 reserved_2; - }; + union { + ut32 reserved_1; + struct { + ut16 suite_mask; + ut16 reserved_2; }; + }; - union { - struct { - ut32 vendor_id[3]; - ut32 version_information; - ut32 feature_information; - ut32 amd_extended_cpu_features; - } x86_cpu_info; - struct { - ut64 processor_features[2]; - } other_cpu_info; - } cpu; - }); + union { + struct { + ut32 vendor_id[3]; + ut32 version_information; + ut32 feature_information; + ut32 amd_extended_cpu_features; + } x86_cpu_info; + struct { + ut64 processor_features[2]; + } other_cpu_info; + } cpu; +} MiniDmpSysInfo; /* Contains information for a specific thread. */ -RZ_PACKED( - struct minidump_thread { - ut32 thread_id; - ut32 suspend_count; - ut32 priority_class; - ut32 priority; - ut64 teb; - struct minidump_memory_descriptor stack; - struct minidump_location_descriptor thread_context; - }); +typedef struct minidump_thread_t { + ut32 thread_id; + ut32 suspend_count; + ut32 priority_class; + ut32 priority; + ut64 teb; + MiniDmpMemDescr32 stack; + MiniDmpLocDescr32 thread_context; +} MiniDmpThread; /* Contains a list of threads. */ -RZ_PACKED( - struct minidump_thread_list { - ut32 number_of_threads; - struct minidump_thread threads[0]; - }); +typedef struct minidump_thread_list_t { + ut32 number_of_threads; + MiniDmpThread threads[0]; // not parsed because not used due missing usage. +} MiniDmpThreadList; /* Contains extended information for a specific thread. */ -RZ_PACKED( - struct minidump_thread_ex { - ut32 thread_id; - ut32 suspend_count; - ut32 priority_class; - ut32 priority; - ut64 teb; +typedef struct minidump_thread_ex_t { + ut32 thread_id; + ut32 suspend_count; + ut32 priority_class; + ut32 priority; + ut64 teb; - struct minidump_memory_descriptor stack; - struct minidump_location_descriptor thread_context; - struct minidump_memory_descriptor backing_store; - }); + MiniDmpMemDescr32 stack; + MiniDmpLocDescr32 thread_context; + MiniDmpMemDescr32 backing_store; +} MiniDmpThreadEx; /* Contains a list of threads. */ -RZ_PACKED( - struct minidump_thread_ex_list { - ut32 number_of_threads; - struct minidump_thread_ex threads[]; - }); +typedef struct minidump_thread_ex_list_t { + ut32 number_of_threads; +} MiniDmpThreadExList; /* Contains thread state information. */ -RZ_PACKED( - struct minidump_thread_info { - ut32 thread_id; - ut32 dump_flags; - ut32 dump_error; - ut32 exit_status; - ut64 create_time; - ut64 exit_time; - ut64 kernel_time; - ut64 user_time; - ut64 start_address; - ut64 affinity; - }); +typedef struct minidump_thread_info_t { + ut32 thread_id; + ut32 dump_flags; + ut32 dump_error; + ut32 exit_status; + ut64 create_time; + ut64 exit_time; + ut64 kernel_time; + ut64 user_time; + ut64 start_address; + ut64 affinity; +} MiniDmpThreadInfo; /* Contains a list of threads. */ -RZ_PACKED( - struct minidump_thread_info_list { - ut32 size_of_header; - ut32 size_of_entry; - ut32 number_of_entries; - struct minidump_thread_info entries[]; - }); +typedef struct minidump_thread_info_list_t { + ut32 size_of_header; + ut32 size_of_entry; + ut32 number_of_entries; +} MiniDmpThreadInfoList; /* Contains a token information. */ -RZ_PACKED( - struct minidump_token_info { - ut32 token_size; - ut32 token_id; - ut64 token_handle; - }); +typedef struct minidump_token_info_t { + ut32 token_size; + ut32 token_id; + ut64 token_handle; +} MiniDmpTokenInfo; /* Contains a list of token information. */ -RZ_PACKED( - struct minidump_token_info_list { - ut32 size_of_list; - ut32 number_of_entries; - ut32 list_header_size; - ut32 element_header_size; - struct minidump_token_info entries[]; - }); +typedef struct minidump_token_info_list_t { + ut32 size_of_list; + ut32 number_of_entries; + ut32 list_header_size; + ut32 element_header_size; +} MiniDmpTokenInfoList; /* Contains information about a module that has been unloaded. This information * can help diagnose problems calling code that is no longer loaded. */ -RZ_PACKED( - struct minidump_unloaded_module { - ut64 base_of_image; - ut32 size_of_image; - ut32 check_sum; - ut32 time_date_stamp; - rva_t module_name_rva; - }); +typedef struct minidump_unloaded_module_t { + ut64 base_of_image; + ut32 size_of_image; + ut32 check_sum; + ut32 time_date_stamp; + rva_t module_name_rva; +} MiniDmpUnloadedModule; /* Contains a list of unloaded modules. */ -RZ_PACKED( - struct minidump_unloaded_module_list { - ut32 size_of_header; - ut32 size_of_entry; - ut32 number_of_entries; - struct minidump_unloaded_module entries[]; - }); +typedef struct minidump_unloaded_module_list_t { + ut32 size_of_header; + ut32 size_of_entry; + ut32 number_of_entries; +} MiniDmpUnloadedModuleList; /* Contains user-defined information stored in a data stream. */ -RZ_PACKED( - struct minidump_user_stream { - ut32 type; - ut32 buffer_size; - void /*PVOID*/ *buffer; - }); +typedef struct minidump_user_stream_t { + ut32 type; + ut32 buffer_size; + void /*PVOID*/ *buffer; +} MiniDmpUserStream; /* unused */ /* Contains a list of user data streams used by the MiniDumpWriteDump function. */ -RZ_PACKED( - struct minidump_user_stream_information { - ut32 user_stream_count; - - struct minidump_user_stream *user_stream_array; - }); +typedef struct minidump_user_stream_information_t { + ut32 user_stream_count; + MiniDmpUserStream *user_stream_array; +} MiniDmpUserStreamInfo; /* unused */ /* Contains information for the MiniDumpCallback function when the callback * type is IncludeThreadCallback. */ -RZ_PACKED( - struct minidump_include_thread_callback { - ut32 thread_id; - }); +typedef struct minidump_include_thread_callback_t { + ut32 thread_id; +} MiniDmpIncludeThreadCallback; /* unused */ /* Contains module information for the MiniDumpCallback function when the * callback type is ModuleCallback. */ -RZ_PACKED( - struct minidump_module_callback { - ut16 /*pwchar*/ *full_path; - ut64 base_of_image; - ut32 size_of_image; - ut32 check_sum; - ut32 time_date_stamp; +typedef struct minidump_module_callback_t { + ut16 /*pwchar*/ *full_path; + ut64 base_of_image; + ut32 size_of_image; + ut32 check_sum; + ut32 time_date_stamp; - struct vs_fixedfileinfo version_info; + VSFixedFileInfo version_info; - void /*pvoid*/ *cv_record; - ut32 size_of_cv_record; - void /*pvoid*/ *misc_record; - ut32 size_of_misc_record; - }); + void /*pvoid*/ *cv_record; + ut32 size_of_cv_record; + void /*pvoid*/ *misc_record; + ut32 size_of_misc_record; +} MiniDmpModuleCallback; /* unused */ /* Contains information for the MiniDumpCallback function when the callback * type is IncludeModuleCallback. */ -RZ_PACKED( - struct minidump_include_module_callback { - ut64 base_of_image; - }); +typedef struct minidump_include_module_callback_t { + ut64 base_of_image; +} MiniDmpIncludeModuleCallback; /* unused */ /* Contains I/O callback information. This structure is used by the * MiniDumpCallback function when the callback type is IoStartCallback, * IoWriteAllCallback, or IoFinishCallback. */ -RZ_PACKED( - struct minidump_io_callback { - void /*handle*/ *Handle; - ut64 offset; - void /*pvoid*/ *buffer; - ut32 buffer_bytes; - }); +typedef struct minidump_io_callback_t { + void /*handle*/ *Handle; + ut64 offset; + void /*pvoid*/ *buffer; + ut32 buffer_bytes; +} MiniDmpIOCallback; /* unused */ /* Contains information about a failed memory read operation. This structure is * used by the MiniDumpCallback function when the callback type is * ReadMemoryFailureCallback. */ -RZ_PACKED( - struct minidump_read_memory_failure_callback { - ut64 offset; - ut32 bytes; - st32 /* HRESULT */ failure_status; - }); +typedef struct minidump_read_memory_failure_callback_t { + ut64 offset; + ut32 bytes; + st32 /* HRESULT */ failure_status; +} MiniDmpReadMemoryFailureCallback; /* unused */ /* Contains information returned by the MiniDumpCallback function. */ -RZ_PACKED( - struct minidump_callback_output { - union { - ut32 module_write_flags; - ut32 thread_write_flags; - ut32 secondary_flags; - struct { - ut64 memory_base; - ut32 memory_size; - }; - struct { - ut8 /*bool*/ check_cancel; - ut8 /*bool*/ cancel; - }; - void /*handle*/ *handle; - }; - +typedef struct minidump_callback_output_t { + union { + ut32 module_write_flags; + ut32 thread_write_flags; + ut32 secondary_flags; struct { - struct minidump_memory_info vm_region; - ut8 /*bool*/ should_continue; + ut64 memory_base; + ut32 memory_size; }; + struct { + ut8 /*bool*/ check_cancel; + ut8 /*bool*/ cancel; + }; + void /*handle*/ *handle; + }; - st32 /* HRESULT */ status; - }); + struct { + MiniDmpMemInfo vm_region; + ut8 /*bool*/ should_continue; + }; -RZ_PACKED( - struct avrf_backtrace_information { - ut32 depth; - ut32 index; - ut64 return_addresses[AVRF_MAX_TRACES]; - }); + st32 /* HRESULT */ status; +} MiniDmpCallbackOutput; /* unused */ -RZ_PACKED( - struct avrf_handle_operation { - ut64 handle; - ut32 process_id; - ut32 thread_id; - ut32 operation_type; - ut32 spare_0; +typedef struct avrf_backtrace_information_t { + ut32 depth; + ut32 index; + ut64 return_addresses[AVRF_MAX_TRACES]; +} AVRFBacktraceInfo; - struct avrf_backtrace_information back_trace_information; - }); +typedef struct avrf_handle_operation_t { + ut64 handle; + ut32 process_id; + ut32 thread_id; + ut32 operation_type; + ut32 spare_0; + + AVRFBacktraceInfo back_trace_information; +} AVRFHandleOp; /* Contains a list of handle operations. */ -RZ_PACKED( - struct minidump_handle_operation_list { - ut32 size_of_header; - ut32 size_of_entry; - ut32 number_of_entries; - ut32 reserved; - struct avrf_handle_operation entries[]; - }); +typedef struct minidump_handle_operation_list_t { + ut32 size_of_header; + ut32 size_of_entry; + ut32 number_of_entries; + ut32 reserved; +} MiniDmpHandleOpList; #endif /* MDMP_SPECS_H */ diff --git a/librz/bin/p/bin_mdmp.c b/librz/bin/p/bin_mdmp.c index 5d8c00eae9..2990f2c063 100644 --- a/librz/bin/p/bin_mdmp.c +++ b/librz/bin/p/bin_mdmp.c @@ -10,18 +10,18 @@ #include "mdmp/mdmp.h" -static Sdb *get_sdb(RzBinFile *bf) { +static Sdb *mdmp_get_sdb(RzBinFile *bf) { rz_return_val_if_fail(bf && bf->o, NULL); - struct rz_bin_mdmp_obj *obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + MiniDmpObj *obj = (MiniDmpObj *)bf->o->bin_obj; return (obj && obj->kv) ? obj->kv : NULL; } -static void destroy(RzBinFile *bf) { - rz_bin_mdmp_free((struct rz_bin_mdmp_obj *)bf->o->bin_obj); +static void mdmp_destroy(RzBinFile *bf) { + rz_bin_mdmp_free((MiniDmpObj *)bf->o->bin_obj); } -static RzList /**/ *entries(RzBinFile *bf) { - struct rz_bin_mdmp_obj *obj; +static RzList /**/ *mdmp_entries(RzBinFile *bf) { + MiniDmpObj *obj; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin; RzListIter *it; @@ -31,7 +31,7 @@ static RzList /**/ *entries(RzBinFile *bf) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; rz_list_foreach (obj->pe32_bins, it, pe32_bin) { list = Pe32_rz_bin_mdmp_pe_get_entrypoint(pe32_bin); @@ -47,15 +47,15 @@ static RzList /**/ *entries(RzBinFile *bf) { return ret; } -static RzBinInfo *info(RzBinFile *bf) { - struct rz_bin_mdmp_obj *obj; +static RzBinInfo *mdmp_info(RzBinFile *bf) { + MiniDmpObj *obj; RzBinInfo *ret; if (!(ret = RZ_NEW0(RzBinInfo))) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; ret->big_endian = obj->endian; ret->claimed_checksum = strdup(sdb_fmt("0x%08x", obj->hdr->check_sum)); // FIXME: Leaks @@ -121,10 +121,10 @@ static RzBinInfo *info(RzBinFile *bf) { return ret; } -static RzList /**/ *libs(RzBinFile *bf) { +static RzList /**/ *mdmp_libs(RzBinFile *bf) { char *ptr = NULL; int i; - struct rz_bin_mdmp_obj *obj; + MiniDmpObj *obj; struct rz_bin_pe_lib_t *libs = NULL; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin; @@ -138,7 +138,7 @@ static RzList /**/ *libs(RzBinFile *bf) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; /* TODO: Resolve module name for lib, or filter to remove duplicates, ** rather than the vaddr :) */ @@ -165,26 +165,26 @@ static RzList /**/ *libs(RzBinFile *bf) { return ret; } -static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) { +static bool mdmp_load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) { rz_return_val_if_fail(buf, false); - struct rz_bin_mdmp_obj *res = rz_bin_mdmp_new_buf(buf); + MiniDmpObj *res = rz_bin_mdmp_new_buf(buf); if (res) { - sdb_ns_set(sdb, "info", res->kv); + sdb_ns_set(sdb, "mdmp_info", res->kv); obj->bin_obj = res; return true; } return false; } -static RzList /**/ *maps(RzBinFile *bf) { - struct rz_bin_mdmp_obj *obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; +static RzList /**/ *mdmp_maps(RzBinFile *bf) { + MiniDmpObj *obj = (MiniDmpObj *)bf->o->bin_obj; RzList *ret = rz_list_newf((RzListFree)rz_bin_map_free); if (!ret) { return NULL; } RzListIter *it; - struct minidump_memory_descriptor *memory; + MiniDmpMemDescr32 *memory; rz_list_foreach (obj->streams.memories, it, memory) { RzBinMap *map = RZ_NEW0(RzBinMap); if (!map) { @@ -200,7 +200,7 @@ static RzList /**/ *maps(RzBinFile *bf) { } ut64 index = obj->streams.memories64.base_rva; - struct minidump_memory_descriptor64 *memory64; + MiniDmpMemDescr64 *memory64; rz_list_foreach (obj->streams.memories64.memories, it, memory64) { RzBinMap *map = RZ_NEW0(RzBinMap); if (!map) { @@ -219,17 +219,18 @@ static RzList /**/ *maps(RzBinFile *bf) { return ret; } -static RzList /**/ *sections(RzBinFile *bf) { - struct minidump_module *module; - struct minidump_string *str; - struct rz_bin_mdmp_obj *obj; +static RzList /**/ *mdmp_sections(RzBinFile *bf) { + MiniDmpModule *module; + MiniDmpObj *obj; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin; RzList *ret, *pe_secs; RzListIter *it, *it0; RzBinSection *ptr; + ut8 str_buffer[512]; + ut32 str_length = 0; - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; if (!(ret = rz_list_newf((RzListFree)rz_bin_section_free))) { return NULL; @@ -237,32 +238,36 @@ static RzList /**/ *sections(RzBinFile *bf) { // XXX: Never add here as they are covered above rz_list_foreach (obj->streams.modules, it, module) { - ut8 b[512]; + if (!rz_buf_read_le32_at(obj->b, module->module_name_rva, &str_length)) { + RZ_LOG_ERROR("bin: mdmp: failed to read utf16 string length\n"); + break; + } + + size_t ptr_name_len = (str_length + 2) * 4; + if (ptr_name_len < 1 || ptr_name_len > (sizeof(str_buffer) + sizeof(str_length))) { + continue; + } else if ((module->module_name_rva + sizeof(str_length) + str_length) > rz_buf_size(obj->b)) { + break; + } + + memset(str_buffer, 0, sizeof(str_buffer)); + + // best effor reading + if (rz_buf_read_at(obj->b, module->module_name_rva + sizeof(str_length), str_buffer, sizeof(str_buffer)) < 2) { + RZ_LOG_ERROR("bin: mdmp: failed to read utf16 string\n"); + break; + } if (!(ptr = RZ_NEW0(RzBinSection))) { return ret; } - if (module->module_name_rva + sizeof(struct minidump_string) >= rz_buf_size(obj->b)) { - free(ptr); - continue; - } - rz_buf_read_at(obj->b, module->module_name_rva, (ut8 *)&b, sizeof(b)); - str = (struct minidump_string *)b; - int ptr_name_len = (str->length + 2) * 4; - if (ptr_name_len < 1 || ptr_name_len > sizeof(b) - 4) { - continue; - } - if (module->module_name_rva + str->length > rz_buf_size(obj->b)) { - free(ptr); - break; - } - ptr->name = calloc(1, ptr_name_len); + + ptr->name = RZ_NEWS0(char, ptr_name_len); if (!ptr->name) { free(ptr); continue; } - rz_str_utf16_to_utf8((ut8 *)ptr->name, str->length * 4, - (const ut8 *)(&str->buffer), str->length, obj->endian); + rz_str_utf16_to_utf8((ut8 *)ptr->name, str_length * 4, str_buffer, str_length, obj->endian); ptr->vaddr = module->base_of_image; ptr->vsize = module->size_of_image; ptr->paddr = rz_bin_mdmp_get_paddr(obj, ptr->vaddr); @@ -297,12 +302,12 @@ static RzList /**/ *sections(RzBinFile *bf) { return ret; } -static RzList /**/ *mem(RzBinFile *bf) { - struct minidump_location_descriptor *location = NULL; - struct minidump_memory_descriptor *module; - struct minidump_memory_descriptor64 *module64; - struct minidump_memory_info *mem_info; - struct rz_bin_mdmp_obj *obj; +static RzList /**/ *mdmp_mem(RzBinFile *bf) { + MiniDmpLocDescr32 *location = NULL; + MiniDmpMemDescr32 *module; + MiniDmpMemDescr64 *module64; + MiniDmpMemInfo *mem_info; + MiniDmpObj *obj; RzList *ret; RzListIter *it; RzBinMem *ptr; @@ -313,9 +318,9 @@ static RzList /**/ *mem(RzBinFile *bf) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; - /* [1] As there isnt a better place to put this info at the moment we will + /* [1] As there isnt a better place to put this mdmp_info at the moment we will ** mash it into the name field, but without enumeration for now */ rz_list_foreach (obj->streams.memories, it, module) { if (!(ptr = RZ_NEW0(RzBinMem))) { @@ -368,8 +373,8 @@ static RzList /**/ *mem(RzBinFile *bf) { return ret; } -static RzList /**/ *relocs(RzBinFile *bf) { - struct rz_bin_mdmp_obj *obj; +static RzList /**/ *mdmp_relocs(RzBinFile *bf) { + MiniDmpObj *obj; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin; RzListIter *it; @@ -379,7 +384,7 @@ static RzList /**/ *relocs(RzBinFile *bf) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; rz_list_foreach (obj->pe32_bins, it, pe32_bin) { if (pe32_bin->bin && pe32_bin->bin->relocs) { @@ -395,8 +400,8 @@ static RzList /**/ *relocs(RzBinFile *bf) { return ret; } -static RzList /**/ *imports(RzBinFile *bf) { - struct rz_bin_mdmp_obj *obj; +static RzList /**/ *mdmp_imports(RzBinFile *bf) { + MiniDmpObj *obj; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin; RzList *list; @@ -407,7 +412,7 @@ static RzList /**/ *imports(RzBinFile *bf) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; rz_list_foreach (obj->pe32_bins, it, pe32_bin) { list = Pe32_rz_bin_mdmp_pe_get_imports(pe32_bin); @@ -426,8 +431,8 @@ static RzList /**/ *imports(RzBinFile *bf) { return ret; } -static RzList /**/ *symbols(RzBinFile *bf) { - struct rz_bin_mdmp_obj *obj; +static RzList /**/ *mdmp_symbols(RzBinFile *bf) { + MiniDmpObj *obj; struct Pe32_rz_bin_mdmp_pe_bin *pe32_bin; struct Pe64_rz_bin_mdmp_pe_bin *pe64_bin; RzList *ret, *list; @@ -437,7 +442,7 @@ static RzList /**/ *symbols(RzBinFile *bf) { return NULL; } - obj = (struct rz_bin_mdmp_obj *)bf->o->bin_obj; + obj = (MiniDmpObj *)bf->o->bin_obj; rz_list_foreach (obj->pe32_bins, it, pe32_bin) { list = Pe32_rz_bin_mdmp_pe_get_symbols(bf->rbin, pe32_bin); @@ -452,7 +457,7 @@ static RzList /**/ *symbols(RzBinFile *bf) { return ret; } -static bool check_buffer(RzBuffer *b) { +static bool mdmp_check_buffer(RzBuffer *b) { ut8 magic[6]; if (rz_buf_read_at(b, 0, magic, sizeof(magic)) == 6) { return !memcmp(magic, MDMP_MAGIC, 6); @@ -460,28 +465,28 @@ static bool check_buffer(RzBuffer *b) { return false; } -static RzList /**/ *strings(RzBinFile *bf) { +static RzList /**/ *mdmp_strings(RzBinFile *bf) { return rz_bin_file_strings(bf, 0, false); } RzBinPlugin rz_bin_plugin_mdmp = { .name = "mdmp", - .desc = "Minidump format rz_bin plugin", + .desc = "Windows MiniDump plugin", .license = "LGPL3", - .destroy = &destroy, - .entries = entries, - .get_sdb = &get_sdb, - .imports = &imports, - .info = &info, - .libs = &libs, - .load_buffer = &load_buffer, - .check_buffer = &check_buffer, - .mem = &mem, - .relocs = &relocs, - .maps = &maps, - .sections = §ions, - .symbols = &symbols, - .strings = &strings, + .destroy = &mdmp_destroy, + .entries = mdmp_entries, + .get_sdb = &mdmp_get_sdb, + .imports = &mdmp_imports, + .info = &mdmp_info, + .libs = &mdmp_libs, + .load_buffer = &mdmp_load_buffer, + .check_buffer = &mdmp_check_buffer, + .mem = &mdmp_mem, + .relocs = &mdmp_relocs, + .maps = &mdmp_maps, + .sections = &mdmp_sections, + .symbols = &mdmp_symbols, + .strings = &mdmp_strings, }; #ifndef RZ_PLUGIN_INCORE diff --git a/test/db/cmd/cmd_list b/test/db/cmd/cmd_list index 796dc42004..a424a8c804 100644 --- a/test/db/cmd/cmd_list +++ b/test/db/cmd/cmd_list @@ -116,7 +116,7 @@ bin luac LUA Compiled File (LGPL3) bin mach0 mach0 bin plugin (LGPL3) bin mach064 mach064 bin plugin (LGPL3) bin mbn MBN/SBL bootloader things (LGPL3) -bin mdmp Minidump format rz_bin plugin (LGPL3) +bin mdmp Windows MiniDump plugin (LGPL3) bin menuet Menuet/KolibriOS bin plugin (LGPL3) bin mz MZ bin plugin (MIT) bin ne NE format plugin (LGPL3) GustavoLCR @@ -219,7 +219,7 @@ NAME=Print the bin plugins in JSON FILE== CMDS=Lij EXPECT=<