diff --git a/include/perk/perk.h b/include/perk/perk.h index 30cc47d..06892b5 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -198,6 +198,7 @@ perk_api int pe_get_image_framework (const struct pe_image_meta *, struct pe_in /* low-level api */ perk_api int pe_read_dos_header (const struct pe_raw_image_dos_hdr *, struct pe_meta_image_dos_hdr *); perk_api int pe_read_coff_header (const struct pe_raw_coff_image_hdr *, struct pe_meta_coff_file_hdr *); +perk_api int pe_read_object_header (const struct pe_raw_coff_object_hdr *, struct pe_meta_coff_file_hdr *); perk_api int pe_read_optional_header (const union pe_raw_opt_hdr *, struct pe_meta_opt_hdr *); perk_api int pe_read_section_header (const struct pe_raw_sec_hdr *, struct pe_meta_sec_hdr *); perk_api int pe_read_export_header (const struct pe_raw_export_hdr *, struct pe_meta_export_hdr *); diff --git a/src/reader/pe_read_coff_header.c b/src/reader/pe_read_coff_header.c index 524ec21..5df1967 100644 --- a/src/reader/pe_read_coff_header.c +++ b/src/reader/pe_read_coff_header.c @@ -33,3 +33,74 @@ int pe_read_coff_header(const struct pe_raw_coff_image_hdr * p, struct pe_meta_c return 0; } + +#define PE_IMAGE_FILE_CHARACTERISTICS (\ + PE_IMAGE_FILE_RELOCS_STRIPPED \ + | PE_IMAGE_FILE_EXECUTABLE_IMAGE \ + | PE_IMAGE_FILE_LINE_NUMS_STRIPPED \ + | PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED \ + | PE_IMAGE_FILE_AGGRESSIVE_WS_TRIM \ + | PE_IMAGE_FILE_LARGE_ADDRESS_AWARE \ + | PE_IMAGE_FILE_RESERVED_CHARACTERISTIC \ + | PE_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP \ + | PE_IMAGE_FILE_BYTES_REVERSED_LO \ + | PE_IMAGE_FILE_32BIT_MACHINE \ + | PE_IMAGE_FILE_DEBUG_STRIPPED \ + | PE_IMAGE_FILE_NET_RUN_FROM_SWAP \ + | PE_IMAGE_FILE_SYSTEM \ + | PE_IMAGE_FILE_DLL \ + | PE_IMAGE_FILE_UP_SYSTEM_ONLY \ + | PE_IMAGE_FILE_BYTES_REVERSED_HI) + +int pe_read_object_header(const struct pe_raw_coff_object_hdr * p, struct pe_meta_coff_file_hdr * m) +{ + if (pe_read_short(p->cfh_size_of_opt_hdr)) + return PERK_ERR_BAD_COFF_HEADER; + + if (pe_read_short(p->cfh_characteristics) & ~PE_IMAGE_FILE_CHARACTERISTICS) + return PERK_ERR_BAD_COFF_HEADER; + + switch (pe_read_short(p->cfh_machine)) { + case PE_IMAGE_FILE_MACHINE_I386: + case PE_IMAGE_FILE_MACHINE_R4000: + case PE_IMAGE_FILE_MACHINE_WCEMIPSV2: + case PE_IMAGE_FILE_MACHINE_SH3: + case PE_IMAGE_FILE_MACHINE_SH3DSP: + case PE_IMAGE_FILE_MACHINE_SH4: + case PE_IMAGE_FILE_MACHINE_SH5: + case PE_IMAGE_FILE_MACHINE_ARM: + case PE_IMAGE_FILE_MACHINE_THUMB: + case PE_IMAGE_FILE_MACHINE_ARMV7: + case PE_IMAGE_FILE_MACHINE_AM33: + case PE_IMAGE_FILE_MACHINE_POWERPC: + case PE_IMAGE_FILE_MACHINE_POWERPCFP: + case PE_IMAGE_FILE_MACHINE_IA64: + case PE_IMAGE_FILE_MACHINE_MIPS16: + case PE_IMAGE_FILE_MACHINE_MIPSFPU: + case PE_IMAGE_FILE_MACHINE_MIPSFPU16: + case PE_IMAGE_FILE_MACHINE_EBC: + case PE_IMAGE_FILE_MACHINE_AMD64: + case PE_IMAGE_FILE_MACHINE_M32R: + break; + + default: + return PERK_ERR_BAD_COFF_HEADER; + } + + m->cfh_signature[0] = 0; + m->cfh_signature[1] = 0; + m->cfh_signature[2] = 0; + m->cfh_signature[3] = 0; + + m->cfh_machine = pe_read_short(p->cfh_machine); + m->cfh_num_of_sections = pe_read_short(p->cfh_num_of_sections); + + m->cfh_time_date_stamp = pe_read_long(p->cfh_time_date_stamp); + m->cfh_ptr_to_sym_tbl = pe_read_long(p->cfh_ptr_to_sym_tbl); + m->cfh_num_of_syms = pe_read_long(p->cfh_num_of_syms); + + m->cfh_size_of_opt_hdr = pe_read_short(p->cfh_size_of_opt_hdr); + m->cfh_characteristics = pe_read_short(p->cfh_characteristics); + + return 0; +}