mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-04 04:28:20 +00:00
Fix s390x mdmp symbols count ##refactor (#17977)
This commit is contained in:
parent
1c443d056a
commit
63249d6a84
@ -323,12 +323,25 @@ static void r_bin_mdmp_init_parsing(struct r_bin_mdmp_obj *obj) {
|
||||
sdb_set (obj->kv, "mdmp_string.format", "dZ Length Buffer", 0);
|
||||
}
|
||||
|
||||
static void read_hdr(RBuffer *b, struct minidump_header *hdr) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
r_buf_seek (b, 0, R_BUF_SET);
|
||||
hdr->signature = r_buf_read_le32 (b);
|
||||
hdr->version = r_buf_read_le32 (b);
|
||||
hdr->number_of_streams = r_buf_read_le32 (b);
|
||||
hdr->stream_directory_rva = r_buf_read_le32 (b);
|
||||
hdr->check_sum = r_buf_read_le32 (b);
|
||||
hdr->reserved = r_buf_read_le32 (b);
|
||||
hdr->flags = r_buf_read_le64 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
}
|
||||
|
||||
static bool r_bin_mdmp_init_hdr(struct r_bin_mdmp_obj *obj) {
|
||||
obj->hdr = R_NEW (struct minidump_header);
|
||||
if (!obj->hdr) {
|
||||
return false;
|
||||
}
|
||||
r_buf_read_at (obj->b, 0, (ut8 *)obj->hdr, sizeof (*obj->hdr));
|
||||
read_hdr (obj->b, obj->hdr);
|
||||
|
||||
if (obj->hdr->number_of_streams == 0) {
|
||||
eprintf ("[WARN] No streams present!\n");
|
||||
@ -356,6 +369,52 @@ static bool r_bin_mdmp_init_hdr(struct r_bin_mdmp_obj *obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void read_module(RBuffer *b, ut64 addr, struct minidump_module *module) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
r_buf_seek (b, addr, R_BUF_SET);
|
||||
module->base_of_image = r_buf_read_le64 (b);
|
||||
module->size_of_image = r_buf_read_le32 (b);
|
||||
module->check_sum = r_buf_read_le32 (b);
|
||||
module->time_date_stamp = r_buf_read_le32 (b);
|
||||
module->module_name_rva = r_buf_read_le32 (b);
|
||||
module->version_info.dw_signature = r_buf_read_le32 (b);
|
||||
module->version_info.dw_struc_version = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_version_ms = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_version_ls = r_buf_read_le32 (b);
|
||||
module->version_info.dw_product_version_ms = r_buf_read_le32 (b);
|
||||
module->version_info.dw_product_version_ls = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_flags_mask = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_flags = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_os = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_type = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_subtype = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_date_ms = r_buf_read_le32 (b);
|
||||
module->version_info.dw_file_date_ls = r_buf_read_le32 (b);
|
||||
module->cv_record.data_size = r_buf_read_le32 (b);
|
||||
module->cv_record.rva = r_buf_read_le32 (b);
|
||||
module->misc_record.data_size = r_buf_read_le32 (b);
|
||||
module->misc_record.rva = r_buf_read_le32 (b);
|
||||
module->reserved_0 = r_buf_read_le64 (b);
|
||||
module->reserved_1 = r_buf_read_le64 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
}
|
||||
|
||||
static void read_memory64_list(RBuffer *b, ut64 addr, struct minidump_memory64_list *memory64_list) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
r_buf_seek (b, addr, R_BUF_SET);
|
||||
memory64_list->number_of_memory_ranges = r_buf_read_le64 (b);
|
||||
memory64_list->base_rva = r_buf_read_le64 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
}
|
||||
|
||||
static void read_desc(RBuffer *b, ut64 addr, struct minidump_memory_descriptor64 *desc) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
r_buf_seek (b, addr, R_BUF_SET);
|
||||
desc->start_of_memory_range = r_buf_read_le64 (b);
|
||||
desc->data_size = r_buf_read_le64 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
}
|
||||
|
||||
static bool r_bin_mdmp_init_directory_entry(struct r_bin_mdmp_obj *obj, struct minidump_directory *entry) {
|
||||
struct minidump_handle_operation_list handle_operation_list;
|
||||
struct minidump_memory_list memory_list;
|
||||
@ -399,10 +458,7 @@ static bool r_bin_mdmp_init_directory_entry(struct r_bin_mdmp_obj *obj, struct m
|
||||
/* TODO: Not yet fully parsed or utilised */
|
||||
break;
|
||||
case MODULE_LIST_STREAM:
|
||||
r = r_buf_read_at (obj->b, entry->location.rva, (ut8 *)&module_list, sizeof (module_list));
|
||||
if (r != sizeof (module_list)) {
|
||||
break;
|
||||
}
|
||||
module_list.number_of_modules = r_buf_read_le32_at (obj->b, entry->location.rva);
|
||||
|
||||
sdb_set (obj->kv, "mdmp_module.format", "qddtd???qq "
|
||||
"BaseOfImage SizeOfImage CheckSum "
|
||||
@ -425,10 +481,7 @@ static bool r_bin_mdmp_init_directory_entry(struct r_bin_mdmp_obj *obj, struct m
|
||||
if (!module) {
|
||||
break;
|
||||
}
|
||||
r = r_buf_read_at (obj->b, offset, (ut8 *)module, sizeof (*module));
|
||||
if (r != sizeof (*module)) {
|
||||
break;
|
||||
}
|
||||
read_module (obj->b, offset, module);
|
||||
r_list_append (obj->streams.modules, module);
|
||||
offset += sizeof (*module);
|
||||
}
|
||||
@ -546,10 +599,7 @@ static bool r_bin_mdmp_init_directory_entry(struct r_bin_mdmp_obj *obj, struct m
|
||||
}
|
||||
break;
|
||||
case MEMORY_64_LIST_STREAM:
|
||||
r = r_buf_read_at (obj->b, entry->location.rva, (ut8 *)&memory64_list, sizeof (memory64_list));
|
||||
if (r != sizeof (memory64_list)) {
|
||||
break;
|
||||
}
|
||||
read_memory64_list (obj->b, entry->location.rva, &memory64_list);
|
||||
|
||||
sdb_num_set (obj->kv, "mdmp_memory64_list.offset",
|
||||
entry->location.rva, 0);
|
||||
@ -567,10 +617,7 @@ static bool r_bin_mdmp_init_directory_entry(struct r_bin_mdmp_obj *obj, struct m
|
||||
if (!desc) {
|
||||
break;
|
||||
}
|
||||
r = r_buf_read_at (obj->b, offset, (ut8 *)desc, sizeof (*desc));
|
||||
if (r != sizeof (*desc)) {
|
||||
break;
|
||||
}
|
||||
read_desc (obj->b, offset, desc);
|
||||
r_list_append (obj->streams.memories64.memories, desc);
|
||||
offset += sizeof (*desc);
|
||||
}
|
||||
@ -830,6 +877,18 @@ static bool r_bin_mdmp_init_directory_entry(struct r_bin_mdmp_obj *obj, struct m
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool read_entry (RBuffer *b, ut64 addr, struct minidump_directory *entry) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return false;
|
||||
}
|
||||
entry->stream_type = r_buf_read_le32 (b);
|
||||
entry->location.data_size = r_buf_read_le32 (b);
|
||||
entry->location.rva = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool r_bin_mdmp_init_directory(struct r_bin_mdmp_obj *obj) {
|
||||
ut32 i;
|
||||
struct minidump_directory entry;
|
||||
@ -850,8 +909,7 @@ static bool r_bin_mdmp_init_directory(struct r_bin_mdmp_obj *obj) {
|
||||
/* Parse each entry in the directory */
|
||||
for (i = 0; i < max_entries; i++) {
|
||||
ut32 delta = i * sizeof (struct minidump_directory);
|
||||
int r = r_buf_read_at (obj->b, rvadir + delta, (ut8*) &entry, sizeof (struct minidump_directory));
|
||||
if (r) {
|
||||
if (read_entry (obj->b, rvadir + delta, &entry)) {
|
||||
if (!r_bin_mdmp_init_directory_entry (obj, &entry)) {
|
||||
return false;
|
||||
}
|
||||
@ -866,16 +924,16 @@ static bool r_bin_mdmp_patch_pe_headers(RBuffer *pe_buf) {
|
||||
Pe64_image_dos_header dos_hdr;
|
||||
Pe64_image_nt_headers nt_hdr;
|
||||
|
||||
r_buf_read_at (pe_buf, 0, (ut8 *)&dos_hdr, sizeof (Pe64_image_dos_header));
|
||||
r_buf_read_at (pe_buf, dos_hdr.e_lfanew, (ut8 *)&nt_hdr, sizeof (Pe64_image_nt_headers));
|
||||
Pe64_read_dos_header (pe_buf, &dos_hdr);
|
||||
Pe64_read_nt_headers (pe_buf, dos_hdr.e_lfanew, &nt_hdr);
|
||||
|
||||
/* Patch RawData in headers */
|
||||
ut64 sect_hdrs_off = dos_hdr.e_lfanew + 4 + sizeof (Pe64_image_file_header) + nt_hdr.file_header.SizeOfOptionalHeader;
|
||||
Pe64_image_section_header section_hdr;
|
||||
for (i = 0; i < nt_hdr.file_header.NumberOfSections; i++) {
|
||||
r_buf_read_at (pe_buf, sect_hdrs_off + i * sizeof (section_hdr), (ut8 *)§ion_hdr, sizeof (section_hdr));
|
||||
Pe64_read_image_section_header (pe_buf, sect_hdrs_off + i * sizeof (section_hdr), §ion_hdr);
|
||||
section_hdr.PointerToRawData = section_hdr.VirtualAddress;
|
||||
r_buf_write_at (pe_buf, sect_hdrs_off + i * sizeof (section_hdr), (const ut8 *)§ion_hdr, sizeof (section_hdr));
|
||||
Pe64_write_image_section_header (pe_buf, sect_hdrs_off + i * sizeof (section_hdr), §ion_hdr);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -460,8 +460,8 @@ static int bin_pe_parse_imports(struct PE_(r_bin_pe_obj_t)* bin,
|
||||
if (off + i * sizeof(PE_DWord) > bin->size) {
|
||||
break;
|
||||
}
|
||||
len = r_buf_read_at (bin->b, off + i * sizeof (PE_DWord), (ut8*) &import_table, sizeof (PE_DWord));
|
||||
if (len != sizeof (PE_DWord)) {
|
||||
import_table = R_BUF_READ_PE_DWORD_AT (bin->b, off + i * sizeof (PE_DWord));
|
||||
if (import_table == PE_DWORD_MAX) {
|
||||
bprintf ("Warning: read (import table)\n");
|
||||
goto error;
|
||||
} else if (import_table) {
|
||||
@ -517,8 +517,8 @@ static int bin_pe_parse_imports(struct PE_(r_bin_pe_obj_t)* bin,
|
||||
bprintf ("Warning: off > bin->size\n");
|
||||
goto error;
|
||||
}
|
||||
len = r_buf_read_at (bin->b, off, (ut8*) &import_hint, sizeof (PE_Word));
|
||||
if (len != sizeof (PE_Word)) {
|
||||
import_hint = r_buf_read_le16_at (bin->b, off);
|
||||
if (import_hint == UT16_MAX) {
|
||||
bprintf ("Warning: read import hint at 0x%08"PFMT64x "\n", off);
|
||||
goto error;
|
||||
}
|
||||
@ -574,7 +574,7 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int read_dos_header(RBuffer *b, PE_(image_dos_header) *header) {
|
||||
int PE_(read_dos_header)(RBuffer *b, PE_(image_dos_header) *header) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, 0, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
@ -609,7 +609,7 @@ static int read_dos_header(RBuffer *b, PE_(image_dos_header) *header) {
|
||||
return sizeof (PE_(image_dos_header));
|
||||
}
|
||||
|
||||
static int read_nt_headers(RBuffer *b, ut64 addr, PE_(image_nt_headers) *headers) {
|
||||
int PE_(read_nt_headers)(RBuffer *b, ut64 addr, PE_(image_nt_headers) *headers) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
@ -679,7 +679,7 @@ static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
r_sys_perror ("malloc (dos header)");
|
||||
return false;
|
||||
}
|
||||
if (read_dos_header (bin->b, bin->dos_header) < 0) {
|
||||
if (PE_(read_dos_header) (bin->b, bin->dos_header) < 0) {
|
||||
bprintf ("Warning: read (dos header)\n");
|
||||
return false;
|
||||
}
|
||||
@ -697,7 +697,7 @@ static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
return false;
|
||||
}
|
||||
bin->nt_header_offset = bin->dos_header->e_lfanew;
|
||||
if (read_nt_headers (bin->b, bin->dos_header->e_lfanew, bin->nt_headers) < 0) {
|
||||
if (PE_(read_nt_headers) (bin->b, bin->dos_header->e_lfanew, bin->nt_headers) < 0) {
|
||||
bprintf ("Warning: read (nt header)\n");
|
||||
return false;
|
||||
}
|
||||
@ -875,6 +875,40 @@ static struct r_bin_pe_export_t* parse_symbol_table(struct PE_(r_bin_pe_obj_t)*
|
||||
return exports;
|
||||
}
|
||||
|
||||
int PE_(read_image_section_header)(RBuffer *b, ut64 addr, PE_(image_section_header) *section_header) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
r_buf_read (b, section_header->Name, PE_IMAGE_SIZEOF_SHORT_NAME);
|
||||
section_header->Misc.PhysicalAddress = r_buf_read_le32 (b);
|
||||
section_header->VirtualAddress = r_buf_read_le32 (b);
|
||||
section_header->SizeOfRawData = r_buf_read_le32 (b);
|
||||
section_header->PointerToRawData = r_buf_read_le32 (b);
|
||||
section_header->PointerToRelocations = r_buf_read_le32 (b);
|
||||
section_header->PointerToLinenumbers = r_buf_read_le32 (b);
|
||||
section_header->NumberOfRelocations = r_buf_read_le16 (b);
|
||||
section_header->NumberOfLinenumbers = r_buf_read_le16 (b);
|
||||
section_header->Characteristics = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_section_header));
|
||||
}
|
||||
|
||||
void PE_(write_image_section_header)(RBuffer *b, ut64 addr, PE_(image_section_header) *section_header) {
|
||||
ut8 buf[sizeof (PE_(image_section_header))];
|
||||
memcpy (buf, section_header->Name, PE_IMAGE_SIZEOF_SHORT_NAME);
|
||||
r_write_at_le32 (buf, section_header->Misc.PhysicalAddress, PE_IMAGE_SIZEOF_SHORT_NAME);
|
||||
r_write_at_le32 (buf, section_header->VirtualAddress, PE_IMAGE_SIZEOF_SHORT_NAME + 4);
|
||||
r_write_at_le32 (buf, section_header->SizeOfRawData, PE_IMAGE_SIZEOF_SHORT_NAME + 8);
|
||||
r_write_at_le32 (buf, section_header->PointerToRawData, PE_IMAGE_SIZEOF_SHORT_NAME + 12);
|
||||
r_write_at_le32 (buf, section_header->PointerToRelocations, PE_IMAGE_SIZEOF_SHORT_NAME + 16);
|
||||
r_write_at_le32 (buf, section_header->PointerToLinenumbers, PE_IMAGE_SIZEOF_SHORT_NAME + 20);
|
||||
r_write_at_le16 (buf, section_header->NumberOfRelocations, PE_IMAGE_SIZEOF_SHORT_NAME + 24);
|
||||
r_write_at_le16 (buf, section_header->NumberOfLinenumbers, PE_IMAGE_SIZEOF_SHORT_NAME + 26);
|
||||
r_write_at_le32 (buf, section_header->Characteristics, PE_IMAGE_SIZEOF_SHORT_NAME + 28);
|
||||
r_buf_write_at (b, addr, buf, sizeof (PE_(image_section_header)));
|
||||
}
|
||||
|
||||
static struct r_bin_pe_section_t* PE_(r_bin_pe_get_sections)(struct PE_(r_bin_pe_obj_t)* bin);
|
||||
static int bin_pe_init_sections(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
bin->num_sections = bin->nt_headers->file_header.NumberOfSections;
|
||||
@ -895,10 +929,14 @@ static int bin_pe_init_sections(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
}
|
||||
bin->section_header_offset = bin->dos_header->e_lfanew + 4 + sizeof (PE_(image_file_header)) +
|
||||
bin->nt_headers->file_header.SizeOfOptionalHeader;
|
||||
if (r_buf_read_at (bin->b, bin->section_header_offset, (ut8*) bin->section_header, sections_size) < 0) {
|
||||
bprintf ("Warning: read (sections)\n");
|
||||
R_FREE (bin->section_header);
|
||||
goto out_error;
|
||||
int i;
|
||||
for (i = 0; i < bin->num_sections; i++) {
|
||||
if (PE_(read_image_section_header) (bin->b, bin->section_header_offset + i * sizeof (PE_(image_section_header)),
|
||||
bin->section_header + i) < 0) {
|
||||
bprintf ("Warning: read (sections)\n");
|
||||
R_FREE (bin->section_header);
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
Each symbol table entry includes a name, storage class, type, value and section number.Short names (8 characters or fewer) are stored directly in the symbol table;
|
||||
@ -1286,6 +1324,34 @@ static int bin_pe_init_overlay(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_image_clr_header(RBuffer *b, ut64 addr, PE_(image_clr_header) *header) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
header->HeaderSize = r_buf_read_le32 (b);
|
||||
header->MajorRuntimeVersion = r_buf_read_le16 (b);
|
||||
header->MinorRuntimeVersion = r_buf_read_le16 (b);
|
||||
header->MetaDataDirectoryAddress = r_buf_read_le32 (b);
|
||||
header->MetaDataDirectorySize = r_buf_read_le32 (b);
|
||||
header->Flags = r_buf_read_le32 (b);
|
||||
header->EntryPointToken = r_buf_read_le32 (b);
|
||||
header->ResourcesDirectoryAddress = r_buf_read_le32 (b);
|
||||
header->ResourcesDirectorySize = r_buf_read_le32 (b);
|
||||
header->StrongNameSignatureAddress = r_buf_read_le32 (b);
|
||||
header->StrongNameSignatureSize = r_buf_read_le32 (b);
|
||||
header->CodeManagerTableAddress = r_buf_read_le32 (b);
|
||||
header->CodeManagerTableSize = r_buf_read_le32 (b);
|
||||
header->VTableFixupsAddress = r_buf_read_le32 (b);
|
||||
header->VTableFixupsSize = r_buf_read_le32 (b);
|
||||
header->ExportAddressTableJumpsAddress = r_buf_read_le32 (b);
|
||||
header->ExportAddressTableJumpsSize = r_buf_read_le32 (b);
|
||||
header->ManagedNativeHeaderAddress = r_buf_read_le32 (b);
|
||||
header->ManagedNativeHeaderSize = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_clr_header));
|
||||
}
|
||||
|
||||
static int bin_pe_init_clr_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
PE_(image_data_directory) * clr_dir = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
|
||||
PE_DWord image_clr_hdr_paddr = bin_pe_rva_to_paddr (bin, clr_dir->VirtualAddress);
|
||||
@ -1296,7 +1362,7 @@ static int bin_pe_init_clr_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
if (!clr_hdr) {
|
||||
return 0;
|
||||
}
|
||||
rr = r_buf_read_at (bin->b, image_clr_hdr_paddr, (ut8*) (clr_hdr), len);
|
||||
rr = read_image_clr_header (bin->b, image_clr_hdr_paddr, clr_hdr);
|
||||
|
||||
// printf("%x\n", clr_hdr->HeaderSize);
|
||||
|
||||
@ -1315,6 +1381,37 @@ static int bin_pe_init_clr_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_image_import_directory(RBuffer *b, ut64 addr, PE_(image_import_directory) *import_dir) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
import_dir->Characteristics = r_buf_read_le32 (b);
|
||||
import_dir->TimeDateStamp = r_buf_read_le32 (b);
|
||||
import_dir->ForwarderChain = r_buf_read_le32 (b);
|
||||
import_dir->Name = r_buf_read_le32 (b);
|
||||
import_dir->FirstThunk = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_import_directory));
|
||||
}
|
||||
|
||||
static int read_image_delay_import_directory(RBuffer *b, ut64 addr, PE_(image_delay_import_directory) *directory) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
directory->Attributes = r_buf_read_le32 (b);
|
||||
directory->Name = r_buf_read_le32 (b);
|
||||
directory->ModulePlugin = r_buf_read_le32 (b);
|
||||
directory->DelayImportAddressTable = r_buf_read_le32 (b);
|
||||
directory->DelayImportNameTable = r_buf_read_le32 (b);
|
||||
directory->BoundDelayImportTable = r_buf_read_le32 (b);
|
||||
directory->UnloadDelayImportTable = r_buf_read_le32 (b);
|
||||
directory->TimeStamp = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_delay_import_directory));
|
||||
}
|
||||
|
||||
static int bin_pe_init_imports(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
PE_(image_data_directory) * data_dir_import = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_IMPORT];
|
||||
PE_(image_data_directory) * data_dir_delay_import = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
|
||||
@ -1374,7 +1471,7 @@ static int bin_pe_init_imports(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
import_dir = new_import_dir;
|
||||
new_import_dir = NULL;
|
||||
curr_import_dir = import_dir + indx;
|
||||
if (r_buf_read_at (bin->b, import_dir_offset + indx * dir_size, (ut8*) (curr_import_dir), dir_size) <= 0) {
|
||||
if (read_image_import_directory (bin->b, import_dir_offset + indx * dir_size, curr_import_dir) <= 0) {
|
||||
bprintf ("Warning: read (import directory)\n");
|
||||
R_FREE (import_dir);
|
||||
break; //return false;
|
||||
@ -1413,8 +1510,8 @@ static int bin_pe_init_imports(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
}
|
||||
delay_import_dir = new_delay_import_dir;
|
||||
curr_delay_import_dir = delay_import_dir + (indx - 1);
|
||||
rr = r_buf_read_at (bin->b, delay_import_dir_offset + (indx - 1) * delay_import_size,
|
||||
(ut8 *)(curr_delay_import_dir), dir_size);
|
||||
rr = read_image_delay_import_directory (bin->b, delay_import_dir_offset + (indx - 1) * delay_import_size,
|
||||
curr_delay_import_dir);
|
||||
if (rr != dir_size) {
|
||||
bprintf ("Warning: read (delay import directory)\n");
|
||||
goto fail;
|
||||
@ -1432,6 +1529,26 @@ fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int read_image_export_directory(RBuffer *b, ut64 addr, PE_(image_export_directory) *export_dir) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
export_dir->Characteristics = r_buf_read_le32 (b);
|
||||
export_dir->TimeDateStamp = r_buf_read_le32 (b);
|
||||
export_dir->MajorVersion = r_buf_read_le16 (b);
|
||||
export_dir->MinorVersion = r_buf_read_le16 (b);
|
||||
export_dir->Name = r_buf_read_le32 (b);
|
||||
export_dir->Base = r_buf_read_le32 (b);
|
||||
export_dir->NumberOfFunctions = r_buf_read_le32 (b);
|
||||
export_dir->NumberOfNames = r_buf_read_le32 (b);
|
||||
export_dir->AddressOfFunctions = r_buf_read_le32 (b);
|
||||
export_dir->AddressOfNames = r_buf_read_le32 (b);
|
||||
export_dir->AddressOfOrdinals = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_export_directory));
|
||||
}
|
||||
|
||||
static int bin_pe_init_exports(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
PE_(image_data_directory) * data_dir_export = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
PE_DWord export_dir_paddr = bin_pe_rva_to_paddr (bin, data_dir_export->VirtualAddress);
|
||||
@ -1446,7 +1563,7 @@ static int bin_pe_init_exports(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
r_sys_perror ("malloc (export directory)");
|
||||
return false;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, export_dir_paddr, (ut8*) bin->export_directory, sizeof (PE_(image_export_directory))) < 0) {
|
||||
if (read_image_export_directory (bin->b, export_dir_paddr, bin->export_directory) < 0) {
|
||||
bprintf ("Warning: read (export directory)\n");
|
||||
R_FREE (bin->export_directory);
|
||||
return false;
|
||||
@ -1465,6 +1582,20 @@ static void _free_resource(r_pe_resource *rs) {
|
||||
}
|
||||
}
|
||||
|
||||
static int read_image_resource_directory(RBuffer *b, ut64 addr, Pe_image_resource_directory *dir) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
dir->Characteristics = r_buf_read_le32 (b);
|
||||
dir->TimeDateStamp = r_buf_read_le32 (b);
|
||||
dir->MajorVersion = r_buf_read_le16 (b);
|
||||
dir->MinorVersion = r_buf_read_le16 (b);
|
||||
dir->NumberOfNamedEntries = r_buf_read_le16 (b);
|
||||
dir->NumberOfIdEntries = r_buf_read_le16 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (Pe_image_resource_directory);
|
||||
}
|
||||
|
||||
static int bin_pe_init_resource(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
PE_(image_data_directory) * resource_dir = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_RESOURCE];
|
||||
@ -1481,8 +1612,7 @@ static int bin_pe_init_resource(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
r_sys_perror ("malloc (resource directory)");
|
||||
return false;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, resource_dir_paddr, (ut8*) bin->resource_directory,
|
||||
sizeof (*bin->resource_directory)) != sizeof (*bin->resource_directory)) {
|
||||
if (read_image_resource_directory (bin->b, resource_dir_paddr, bin->resource_directory) < 0) {
|
||||
bprintf ("Warning: read (resource directory)\n");
|
||||
R_FREE (bin->resource_directory);
|
||||
return false;
|
||||
@ -1498,7 +1628,8 @@ static void bin_pe_store_tls_callbacks(struct PE_(r_bin_pe_obj_t)* bin, PE_DWord
|
||||
char* key;
|
||||
|
||||
while (addressOfTLSCallback != 0) {
|
||||
if (r_buf_read_at (bin->b, callbacks, (ut8*) &addressOfTLSCallback, sizeof(addressOfTLSCallback)) != sizeof (addressOfTLSCallback)) {
|
||||
addressOfTLSCallback = R_BUF_READ_PE_DWORD_AT (bin->b, callbacks);
|
||||
if (addressOfTLSCallback == PE_DWORD_MAX) {
|
||||
bprintf ("Warning: read (tls_callback)\n");
|
||||
return;
|
||||
}
|
||||
@ -1524,13 +1655,28 @@ static void bin_pe_store_tls_callbacks(struct PE_(r_bin_pe_obj_t)* bin, PE_DWord
|
||||
}
|
||||
}
|
||||
|
||||
static int read_tls_directory(RBuffer *b, ut64 addr, PE_(image_tls_directory) *tls_directory) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
tls_directory->StartAddressOfRawData = r_buf_read_le32 (b);
|
||||
tls_directory->EndAddressOfRawData = r_buf_read_le32 (b);
|
||||
tls_directory->AddressOfIndex = r_buf_read_le32 (b);
|
||||
tls_directory->AddressOfCallBacks = r_buf_read_le32 (b);
|
||||
tls_directory->SizeOfZeroFill = r_buf_read_le32 (b);
|
||||
tls_directory->Characteristics = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_tls_directory));
|
||||
}
|
||||
|
||||
static int bin_pe_init_tls(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
PE_(image_tls_directory) * image_tls_directory;
|
||||
PE_(image_data_directory) * data_dir_tls = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_TLS];
|
||||
PE_DWord tls_paddr = bin_pe_rva_to_paddr (bin, data_dir_tls->VirtualAddress);
|
||||
|
||||
image_tls_directory = R_NEW0 (PE_(image_tls_directory));
|
||||
if (r_buf_read_at (bin->b, tls_paddr, (ut8*) image_tls_directory, sizeof (PE_(image_tls_directory))) != sizeof (PE_(image_tls_directory))) {
|
||||
if (read_tls_directory (bin->b, tls_paddr, image_tls_directory) < 0) {
|
||||
bprintf ("Warning: read (image_tls_directory)\n");
|
||||
free (image_tls_directory);
|
||||
return 0;
|
||||
@ -1628,19 +1774,19 @@ static Var* Pe_r_bin_pe_parse_var(struct PE_(r_bin_pe_obj_t)* bin, PE_DWord* cur
|
||||
bprintf ("Warning: calloc (Var)\n");
|
||||
return NULL;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &var->wLength, sizeof(var->wLength)) != sizeof(var->wLength)) {
|
||||
if ((var->wLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (Var wLength)\n");
|
||||
free_Var (var);
|
||||
return NULL;
|
||||
}
|
||||
*curAddr += sizeof(var->wLength);
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &var->wValueLength, sizeof(var->wValueLength)) != sizeof(var->wValueLength)) {
|
||||
if ((var->wValueLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (Var wValueLength)\n");
|
||||
free_Var (var);
|
||||
return NULL;
|
||||
}
|
||||
*curAddr += sizeof(var->wValueLength);
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &var->wType, sizeof(var->wType)) != sizeof(var->wType)) {
|
||||
if ((var->wType = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (Var wType)\n");
|
||||
free_Var (var);
|
||||
return NULL;
|
||||
@ -1698,14 +1844,14 @@ static VarFileInfo* Pe_r_bin_pe_parse_var_file_info(struct PE_(r_bin_pe_obj_t)*
|
||||
return NULL;
|
||||
}
|
||||
PE_DWord startAddr = *curAddr;
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &varFileInfo->wLength, sizeof(varFileInfo->wLength)) != sizeof(varFileInfo->wLength)) {
|
||||
if ((varFileInfo->wLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (VarFileInfo wLength)\n");
|
||||
free_VarFileInfo (varFileInfo);
|
||||
return NULL;
|
||||
}
|
||||
*curAddr += sizeof(varFileInfo->wLength);
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &varFileInfo->wValueLength, sizeof(varFileInfo->wValueLength)) != sizeof(varFileInfo->wValueLength)) {
|
||||
if ((varFileInfo->wValueLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (VarFileInfo wValueLength)\n");
|
||||
free_VarFileInfo (varFileInfo);
|
||||
return NULL;
|
||||
@ -1718,7 +1864,7 @@ static VarFileInfo* Pe_r_bin_pe_parse_var_file_info(struct PE_(r_bin_pe_obj_t)*
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &varFileInfo->wType, sizeof(varFileInfo->wType)) != sizeof(varFileInfo->wType)) {
|
||||
if ((varFileInfo->wType = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (VarFileInfo wType)\n");
|
||||
free_VarFileInfo (varFileInfo);
|
||||
return NULL;
|
||||
@ -1782,7 +1928,7 @@ static String* Pe_r_bin_pe_parse_string(struct PE_(r_bin_pe_obj_t)* bin, PE_DWor
|
||||
free_String (string);
|
||||
return NULL;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &string->wLength, sizeof(string->wLength)) != sizeof(string->wLength)) {
|
||||
if ((string->wLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (String wLength)\n");
|
||||
goto out_error;
|
||||
}
|
||||
@ -1790,7 +1936,7 @@ static String* Pe_r_bin_pe_parse_string(struct PE_(r_bin_pe_obj_t)* bin, PE_DWor
|
||||
if (*curAddr > bin->size || *curAddr + sizeof(string->wValueLength) > bin->size) {
|
||||
goto out_error;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &string->wValueLength, sizeof(string->wValueLength)) != sizeof(string->wValueLength)) {
|
||||
if ((string->wValueLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (String wValueLength)\n");
|
||||
goto out_error;
|
||||
}
|
||||
@ -1799,7 +1945,7 @@ static String* Pe_r_bin_pe_parse_string(struct PE_(r_bin_pe_obj_t)* bin, PE_DWor
|
||||
if (*curAddr > bin->size || *curAddr + sizeof(string->wType) > bin->size) {
|
||||
goto out_error;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &string->wType, sizeof(string->wType)) != sizeof(string->wType)) {
|
||||
if ((string->wType = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (String wType)\n");
|
||||
goto out_error;
|
||||
}
|
||||
@ -1865,14 +2011,14 @@ static StringTable* Pe_r_bin_pe_parse_string_table(struct PE_(r_bin_pe_obj_t)* b
|
||||
}
|
||||
|
||||
PE_DWord startAddr = *curAddr;
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &stringTable->wLength, sizeof(stringTable->wLength)) != sizeof(stringTable->wLength)) {
|
||||
if ((stringTable->wLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (StringTable wLength)\n");
|
||||
free_StringTable (stringTable);
|
||||
return NULL;
|
||||
}
|
||||
*curAddr += sizeof(stringTable->wLength);
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &stringTable->wValueLength, sizeof(stringTable->wValueLength)) != sizeof(stringTable->wValueLength)) {
|
||||
if ((stringTable->wValueLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (StringTable wValueLength)\n");
|
||||
free_StringTable (stringTable);
|
||||
return NULL;
|
||||
@ -1885,7 +2031,7 @@ static StringTable* Pe_r_bin_pe_parse_string_table(struct PE_(r_bin_pe_obj_t)* b
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &stringTable->wType, sizeof(stringTable->wType)) != sizeof(stringTable->wType)) {
|
||||
if ((stringTable->wType = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (StringTable wType)\n");
|
||||
free_StringTable (stringTable);
|
||||
return NULL;
|
||||
@ -1945,14 +2091,14 @@ static StringFileInfo* Pe_r_bin_pe_parse_string_file_info(struct PE_(r_bin_pe_ob
|
||||
|
||||
PE_DWord startAddr = *curAddr;
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &stringFileInfo->wLength, sizeof(stringFileInfo->wLength)) != sizeof(stringFileInfo->wLength)) {
|
||||
if ((stringFileInfo->wLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (StringFileInfo wLength)\n");
|
||||
free_StringFileInfo (stringFileInfo);
|
||||
return NULL;
|
||||
}
|
||||
*curAddr += sizeof(stringFileInfo->wLength);
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &stringFileInfo->wValueLength, sizeof(stringFileInfo->wValueLength)) != sizeof(stringFileInfo->wValueLength)) {
|
||||
if ((stringFileInfo->wValueLength = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (StringFileInfo wValueLength)\n");
|
||||
free_StringFileInfo (stringFileInfo);
|
||||
return NULL;
|
||||
@ -1965,7 +2111,7 @@ static StringFileInfo* Pe_r_bin_pe_parse_string_file_info(struct PE_(r_bin_pe_ob
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r_buf_read_at (bin->b, *curAddr, (ut8*) &stringFileInfo->wType, sizeof(stringFileInfo->wType)) != sizeof(stringFileInfo->wType)) {
|
||||
if ((stringFileInfo->wType = r_buf_read_le16_at (bin->b, *curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (StringFileInfo wType)\n");
|
||||
free_StringFileInfo (stringFileInfo);
|
||||
return NULL;
|
||||
@ -2044,19 +2190,19 @@ static PE_VS_VERSIONINFO* Pe_r_bin_pe_parse_version_info(struct PE_(r_bin_pe_obj
|
||||
//Mb we are in subsequent version resource data and not aligned.
|
||||
sz = sizeof(ut16);
|
||||
EXIT_ON_OVERFLOW (sz);
|
||||
if (r_buf_read_at (bin->b, curAddr, (ut8*) &vs_VersionInfo->wLength, sz) != sz) {
|
||||
if ((vs_VersionInfo->wLength = r_buf_read_le16_at (bin->b, curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (VS_VERSIONINFO wLength)\n");
|
||||
goto out_error;
|
||||
}
|
||||
curAddr += sz;
|
||||
EXIT_ON_OVERFLOW (sz);
|
||||
if (r_buf_read_at (bin->b, curAddr, (ut8*) &vs_VersionInfo->wValueLength, sz) != sz) {
|
||||
if ((vs_VersionInfo->wValueLength = r_buf_read_le16_at (bin->b, curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (VS_VERSIONINFO wValueLength)\n");
|
||||
goto out_error;
|
||||
}
|
||||
curAddr += sz;
|
||||
EXIT_ON_OVERFLOW (sz);
|
||||
if (r_buf_read_at (bin->b, curAddr, (ut8*) &vs_VersionInfo->wType, sz) != sz) {
|
||||
if ((vs_VersionInfo->wType = r_buf_read_le16_at (bin->b, curAddr)) == UT16_MAX) {
|
||||
bprintf ("Warning: read (VS_VERSIONINFO wType)\n");
|
||||
goto out_error;
|
||||
}
|
||||
@ -2765,6 +2911,30 @@ static char* _resource_type_str(int type) {
|
||||
return strdup (typeName);
|
||||
}
|
||||
|
||||
static int read_image_resource_directory_entry(RBuffer *b, ut64 addr, Pe_image_resource_directory_entry *entry) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
entry->u1.Name = r_buf_read_le32 (b);
|
||||
entry->u2.OffsetToData = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (Pe_image_resource_directory_entry);
|
||||
}
|
||||
|
||||
static int read_image_resource_data_entry(RBuffer *b, ut64 addr, Pe_image_resource_data_entry *entry) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
entry->OffsetToData = r_buf_read_le32 (b);
|
||||
entry->Size = r_buf_read_le32 (b);
|
||||
entry->CodePage = r_buf_read_le32 (b);
|
||||
entry->Reserved = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (Pe_image_resource_data_entry);
|
||||
}
|
||||
|
||||
static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_resource_directory *dir, ut64 offDir, int type, int id, HtUU *dirs, const char *resource_name) {
|
||||
char *resourceEntryName = NULL;
|
||||
int index = 0;
|
||||
@ -2784,14 +2954,15 @@ static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_
|
||||
if (off > bin->size || off + sizeof (entry) > bin->size) {
|
||||
break;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, off, (ut8*)&entry, sizeof(entry)) < 1) {
|
||||
if (read_image_resource_directory_entry (bin->b, off, &entry) < 0) {
|
||||
eprintf ("Warning: read resource entry\n");
|
||||
break;
|
||||
}
|
||||
if (entry.u1.s.NameIsString) {
|
||||
if (entry.u1.Name >> 31) {
|
||||
int i;
|
||||
ut16 buf;
|
||||
if (r_buf_read_at (bin->b, bin->resource_directory_offset + entry.u1.s.NameOffset, (ut8*)&buf, sizeof (ut16)) != sizeof (ut16)) {
|
||||
ut32 NameOffset = entry.u1.Name & 0x7fffffff;
|
||||
if (r_buf_read_at (bin->b, bin->resource_directory_offset + NameOffset, (ut8*)&buf, sizeof (ut16)) != sizeof (ut16)) {
|
||||
break;
|
||||
}
|
||||
ut16 resourceEntryNameLength = r_read_le16 (&buf);
|
||||
@ -2799,7 +2970,7 @@ static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_
|
||||
if (resourceEntryName) {
|
||||
for (i = 0; i < resourceEntryNameLength; i++) { /* Convert Unicode to ASCII */
|
||||
ut8 byte;
|
||||
int r = r_buf_read_at (bin->b, bin->resource_directory_offset + entry.u1.s.NameOffset + 2 + (i*2), &byte, sizeof (ut8));
|
||||
int r = r_buf_read_at (bin->b, bin->resource_directory_offset + NameOffset + 2 + (i*2), &byte, sizeof (ut8));
|
||||
if (r != sizeof (ut8) || !byte) {
|
||||
R_FREE (resourceEntryName);
|
||||
break;
|
||||
@ -2808,15 +2979,16 @@ static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entry.u2.s.DataIsDirectory) {
|
||||
if (entry.u2.OffsetToData >> 31) {
|
||||
//detect here malicious file trying to making us infinite loop
|
||||
Pe_image_resource_directory identEntry;
|
||||
off = rsrc_base + entry.u2.s.OffsetToDirectory;
|
||||
int len = r_buf_read_at (bin->b, off, (ut8*) &identEntry, sizeof (identEntry));
|
||||
ut32 OffsetToDirectory = entry.u2.OffsetToData & 0x7fffffff;
|
||||
off = rsrc_base + OffsetToDirectory;
|
||||
int len = read_image_resource_directory (bin->b, off, &identEntry);
|
||||
if (len < 1 || len != sizeof (Pe_image_resource_directory)) {
|
||||
eprintf ("Warning: parsing resource directory\n");
|
||||
}
|
||||
_parse_resource_directory (bin, &identEntry, entry.u2.s.OffsetToDirectory, type, entry.u1.Id, dirs, resourceEntryName);
|
||||
_parse_resource_directory (bin, &identEntry, OffsetToDirectory, type, entry.u1.Name & 0xffff, dirs, resourceEntryName);
|
||||
R_FREE (resourceEntryName);
|
||||
continue;
|
||||
}
|
||||
@ -2831,7 +3003,7 @@ static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_
|
||||
free (data);
|
||||
break;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, off, (ut8*)data, sizeof (*data)) != sizeof (*data)) {
|
||||
if (read_image_resource_data_entry (bin->b, off, data) != sizeof (*data)) {
|
||||
eprintf ("Warning: read (resource data entry)\n");
|
||||
free (data);
|
||||
break;
|
||||
@ -2959,18 +3131,19 @@ R_API void PE_(bin_pe_parse_resource)(struct PE_(r_bin_pe_obj_t) *bin) {
|
||||
if (off > bin->size || off + sizeof(typeEntry) > bin->size) {
|
||||
break;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, off, (ut8*)&typeEntry, sizeof(typeEntry)) < 1) {
|
||||
eprintf ("Warning: read resource directory entry\n");
|
||||
if (read_image_resource_directory_entry (bin->b, off, &typeEntry) < 0) {
|
||||
eprintf ("Warning: read resource directory entry\n");
|
||||
break;
|
||||
}
|
||||
if (typeEntry.u2.s.DataIsDirectory) {
|
||||
if (typeEntry.u2.OffsetToData >> 31) {
|
||||
Pe_image_resource_directory identEntry;
|
||||
off = rsrc_base + typeEntry.u2.s.OffsetToDirectory;
|
||||
int len = r_buf_read_at (bin->b, off, (ut8*)&identEntry, sizeof(identEntry));
|
||||
if (len < 1 || len != sizeof (identEntry)) {
|
||||
ut32 OffsetToDirectory = typeEntry.u2.OffsetToData & 0x7fffffff;
|
||||
off = rsrc_base + OffsetToDirectory;
|
||||
int len = read_image_resource_directory (bin->b, off, &identEntry);
|
||||
if (len != sizeof (identEntry)) {
|
||||
eprintf ("Warning: parsing resource directory\n");
|
||||
}
|
||||
(void)_parse_resource_directory (bin, &identEntry, typeEntry.u2.s.OffsetToDirectory, typeEntry.u1.Id, 0, dirs, NULL);
|
||||
(void)_parse_resource_directory (bin, &identEntry, OffsetToDirectory, typeEntry.u1.Name & 0xffff, 0, dirs, NULL);
|
||||
}
|
||||
}
|
||||
ht_uu_free (dirs);
|
||||
@ -3301,7 +3474,7 @@ struct r_bin_pe_export_t* PE_(r_bin_pe_get_exports)(struct PE_(r_bin_pe_obj_t)*
|
||||
if (i == fo) {
|
||||
function_ordinal = fo;
|
||||
// get the VA of export name from AddressOfNames
|
||||
r_buf_read_at (bin->b, names_paddr + n * sizeof (PE_VWord), (ut8*) &name_vaddr, sizeof (PE_VWord));
|
||||
name_vaddr = r_buf_read_le32_at (bin->b, names_paddr + n * sizeof (PE_VWord));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3467,6 +3640,23 @@ static int get_debug_info(struct PE_(r_bin_pe_obj_t)* bin, PE_(image_debug_direc
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_image_debug_directory_entry(RBuffer *b, ut64 addr, PE_(image_debug_directory_entry) *entry) {
|
||||
st64 o_addr = r_buf_seek (b, 0, R_BUF_CUR);
|
||||
if (r_buf_seek (b, addr, R_BUF_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
entry->Characteristics = r_buf_read_le32 (b);
|
||||
entry->TimeDateStamp = r_buf_read_le32 (b);
|
||||
entry->MajorVersion = r_buf_read_le16 (b);
|
||||
entry->MinorVersion = r_buf_read_le16 (b);
|
||||
entry->Type = r_buf_read_le32 (b);
|
||||
entry->SizeOfData = r_buf_read_le32 (b);
|
||||
entry->AddressOfRawData = r_buf_read_le32 (b);
|
||||
entry->PointerToRawData = r_buf_read_le32 (b);
|
||||
r_buf_seek (b, o_addr, R_BUF_SET);
|
||||
return sizeof (PE_(image_debug_directory_entry));
|
||||
}
|
||||
|
||||
int PE_(r_bin_pe_get_debug_data)(struct PE_(r_bin_pe_obj_t)* bin, SDebugInfo* res) {
|
||||
PE_(image_debug_directory_entry) img_dbg_dir_entry;
|
||||
PE_(image_data_directory) * dbg_dir;
|
||||
@ -3484,7 +3674,7 @@ int PE_(r_bin_pe_get_debug_data)(struct PE_(r_bin_pe_obj_t)* bin, SDebugInfo* re
|
||||
if (dbg_dir_offset >= r_buf_size (bin->b)) {
|
||||
return false;
|
||||
}
|
||||
r_buf_read_at (bin->b, dbg_dir_offset, (ut8 *)&img_dbg_dir_entry, sizeof (img_dbg_dir_entry));
|
||||
read_image_debug_directory_entry (bin->b, dbg_dir_offset, &img_dbg_dir_entry);
|
||||
if ((r_buf_size (bin->b) - dbg_dir_offset) < sizeof (PE_(image_debug_directory_entry))) {
|
||||
return false;
|
||||
}
|
||||
@ -3530,8 +3720,8 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t)*
|
||||
if (off + sizeof(PE_(image_import_directory)) > bin->size) {
|
||||
return NULL;
|
||||
}
|
||||
int r = r_buf_read_at (bin->b, bin->import_directory_offset + idi * sizeof (curr_import_dir),
|
||||
(ut8 *)&curr_import_dir, sizeof (curr_import_dir));
|
||||
int r = read_image_import_directory (bin->b, bin->import_directory_offset +
|
||||
idi * sizeof (curr_import_dir), &curr_import_dir);
|
||||
if (r < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -3561,7 +3751,7 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t)*
|
||||
goto beach;
|
||||
}
|
||||
dll_name[bin->size - paddr] = '\0';
|
||||
}else {
|
||||
} else {
|
||||
rr = r_buf_read_at (bin->b, paddr, (ut8*) dll_name, PE_NAME_LENGTH);
|
||||
if (rr != PE_NAME_LENGTH) {
|
||||
goto beach;
|
||||
@ -3574,8 +3764,8 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t)*
|
||||
break;
|
||||
}
|
||||
idi++;
|
||||
r = r_buf_read_at (bin->b, bin->import_directory_offset + idi * sizeof (curr_import_dir),
|
||||
(ut8 *)&curr_import_dir, sizeof (curr_import_dir));
|
||||
r = read_image_import_directory (bin->b, bin->import_directory_offset +
|
||||
idi * sizeof (curr_import_dir), &curr_import_dir);
|
||||
if (r < 0) {
|
||||
free (imports);
|
||||
return NULL;
|
||||
@ -3588,8 +3778,8 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t)*
|
||||
if (off + sizeof(PE_(image_delay_import_directory)) > bin->size) {
|
||||
goto beach;
|
||||
}
|
||||
int r = r_buf_read_at (bin->b, off + didi * sizeof (curr_delay_import_dir),
|
||||
(ut8 *)&curr_delay_import_dir, sizeof (curr_delay_import_dir));
|
||||
int r = read_image_delay_import_directory (bin->b, off + didi * sizeof (curr_delay_import_dir),
|
||||
&curr_delay_import_dir);
|
||||
if (r != sizeof (curr_delay_import_dir)) {
|
||||
goto beach;
|
||||
}
|
||||
@ -3617,8 +3807,8 @@ struct r_bin_pe_import_t* PE_(r_bin_pe_get_imports)(struct PE_(r_bin_pe_obj_t)*
|
||||
break;
|
||||
}
|
||||
didi++;
|
||||
r = r_buf_read_at (bin->b, off + didi * sizeof (curr_delay_import_dir),
|
||||
(ut8 *)&curr_delay_import_dir, sizeof (curr_delay_import_dir));
|
||||
r = read_image_delay_import_directory (bin->b, off + didi * sizeof (curr_delay_import_dir),
|
||||
&curr_delay_import_dir);
|
||||
if (r != sizeof (curr_delay_import_dir)) {
|
||||
goto beach;
|
||||
}
|
||||
@ -3671,8 +3861,8 @@ struct r_bin_pe_lib_t* PE_(r_bin_pe_get_libs)(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
if (off + sizeof (PE_(image_import_directory)) > bin->size) {
|
||||
goto out_error;
|
||||
}
|
||||
int r = r_buf_read_at (bin->b, off + iidi * sizeof (curr_import_dir),
|
||||
(ut8 *)&curr_import_dir, sizeof (curr_import_dir));
|
||||
int r = read_image_import_directory (bin->b, off + iidi * sizeof (curr_import_dir),
|
||||
&curr_import_dir);
|
||||
last = off + bin->import_directory_size;
|
||||
while (r == sizeof (curr_import_dir) && off + (iidi + 1) * sizeof (curr_import_dir) <= last && (
|
||||
curr_import_dir.FirstThunk || curr_import_dir.Name ||
|
||||
@ -3705,8 +3895,8 @@ struct r_bin_pe_lib_t* PE_(r_bin_pe_get_libs)(struct PE_(r_bin_pe_obj_t)* bin) {
|
||||
}
|
||||
next:
|
||||
iidi++;
|
||||
r = r_buf_read_at (bin->b, off + iidi * sizeof (curr_import_dir),
|
||||
(ut8 *)&curr_import_dir, sizeof (curr_import_dir));
|
||||
r = read_image_import_directory (bin->b, off + iidi * sizeof (curr_import_dir),
|
||||
&curr_import_dir);
|
||||
}
|
||||
}
|
||||
off = bin->delay_import_directory_offset;
|
||||
@ -3715,7 +3905,7 @@ next:
|
||||
if (off + sizeof(PE_(image_delay_import_directory)) > bin->size) {
|
||||
goto out_error;
|
||||
}
|
||||
int r = r_buf_read_at (bin->b, off, (ut8 *)&curr_delay_import_dir, sizeof (curr_delay_import_dir));
|
||||
int r = read_image_delay_import_directory (bin->b, off, &curr_delay_import_dir);
|
||||
if (r != sizeof (curr_delay_import_dir)) {
|
||||
goto out_error;
|
||||
}
|
||||
@ -3747,8 +3937,8 @@ next:
|
||||
}
|
||||
}
|
||||
did++;
|
||||
r = r_buf_read_at (bin->b, off + did * sizeof (curr_delay_import_dir),
|
||||
(ut8 *)&curr_delay_import_dir, sizeof (curr_delay_import_dir));
|
||||
r = read_image_delay_import_directory (bin->b, off + did * sizeof (curr_delay_import_dir),
|
||||
&curr_delay_import_dir);
|
||||
}
|
||||
}
|
||||
sdb_ht_free (lib_map);
|
||||
|
@ -6,6 +6,8 @@
|
||||
#undef PE_Word
|
||||
#undef PE_DWord
|
||||
#undef PE_VWord
|
||||
#undef R_BUF_READ_PE_DWORD_AT
|
||||
#undef PE_DWORD_MAX
|
||||
|
||||
#ifdef R_BIN_PE64
|
||||
#define PE_(name) Pe64_ ## name
|
||||
@ -14,6 +16,8 @@
|
||||
#define PE_Word ut16
|
||||
#define PE_DWord ut64
|
||||
#define PE_VWord ut32
|
||||
#define R_BUF_READ_PE_DWORD_AT r_buf_read_le64_at
|
||||
#define PE_DWORD_MAX UT64_MAX
|
||||
#else
|
||||
#define PE_(name) Pe32_ ## name
|
||||
#define ILT_MASK1 0x80000000
|
||||
@ -21,6 +25,8 @@
|
||||
#define PE_Word ut16
|
||||
#define PE_DWord ut32
|
||||
#define PE_VWord ut32
|
||||
#define R_BUF_READ_PE_DWORD_AT r_buf_read_le32_at
|
||||
#define PE_DWORD_MAX UT32_MAX
|
||||
#endif
|
||||
|
||||
#ifndef _INCLUDE_R_BIN_PE_SPECS_H_
|
||||
@ -496,19 +502,19 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
ut32 NameOffset: 31;
|
||||
ut32 NameIsString: 1;
|
||||
} s;
|
||||
// struct {
|
||||
// ut32 NameOffset: 31;
|
||||
// ut32 NameIsString: 1;
|
||||
// } s;
|
||||
// ut16 Id;
|
||||
ut32 Name;
|
||||
ut16 Id;
|
||||
} u1;
|
||||
union {
|
||||
// struct {
|
||||
// ut32 OffsetToDirectory: 31;
|
||||
// ut32 DataIsDirectory: 1;
|
||||
// } s;
|
||||
ut32 OffsetToData;
|
||||
struct {
|
||||
ut32 OffsetToDirectory: 31;
|
||||
ut32 DataIsDirectory: 1;
|
||||
} s;
|
||||
} u2;
|
||||
} Pe_image_resource_directory_entry;
|
||||
|
||||
@ -776,4 +782,14 @@ typedef struct {
|
||||
PE64_SCOPE_RECORD ScopeRecord[];
|
||||
} PE64_SCOPE_TABLE;
|
||||
|
||||
int Pe32_read_dos_header(RBuffer *b, Pe32_image_dos_header *header);
|
||||
int Pe32_read_nt_headers(RBuffer *b, ut64 addr, Pe32_image_nt_headers *headers);
|
||||
int Pe32_read_image_section_header(RBuffer *b, ut64 addr, Pe32_image_section_header *section_header);
|
||||
void Pe32_write_image_section_header(RBuffer *b, ut64 addr, Pe32_image_section_header *section_header);
|
||||
|
||||
int Pe64_read_dos_header(RBuffer *b, Pe64_image_dos_header *header);
|
||||
int Pe64_read_nt_headers(RBuffer *b, ut64 addr, Pe64_image_nt_headers *headers);
|
||||
int Pe64_read_image_section_header(RBuffer *b, ut64 addr, Pe64_image_section_header *section_header);
|
||||
void Pe64_write_image_section_header(RBuffer *b, ut64 addr, Pe64_image_section_header *section_header);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user