summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/perk/perk.h1
-rw-r--r--src/reader/pe_read_coff_header.c71
2 files changed, 72 insertions, 0 deletions
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;
+}