diff options
-rw-r--r-- | include/perk/perk.h | 12 | ||||
-rw-r--r-- | include/perk/perk_meta.h | 8 | ||||
-rw-r--r-- | include/perk/perk_secattr.h | 75 | ||||
-rw-r--r-- | project/common.mk | 9 | ||||
-rw-r--r-- | project/headers.mk | 1 | ||||
-rw-r--r-- | src/cmds/pe_cmd_perk.c | 8 | ||||
-rw-r--r-- | src/logic/pe_image_meta_data.c | 9 | ||||
-rw-r--r-- | src/output/pe_output_image_sections.c | 128 | ||||
-rw-r--r-- | src/output/pe_output_pecoff_category.c (renamed from src/output/pe_output_image_category.c) | 2 | ||||
-rw-r--r-- | src/output/pe_output_pecoff_sections.c | 223 | ||||
-rw-r--r-- | src/output/pe_output_pecoff_strings.c (renamed from src/output/pe_output_image_strings.c) | 2 | ||||
-rw-r--r-- | src/output/pe_output_pecoff_symbols.c (renamed from src/output/pe_output_image_symbols.c) | 46 | ||||
-rw-r--r-- | src/reader/pe_read_coff_reloc.c | 22 |
13 files changed, 389 insertions, 156 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h index 59b55e5..6d64f95 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -127,6 +127,7 @@ struct pe_raw_image; struct pe_raw_image_dos_hdr; struct pe_raw_coff_image_hdr; struct pe_raw_coff_object_hdr; +struct pe_raw_coff_reloc; union pe_raw_opt_hdr; struct pe_raw_sec_hdr; struct pe_raw_export_hdr; @@ -185,6 +186,7 @@ struct pe_image_meta { struct pe_meta_coff_symbol ** m_symvec_crc32; struct pe_meta_coff_symbol ** m_symvec_crc64; + struct pe_meta_coff_symbol ** m_symvec_symidx; struct pe_meta_export_hdr m_edata; struct pe_meta_import_hdr * m_idata; @@ -294,10 +296,10 @@ perk_api int pe_cmd_ar (const struct pe_driver_ctx *, u /* utility api */ perk_api int pe_main (char **, char **, const struct pe_fd_ctx *); -perk_api int pe_output_image_category (const struct pe_driver_ctx *, const struct pe_image_meta *); -perk_api int pe_output_image_sections (const struct pe_driver_ctx *, const struct pe_image_meta *); -perk_api int pe_output_image_symbols (const struct pe_driver_ctx *, const struct pe_image_meta *); -perk_api int pe_output_image_strings (const struct pe_driver_ctx *, const struct pe_image_meta *); +perk_api int pe_output_pecoff_category (const struct pe_driver_ctx *, const struct pe_image_meta *); +perk_api int pe_output_pecoff_sections (const struct pe_driver_ctx *, const struct pe_image_meta *); +perk_api int pe_output_pecoff_symbols (const struct pe_driver_ctx *, const struct pe_image_meta *); +perk_api int pe_output_pecoff_strings (const struct pe_driver_ctx *, const struct pe_image_meta *); perk_api int pe_output_export_symbols (const struct pe_driver_ctx *, const struct pe_image_meta *); perk_api int pe_output_import_libraries (const struct pe_driver_ctx *, const struct pe_image_meta *); perk_api int pe_output_mdso_libraries (const struct pe_driver_ctx *, const struct pe_image_meta *); @@ -352,10 +354,12 @@ perk_api int pe_read_optional_header (const union pe_raw_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 *); perk_api int pe_read_import_header (const struct pe_raw_import_hdr *, struct pe_meta_import_hdr *); +perk_api int pe_read_coff_reloc (const struct pe_raw_coff_reloc *, struct pe_meta_coff_reloc *); perk_api int pe_read_coff_symbol (const struct pe_raw_coff_symbol *, struct pe_meta_coff_symbol *, const struct pe_meta_coff_file_hdr *, void * base); + perk_api int pe_read_import_lookup (const unsigned char *, struct pe_meta_import_lookup *, uint32_t magic); diff --git a/include/perk/perk_meta.h b/include/perk/perk_meta.h index 5a4136f..2b6b0ef 100644 --- a/include/perk/perk_meta.h +++ b/include/perk/perk_meta.h @@ -196,6 +196,14 @@ struct pe_meta_sec_hdr { }; +/* section relocation record */ +struct pe_meta_coff_reloc { + uint32_t rel_rva; + uint32_t rel_sym; + uint16_t rel_type; +}; + + /* .edata section header*/ struct pe_meta_export_hdr { uint32_t eh_virtual_addr; diff --git a/include/perk/perk_secattr.h b/include/perk/perk_secattr.h new file mode 100644 index 0000000..e0cf2b1 --- /dev/null +++ b/include/perk/perk_secattr.h @@ -0,0 +1,75 @@ +#ifndef PERK_SECATTR_H +#define PERK_SECATTR_H + +#include "perk_consts.h" + +#define PE_SECTION_ATTR_BSS (PE_IMAGE_SCN_CNT_UNINITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE) + +#define PE_SECTION_ATTR_TEXT (PE_IMAGE_SCN_CNT_CODE \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_EXECUTE) + +#define PE_SECTION_ATTR_DATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE) + +#define PE_SECTION_ATTR_TLS (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE) + +#define PE_SECTION_ATTR_DEBUG (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_DISCARDABLE) + +#define PE_SECTION_ATTR_DRECTIVE (PE_IMAGE_SCN_LNK_INFO) + +#define PE_SECTION_ATTR_CORMETA (PE_IMAGE_SCN_LNK_INFO) + +#define PE_SECTION_ATTR_IDLSYM (PE_IMAGE_SCN_LNK_INFO) + +#define PE_SECTION_ATTR_EDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ) + +#define PE_SECTION_ATTR_IDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE) + +#define PE_SECTION_ATTR_PDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ) + +#define PE_SECTION_ATTR_RDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ) + +#define PE_SECTION_ATTR_RELOC (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_DISCARDABLE) + +#define PE_SECTION_ATTR_RSRC (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ) + +#define PE_SECTION_ATTR_SBSS (PE_IMAGE_SCN_CNT_UNINITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE \ + |PE_IMAGE_SCN_GPREL) + +#define PE_SECTION_ATTR_SDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE \ + |PE_IMAGE_SCN_GPREL) + +#define PE_SECTION_ATTR_VSDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_MEM_WRITE) + +#define PE_SECTION_ATTR_SRDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ \ + |PE_IMAGE_SCN_GPREL) + +#define PE_SECTION_ATTR_XDATA (PE_IMAGE_SCN_CNT_INITIALIZED_DATA \ + |PE_IMAGE_SCN_MEM_READ) + +#define PE_SECTION_ATTR_SXDATA (PE_IMAGE_SCN_LNK_INFO) + +#endif diff --git a/project/common.mk b/project/common.mk index 8eab6ac..8bf1b0c 100644 --- a/project/common.mk +++ b/project/common.mk @@ -28,15 +28,16 @@ API_SRCS = \ src/logic/pe_image_raw_data.c \ src/output/pe_output_error.c \ src/output/pe_output_export_symbols.c \ - src/output/pe_output_image_category.c \ - src/output/pe_output_image_sections.c \ - src/output/pe_output_image_strings.c \ - src/output/pe_output_image_symbols.c \ + src/output/pe_output_pecoff_category.c \ + src/output/pe_output_pecoff_sections.c \ + src/output/pe_output_pecoff_strings.c \ + src/output/pe_output_pecoff_symbols.c \ src/output/pe_output_idata_libraries.c \ src/output/pe_output_mdso_libraries.c \ src/reader/pe_read_aux_rec_section.c \ src/reader/pe_read_aux_rec_weaksym.c \ src/reader/pe_read_coff_header.c \ + src/reader/pe_read_coff_reloc.c \ src/reader/pe_read_coff_symbol.c \ src/reader/pe_read_dos_header.c \ src/reader/pe_read_export_header.c \ diff --git a/project/headers.mk b/project/headers.mk index 00ee4ae..1dab49c 100644 --- a/project/headers.mk +++ b/project/headers.mk @@ -8,6 +8,7 @@ API_HEADERS = \ $(SOURCE_DIR)/include/$(PACKAGE)/perk_edefs.h \ $(SOURCE_DIR)/include/$(PACKAGE)/perk_meta.h \ $(SOURCE_DIR)/include/$(PACKAGE)/perk_output.h \ + $(SOURCE_DIR)/include/$(PACKAGE)/perk_secattr.h \ $(SOURCE_DIR)/include/$(PACKAGE)/perk_structs.h INTERNAL_HEADERS = \ diff --git a/src/cmds/pe_cmd_perk.c b/src/cmds/pe_cmd_perk.c index 6fe6112..bdb6364 100644 --- a/src/cmds/pe_cmd_perk.c +++ b/src/cmds/pe_cmd_perk.c @@ -44,16 +44,16 @@ static void pe_perform_unit_actions_impl( uint64_t flags = dctx->cctx->fmtflags; if (flags & PERK_OUTPUT_IMAGE_CATEGORY) - pe_output_image_category(dctx,meta); + pe_output_pecoff_category(dctx,meta); if (flags & PERK_OUTPUT_IMAGE_SECTIONS) - pe_output_image_sections(dctx,meta); + pe_output_pecoff_sections(dctx,meta); if (flags & PERK_OUTPUT_IMAGE_SYMBOLS) - pe_output_image_symbols(dctx,meta); + pe_output_pecoff_symbols(dctx,meta); if (flags & PERK_OUTPUT_IMAGE_STRINGS) - pe_output_image_strings(dctx,meta); + pe_output_pecoff_strings(dctx,meta); if (flags & PERK_OUTPUT_EXPORT_SYMS) pe_output_export_symbols(dctx,meta); diff --git a/src/logic/pe_image_meta_data.c b/src/logic/pe_image_meta_data.c index b2255d7..b789100 100644 --- a/src/logic/pe_image_meta_data.c +++ b/src/logic/pe_image_meta_data.c @@ -28,6 +28,7 @@ static int pe_free_image_meta_impl(struct pe_image_meta * meta, int ret) free(meta->m_symvec_crc32); free(meta->m_symvec_crc64); + free(meta->m_symvec_symidx); free(meta->m_idata); free(meta->m_symtbl); @@ -404,11 +405,17 @@ int pe_meta_get_image_meta( } - if ((nrecs = m->m_coff.cfh_size_of_sym_tbl/sizeof(struct pe_raw_coff_symbol))) + if ((nrecs = m->m_coff.cfh_size_of_sym_tbl/sizeof(struct pe_raw_coff_symbol))) { if (!(m->m_symtbl = calloc(nrecs+1,sizeof(struct pe_meta_coff_symbol)))) return PERK_SYSTEM_ERROR(dctx); + if (!(m->m_symvec_symidx = calloc(nrecs,sizeof(struct pe_meta_coff_symbol *)))) + return PERK_SYSTEM_ERROR(dctx); + } + for (i=0,symrec=m->m_symtbl; i<nrecs; i++,symrec++) { + m->m_symvec_symidx[i] = symrec; + pe_read_coff_symbol( &m->r_symtbl[i],symrec, &m->m_coff,base); diff --git a/src/output/pe_output_image_sections.c b/src/output/pe_output_image_sections.c deleted file mode 100644 index 5a7ef21..0000000 --- a/src/output/pe_output_image_sections.c +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************/ -/* perk: PE Resource Kit */ -/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */ -/* Released under GPLv2 and GPLv3; see COPYING.PERK. */ -/***************************************************************/ - -#include <stdio.h> - -#include <perk/perk.h> -#include <perk/perk_output.h> -#include "perk_driver_impl.h" -#include "perk_dprintf_impl.h" -#include "perk_errinfo_impl.h" - -static int pe_output_section_names( - const struct pe_driver_ctx * dctx, - const struct pe_image_meta * meta, - int fdout) -{ - int i; - - for (i=0; i<meta->m_coff.cfh_num_of_sections; i++) - if (pe_dprintf(fdout,"%s\n",meta->m_sectbl[i].sh_name) < 0) - return PERK_FILE_ERROR(dctx); - - return 0; -} - -static int pe_output_section_names_yaml( - const struct pe_driver_ctx * dctx, - const struct pe_image_meta * meta, - int fdout) -{ - int i; - - if (pe_dprintf(fdout," - Sections:\n") < 0) - return PERK_FILE_ERROR(dctx); - - for (i=0; i<meta->m_coff.cfh_num_of_sections; i++) - if (pe_dprintf(fdout," - section: %s\n",meta->m_sectbl[i].sh_name) < 0) - return PERK_FILE_ERROR(dctx); - - return 0; -} - -static int pe_output_section_record_yaml( - int fdout, - const struct pe_driver_ctx * dctx, - const struct pe_meta_sec_hdr * s) -{ - if (pe_dprintf(fdout, - " - section:\n" - " - [ name: %s ]\n" - " - [ virtual-size: 0x%08x ]\n" - " - [ virtual-addr: 0x%08x ]\n" - " - [ size-of-raw-data: 0x%08x ]\n" - " - [ ptr-to-raw-data: 0x%08x ]\n" - " - [ ptr-to-relocs: 0x%08x ]\n" - " - [ ptr-to-line-nums: 0x%08x ]\n" - " - [ num-of-relocs: %u ]\n" - " - [ num-of-line-nums: %u ]\n" - " - [ characteristics: 0x%08x ]\n" - "\n", - s->sh_name, - s->sh_virtual_size, - s->sh_virtual_addr, - s->sh_size_of_raw_data, - s->sh_ptr_to_raw_data, - s->sh_ptr_to_relocs, - s->sh_ptr_to_line_nums, - s->sh_num_of_relocs, - s->sh_num_of_line_nums, - s->sh_characteristics) < 0) - return PERK_FILE_ERROR(dctx); - - return 0; -} - -static int pe_output_section_records_yaml( - const struct pe_driver_ctx * dctx, - const struct pe_image_meta * meta, - int fdout) -{ - int i; - - if (pe_dprintf(fdout," - Sections:\n") < 0) - return PERK_FILE_ERROR(dctx); - - for (i=0; i<meta->m_coff.cfh_num_of_sections; i++) - if (pe_output_section_record_yaml(fdout,dctx,&meta->m_sectbl[i]) < 0) - return PERK_NESTED_ERROR(dctx); - - return 0; -} - -static int pe_output_image_sections_yaml( - const struct pe_driver_ctx * dctx, - const struct pe_image_meta * meta, - int fdout) -{ - if (dctx->cctx->fmtflags & PERK_PRETTY_VERBOSE) { - if (pe_output_section_records_yaml(dctx,meta,fdout) < 0) - return PERK_NESTED_ERROR(dctx); - } else { - if (pe_output_section_names_yaml(dctx,meta,fdout) < 0) - return PERK_NESTED_ERROR(dctx); - } - - return 0; -} - -int pe_output_image_sections( - const struct pe_driver_ctx * dctx, - const struct pe_image_meta * meta) -{ - int fdout = pe_driver_fdout(dctx); - - if (dctx->cctx->fmtflags & PERK_PRETTY_YAML) { - if (pe_output_image_sections_yaml(dctx,meta,fdout) < 0) - return PERK_NESTED_ERROR(dctx); - - } else { - if (pe_output_section_names(dctx,meta,fdout) < 0) - return PERK_NESTED_ERROR(dctx); - } - - return 0; -} diff --git a/src/output/pe_output_image_category.c b/src/output/pe_output_pecoff_category.c index bd80687..3d4e5d4 100644 --- a/src/output/pe_output_image_category.c +++ b/src/output/pe_output_pecoff_category.c @@ -12,7 +12,7 @@ #include "perk_dprintf_impl.h" #include "perk_errinfo_impl.h" -int pe_output_image_category( +int pe_output_pecoff_category( const struct pe_driver_ctx * dctx, const struct pe_image_meta * meta) { diff --git a/src/output/pe_output_pecoff_sections.c b/src/output/pe_output_pecoff_sections.c new file mode 100644 index 0000000..3ee6fc0 --- /dev/null +++ b/src/output/pe_output_pecoff_sections.c @@ -0,0 +1,223 @@ +/***************************************************************/ +/* perk: PE Resource Kit */ +/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */ +/* Released under GPLv2 and GPLv3; see COPYING.PERK. */ +/***************************************************************/ + +#include <stdio.h> + +#include <perk/perk.h> +#include <perk/perk_output.h> +#include <perk/perk_consts.h> +#include <perk/perk_structs.h> +#include "perk_driver_impl.h" +#include "perk_dprintf_impl.h" +#include "perk_errinfo_impl.h" + +static const char * pe_i386_reloc_type_desc[0x16] = { + [PE_IMAGE_REL_I386_ABSOLUTE] = "PE_IMAGE_REL_I386_ABSOLUTE", + [PE_IMAGE_REL_I386_DIR16] = "PE_IMAGE_REL_I386_DIR16", + [PE_IMAGE_REL_I386_REL16] = "PE_IMAGE_REL_I386_REL16", + [PE_IMAGE_REL_I386_DIR32] = "PE_IMAGE_REL_I386_DIR32", + [PE_IMAGE_REL_I386_DIR32NB] = "PE_IMAGE_REL_I386_DIR32NB", + [PE_IMAGE_REL_I386_SEG12] = "PE_IMAGE_REL_I386_SEG12", + [PE_IMAGE_REL_I386_SECTION] = "PE_IMAGE_REL_I386_SECTION", + [PE_IMAGE_REL_I386_SECREL] = "PE_IMAGE_REL_I386_SECREL", + [PE_IMAGE_REL_I386_TOKEN] = "PE_IMAGE_REL_I386_TOKEN", + [PE_IMAGE_REL_I386_SECREL7] = "PE_IMAGE_REL_I386_SECREL7", + [PE_IMAGE_REL_I386_REL32] = "PE_IMAGE_REL_I386_REL32", +}; + +static const char * pe_amd64_reloc_type_desc[0x12] = { + [PE_IMAGE_REL_AMD64_ABSOLUTE] = "PE_IMAGE_REL_AMD64_ABSOLUTE", + [PE_IMAGE_REL_AMD64_ADDR64] = "PE_IMAGE_REL_AMD64_ADDR64", + [PE_IMAGE_REL_AMD64_ADDR32] = "PE_IMAGE_REL_AMD64_ADDR32", + [PE_IMAGE_REL_AMD64_ADDR32NB] = "PE_IMAGE_REL_AMD64_ADDR32NB", + [PE_IMAGE_REL_AMD64_REL32] = "PE_IMAGE_REL_AMD64_REL32", + [PE_IMAGE_REL_AMD64_REL32_1] = "PE_IMAGE_REL_AMD64_REL32_1", + [PE_IMAGE_REL_AMD64_REL32_2] = "PE_IMAGE_REL_AMD64_REL32_2", + [PE_IMAGE_REL_AMD64_REL32_3] = "PE_IMAGE_REL_AMD64_REL32_3", + [PE_IMAGE_REL_AMD64_REL32_4] = "PE_IMAGE_REL_AMD64_REL32_4", + [PE_IMAGE_REL_AMD64_REL32_5] = "PE_IMAGE_REL_AMD64_REL32_5", + [PE_IMAGE_REL_AMD64_SECTION] = "PE_IMAGE_REL_AMD64_SECTION", + [PE_IMAGE_REL_AMD64_SECREL] = "PE_IMAGE_REL_AMD64_SECREL", + [PE_IMAGE_REL_AMD64_SECREL7] = "PE_IMAGE_REL_AMD64_SECREL7", + [PE_IMAGE_REL_AMD64_TOKEN] = "PE_IMAGE_REL_AMD64_TOKEN", + [PE_IMAGE_REL_AMD64_SREL32] = "PE_IMAGE_REL_AMD64_SREL32", + [PE_IMAGE_REL_AMD64_PAIR] = "PE_IMAGE_REL_AMD64_PAIR", + [PE_IMAGE_REL_AMD64_SSPAN32] = "PE_IMAGE_REL_AMD64_SSPAN32", +}; + +static int pe_output_section_names( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta, + int fdout) +{ + int i; + + for (i=0; i<meta->m_coff.cfh_num_of_sections; i++) + if (pe_dprintf(fdout,"%s\n",meta->m_sectbl[i].sh_name) < 0) + return PERK_FILE_ERROR(dctx); + + return 0; +} + +static int pe_output_section_names_yaml( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta, + int fdout) +{ + int i; + + if (pe_dprintf(fdout," - Sections:\n") < 0) + return PERK_FILE_ERROR(dctx); + + for (i=0; i<meta->m_coff.cfh_num_of_sections; i++) + if (pe_dprintf(fdout," - section: %s\n",meta->m_sectbl[i].sh_name) < 0) + return PERK_FILE_ERROR(dctx); + + return 0; +} + +static int pe_output_section_record_yaml( + int fdout, + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta, + const struct pe_meta_sec_hdr * s, + const unsigned char * base) +{ + int i; + const struct pe_raw_coff_reloc * r; + struct pe_meta_coff_reloc m; + char reltypedesc[64]; + + if (pe_dprintf(fdout, + " - section:\n" + " - [ name: %s ]\n" + " - [ virtual-size: 0x%08x ]\n" + " - [ virtual-addr: 0x%08x ]\n" + " - [ size-of-raw-data: 0x%08x ]\n" + " - [ ptr-to-raw-data: 0x%08x ]\n" + " - [ ptr-to-relocs: 0x%08x ]\n" + " - [ ptr-to-line-nums: 0x%08x ]\n" + " - [ num-of-relocs: %u ]\n" + " - [ num-of-line-nums: %u ]\n" + " - [ characteristics: 0x%08x ]\n" + "\n", + s->sh_name, + s->sh_virtual_size, + s->sh_virtual_addr, + s->sh_size_of_raw_data, + s->sh_ptr_to_raw_data, + s->sh_ptr_to_relocs, + s->sh_ptr_to_line_nums, + s->sh_num_of_relocs, + s->sh_num_of_line_nums, + s->sh_characteristics) < 0) + return PERK_FILE_ERROR(dctx); + + if (s->sh_num_of_relocs == 0) + return 0; + + if (pe_dprintf(fdout," - relocation-records:\n") < 0) + return PERK_FILE_ERROR(dctx); + + r = (const struct pe_raw_coff_reloc *)&base[s->sh_ptr_to_relocs]; + + for (i=0; i<s->sh_num_of_relocs; i++) { + pe_read_coff_reloc(&r[i],&m); + memset(reltypedesc,0,sizeof(reltypedesc)); + + switch (meta->m_abi) { + case PE_ABI_PE32: + if (m.rel_type <= PE_IMAGE_REL_I386_REL32) + snprintf(reltypedesc,sizeof(reltypedesc), + "0x%04x (%s)", + m.rel_type, + pe_i386_reloc_type_desc[m.rel_type]); + break; + + case PE_ABI_PE64: + if (m.rel_type <= PE_IMAGE_REL_AMD64_SSPAN32) + snprintf(reltypedesc,sizeof(reltypedesc), + "0x%04x (%s)", + m.rel_type, + pe_amd64_reloc_type_desc[m.rel_type]); + break; + + default: + snprintf(reltypedesc,sizeof(reltypedesc), + "0x%04x", + m.rel_type); + } + + if (pe_dprintf( + fdout, + " - reloction-record:\n" + " - [ rva: 0x%08x ]\n" + " - [ sym: 0x%08x (%s) ]\n" + " - [ type: %s ]\n" + "\n", + m.rel_rva, + m.rel_sym, + meta->m_symvec_symidx[m.rel_sym]->cs_name, + reltypedesc) < 0) + return PERK_FILE_ERROR(dctx); + } + + return 0; +} + +static int pe_output_section_records_yaml( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta, + int fdout) +{ + int i; + + if (pe_dprintf(fdout," - Sections:\n") < 0) + return PERK_FILE_ERROR(dctx); + + for (i=0; i<meta->m_coff.cfh_num_of_sections; i++) + if (pe_output_section_record_yaml( + fdout,dctx,meta, + &meta->m_sectbl[i], + meta->r_image.map_addr) < 0) + return PERK_NESTED_ERROR(dctx); + + return 0; +} + +static int pe_output_pecoff_sections_yaml( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta, + int fdout) +{ + if (dctx->cctx->fmtflags & PERK_PRETTY_VERBOSE) { + if (pe_output_section_records_yaml(dctx,meta,fdout) < 0) + return PERK_NESTED_ERROR(dctx); + } else { + if (pe_output_section_names_yaml(dctx,meta,fdout) < 0) + return PERK_NESTED_ERROR(dctx); + } + + return 0; +} + +int pe_output_pecoff_sections( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta) +{ + int fdout = pe_driver_fdout(dctx); + + if (dctx->cctx->fmtflags & PERK_PRETTY_YAML) { + if (pe_output_pecoff_sections_yaml(dctx,meta,fdout) < 0) + return PERK_NESTED_ERROR(dctx); + + } else { + if (pe_output_section_names(dctx,meta,fdout) < 0) + return PERK_NESTED_ERROR(dctx); + } + + return 0; +} diff --git a/src/output/pe_output_image_strings.c b/src/output/pe_output_pecoff_strings.c index a0ca849..917f655 100644 --- a/src/output/pe_output_image_strings.c +++ b/src/output/pe_output_pecoff_strings.c @@ -14,7 +14,7 @@ #include "perk_dprintf_impl.h" #include "perk_errinfo_impl.h" -int pe_output_image_strings( +int pe_output_pecoff_strings( const struct pe_driver_ctx * dctx, const struct pe_image_meta * meta) { diff --git a/src/output/pe_output_image_symbols.c b/src/output/pe_output_pecoff_symbols.c index 4847aac..0c2eaa1 100644 --- a/src/output/pe_output_image_symbols.c +++ b/src/output/pe_output_pecoff_symbols.c @@ -84,6 +84,14 @@ static const char * pe_weak_extern_switches[4] = { [PE_IMAGE_WEAK_EXTERN_SEARCH_ALIAS] = "apply weak alias semantics", }; +static const char * pe_comdat_select_desc[0x7] = { + [PE_IMAGE_COMDAT_SELECT_NODUPLICATES] = "PE_IMAGE_COMDAT_SELECT_NODUPLICATES", + [PE_IMAGE_COMDAT_SELECT_ANY] = "PE_IMAGE_COMDAT_SELECT_ANY", + [PE_IMAGE_COMDAT_SELECT_SAME_SIZE] = "PE_IMAGE_COMDAT_SELECT_SAME_SIZE", + [PE_IMAGE_COMDAT_SELECT_EXACT_MATCH] = "PE_IMAGE_COMDAT_SELECT_EXACT_MATCH", + [PE_IMAGE_COMDAT_SELECT_ASSOCIATIVE] = "PE_IMAGE_COMDAT_SELECT_ASSOCIATIVE", + [PE_IMAGE_COMDAT_SELECT_LARGEST] = "PE_IMAGE_COMDAT_SELECT_LARGEST", +}; static int pe_output_symbol_names( const struct pe_driver_ctx * dctx, @@ -161,7 +169,7 @@ static int pe_output_symbol_records_yaml( " - [ value: 0x%08x ]\n" " - [ crc32: 0x%08x ]\n" " - [ crc64: 0x"PPRIX64" ]\n" - " - [ secnum: (%d) ]\n" + " - [ secnum: %d (one-based) ]\n" " - [ secname: %s ]\n" " - [ type: 0x%02X ]\n" " - [ typedesc: %s%s ]\n" @@ -197,8 +205,8 @@ static int pe_output_symbol_records_yaml( pe_read_aux_rec_weaksym(coffsym,&auxrec,idx); if (pe_dprintf(fdout, - " - [ tag-index: = %d ]\n" - " - [ tag-characteristics: = 0x%01X (%s) ]\n\n", + " - [ tag-index: %d ]\n" + " - [ tag-characteristics: 0x%01X (%s) ]\n\n", auxrec.aux_tag_index, auxrec.aux_characteristics, pe_weak_extern_switches[auxrec.aux_characteristics & 0x03]) < 0) @@ -209,6 +217,9 @@ static int pe_output_symbol_records_yaml( const struct pe_raw_coff_symbol * coffsym; struct pe_meta_aux_rec_section auxrec; int idx; + char selection[64]; + const int seldesclo = PE_IMAGE_COMDAT_SELECT_NODUPLICATES; + const int seldeschi = PE_IMAGE_COMDAT_SELECT_LARGEST; coffsym = (const struct pe_raw_coff_symbol *)symrec->cs_aux_recs; coffsym--; @@ -219,20 +230,29 @@ static int pe_output_symbol_records_yaml( for (idx=0; idx<symrec->cs_num_of_aux_recs; idx++) { pe_read_aux_rec_section(coffsym,&auxrec,idx); + if ((auxrec.aux_selection >= seldesclo) && (auxrec.aux_selection <= seldeschi)) { + snprintf(selection,sizeof(selection),"%u (%s)", + auxrec.aux_selection, + pe_comdat_select_desc[auxrec.aux_selection]); + } else { + snprintf(selection,sizeof(selection),"%u", + auxrec.aux_selection); + } + if (pe_dprintf(fdout, - " - [ size: = 0x%08x ]\n" - " - [ num-of-relocs: = 0x%08X ]\n" - " - [ num-of-line-nums: = 0x%08X ]\n" - " - [ check-sum: = 0x%08X ]\n" - " - [ number: = %u ]\n" - " - [ selection: = %u ]\n" + " - [ size: 0x%08x ]\n" + " - [ num-of-relocs: 0x%08X ]\n" + " - [ num-of-line-nums: 0x%08X ]\n" + " - [ check-sum: 0x%08X ]\n" + " - [ number: %u ]\n" + " - [ selection: %s ]\n" "\n", auxrec.aux_size, auxrec.aux_num_of_relocs, auxrec.aux_num_of_line_nums, auxrec.aux_check_sum, auxrec.aux_number, - auxrec.aux_selection) < 0) + selection) < 0) return PERK_SYSTEM_ERROR(dctx); } } @@ -241,7 +261,7 @@ static int pe_output_symbol_records_yaml( return 0; } -static int pe_output_image_symbols_yaml( +static int pe_output_pecoff_symbols_yaml( const struct pe_driver_ctx * dctx, const struct pe_image_meta * meta, int fdout) @@ -257,7 +277,7 @@ static int pe_output_image_symbols_yaml( return 0; } -int pe_output_image_symbols( +int pe_output_pecoff_symbols( const struct pe_driver_ctx * dctx, const struct pe_image_meta * meta) { @@ -267,7 +287,7 @@ int pe_output_image_symbols( return 0; if (dctx->cctx->fmtflags & PERK_PRETTY_YAML) { - if (pe_output_image_symbols_yaml(dctx,meta,fdout) < 0) + if (pe_output_pecoff_symbols_yaml(dctx,meta,fdout) < 0) return PERK_NESTED_ERROR(dctx); } else { diff --git a/src/reader/pe_read_coff_reloc.c b/src/reader/pe_read_coff_reloc.c new file mode 100644 index 0000000..9095cdd --- /dev/null +++ b/src/reader/pe_read_coff_reloc.c @@ -0,0 +1,22 @@ +/***************************************************************/ +/* perk: PE Resource Kit */ +/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */ +/* Released under GPLv2 and GPLv3; see COPYING.PERK. */ +/***************************************************************/ + +#include <perk/perk.h> +#include <perk/perk_consts.h> +#include <perk/perk_structs.h> +#include "perk_endian_impl.h" +#include "perk_reader_impl.h" + +int pe_read_coff_reloc( + const struct pe_raw_coff_reloc * p, + struct pe_meta_coff_reloc * m) +{ + m->rel_rva = pe_read_long(p->rel_rva); + m->rel_sym = pe_read_long(p->rel_sym); + m->rel_type = pe_read_long(p->rel_type); + + return 0; +} |