summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-05-02 10:05:51 -0400
committermidipix <writeonce@midipix.org>2016-11-10 23:35:18 -0500
commitc0fbae7a40c662ae77f59f5f919cd6b88e38a85d (patch)
treead6aaca1b75a1f4b5e9ac533220e382f49489c94
parent99ace9f6a21b254216f60613e91191d902daeeb8 (diff)
downloadperk-c0fbae7a40c662ae77f59f5f919cd6b88e38a85d.tar.bz2
perk-c0fbae7a40c662ae77f59f5f919cd6b88e38a85d.tar.xz
initial commit.
-rw-r--r--include/perk/perk.h98
-rw-r--r--include/perk/perk_consts.h371
-rw-r--r--include/perk/perk_meta.h222
-rw-r--r--include/perk/perk_output.h12
-rw-r--r--include/perk/perk_structs.h615
-rw-r--r--src/internal/perk_impl.h64
-rw-r--r--src/main/pe_get_image_meta.c184
-rw-r--r--src/main/pe_map_raw_image.c40
-rw-r--r--src/main/perk.c116
-rw-r--r--src/output/pe_output_export_symbols.c24
-rw-r--r--src/reader/pe_read_coff_header.c37
-rw-r--r--src/reader/pe_read_dos_header.c52
-rw-r--r--src/reader/pe_read_export_header.c32
-rw-r--r--src/reader/pe_read_import_header.c46
-rw-r--r--src/reader/pe_read_optional_header.c139
-rw-r--r--src/reader/pe_read_section_header.c37
16 files changed, 2089 insertions, 0 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h
new file mode 100644
index 0000000..00d24d5
--- /dev/null
+++ b/include/perk/perk.h
@@ -0,0 +1,98 @@
+#ifndef PERK_H
+#define PERK_H
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <perk/perk_consts.h>
+#include <perk/perk_structs.h>
+#include <perk/perk_meta.h>
+#include <perk/perk_output.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* pre-alpha */
+#ifndef PERK_APP
+#ifndef PERK_PRE_ALPHA
+#error libperk: pre-alpha: ABI is not final!
+#error to use the library, please pass -DPERK_PRE_ALPHA to the compiler.
+#endif
+#endif
+
+/* exec flags */
+#define PERK_HELP 0x01
+
+/* errors */
+#define PERK_OK 0x00
+#define PERK_BAD_OPT 0xA1
+#define PERK_BAD_OPT_VAL 0xA2
+#define PERK_IO_ERROR 0xA3
+#define PERK_MAP_ERROR 0xA4
+#define PERK_BAD_DOS_HEADER 0xA5
+#define PERK_BAD_COFF_HEADER 0xA6
+#define PERK_BAD_IMAGE_TYPE 0xA7
+#define PERK_MALFORMED_IMAGE 0xA8
+
+struct pe_raw_image {
+ char * addr;
+ size_t size;
+};
+
+struct pe_image_summary {
+ uint32_t num_of_export_syms;
+ uint32_t num_of_implibs;
+ uint32_t num_of_relocs;
+};
+
+struct pe_image_meta {
+ struct pe_raw_image image;
+ struct pe_image_summary summary;
+
+ struct pe_meta_image_dos_hdr dos;
+ struct pe_meta_coff_file_hdr coff;
+ struct pe_meta_opt_hdr opt;
+ struct pe_meta_sec_hdr * sectbl;
+
+ struct pe_image_dos_hdr * ados;
+ struct pe_coff_file_hdr * acoff;
+ union pe_opt_hdr * aopt;
+ struct pe_sec_hdr * asectbl;
+
+ struct pe_meta_export_hdr edata;
+ struct pe_export_hdr * aedata;
+ struct pe_meta_sec_hdr * hedata;
+
+ struct pe_meta_import_hdr * idata;
+ struct pe_import_hdr * aidata;
+ struct pe_meta_sec_hdr * hidata;
+};
+
+/* utility api */
+int pe_output_export_symbols (const struct pe_image_meta *, uint32_t flags, FILE *);
+
+/* high-level api */
+int pe_map_raw_image (int fd, const char * name, struct pe_raw_image *);
+int pe_unmap_raw_image (struct pe_raw_image *);
+
+int pe_get_image_meta (const struct pe_raw_image *, struct pe_image_meta **);
+int pe_free_image_meta (struct pe_image_meta *);
+
+int pe_get_named_section_index (const struct pe_image_meta *, const char * name);
+int pe_get_block_section_index (const struct pe_image_meta *, const struct pe_block *);
+
+/* low-level api */
+int pe_read_dos_header (const struct pe_image_dos_hdr *, struct pe_meta_image_dos_hdr *);
+int pe_read_coff_header (const struct pe_coff_file_hdr *, struct pe_meta_coff_file_hdr *);
+int pe_read_optional_header (const union pe_opt_hdr *, struct pe_meta_opt_hdr *);
+int pe_read_section_header (const struct pe_sec_hdr *, struct pe_meta_sec_hdr *);
+int pe_read_export_header (const struct pe_export_hdr *, struct pe_meta_export_hdr *);
+int pe_read_import_header (const struct pe_import_hdr *, struct pe_meta_import_hdr *);
+int pe_read_import_lookup_item (const struct pe_import_lookup_item *, struct pe_meta_import_lookup_item *,uint32_t magic);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/perk/perk_consts.h b/include/perk/perk_consts.h
new file mode 100644
index 0000000..a3a329b
--- /dev/null
+++ b/include/perk/perk_consts.h
@@ -0,0 +1,371 @@
+#ifndef PERK_CONSTS_H
+#define PERK_CONSTS_H
+
+#ifndef PE_BITWISE
+#define PE_BITWISE(x) x
+#endif
+
+#ifndef PE_ARBITRARY
+#define PE_ARBITRARY(x) x
+#endif
+
+#define PE_IMAGE_REL_BASED_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_BASED_HIGH PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_BASED_LOW PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_BASED_HIGHLOW PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_BASED_HIGHADJ PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_BASED_MIPS_JMPADDR PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_BASED_ARM_MOV32A PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_BASED_RESERVED PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_BASED_ARM_MOV32T PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_BASED_MIPS_JMPADDR16 PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_BASED_DIR64 PE_ARBITRARY (0x0000000a)
+#define PE_WIN_CERT_REVISION_1_0 PE_ARBITRARY (0x00000100)
+#define PE_WIN_CERT_REVISION_2_0 PE_ARBITRARY (0x00000200)
+#define PE_WIN_CERT_TYPE_X509 PE_ARBITRARY (0x00000001)
+#define PE_WIN_CERT_TYPE_PKCS_SIGNED_DATA PE_ARBITRARY (0x00000002)
+#define PE_WIN_CERT_TYPE_RESERVED_1 PE_ARBITRARY (0x00000003)
+#define PE_WIN_CERT_TYPE_TS_STACK_SIGNED PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_ARM_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_ARM_ADDR32 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_ARM_ADDR32NB PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_ARM_BRANCH24 PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_ARM_BRANCH11 PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_ARM_TOKEN PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_ARM_BLX24 PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_REL_ARM_BLX11 PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_ARM_SECTION PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_REL_ARM_SECREL PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_REL_ARM_MOV32A PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_REL_ARM_MOV32T PE_ARBITRARY (0x00000011)
+#define PE_IMAGE_REL_ARM_BRANCH20T PE_ARBITRARY (0x00000012)
+#define PE_IMAGE_REL_ARM_BRANCH24T PE_ARBITRARY (0x00000014)
+#define PE_IMAGE_REL_ARM_BLX23T PE_ARBITRARY (0x00000015)
+#define PE_IMAGE_REL_SH3_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_SH3_DIRECT16 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_SH3_DIRECT32 PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_SH3_DIRECT8 PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_SH3_DIRECT8_WORD PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_SH3_DIRECT8_LONG PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_SH3_DIRECT4 PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_SH3_DIRECT4_WORD PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_SH3_DIRECT4_LONG PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_REL_SH3_PCREL8_WORD PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_SH3_PCREL8_LONG PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_SH3_PCREL12_WORD PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_SH3_STARTOF_SECTION PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_SH3_SIZEOF_SECTION PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_REL_SH3_SECTION PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_REL_SH3_SECREL PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_REL_SH3_DIRECT32_NB PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_REL_SH3_GPREL4_LONG PE_ARBITRARY (0x00000011)
+#define PE_IMAGE_REL_SH3_TOKEN PE_ARBITRARY (0x00000012)
+#define PE_IMAGE_REL_SHM_PCRELPT PE_ARBITRARY (0x00000013)
+#define PE_IMAGE_REL_SHM_REFLO PE_ARBITRARY (0x00000014)
+#define PE_IMAGE_REL_SHM_REFHALF PE_ARBITRARY (0x00000015)
+#define PE_IMAGE_REL_SHM_RELLO PE_ARBITRARY (0x00000016)
+#define PE_IMAGE_REL_SHM_RELHALF PE_ARBITRARY (0x00000017)
+#define PE_IMAGE_REL_SHM_PAIR PE_ARBITRARY (0x00000018)
+#define PE_IMAGE_REL_SHM_NOMODE PE_ARBITRARY (0x00008000)
+#define PE_IMAGE_REL_I386_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_I386_DIR16 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_I386_REL16 PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_I386_DIR32 PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_I386_DIR32NB PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_I386_SEG12 PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_I386_SECTION PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_I386_SECREL PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_I386_TOKEN PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_I386_SECREL7 PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_REL_I386_REL32 PE_ARBITRARY (0x00000014)
+#define PE_IMAGE_REL_IA64_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_IA64_IMM14 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_IA64_IMM22 PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_IA64_IMM64 PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_IA64_DIR32 PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_IA64_DIR64 PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_IA64_PCREL21B PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_IA64_PCREL21M PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_IA64_PCREL21F PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_REL_IA64_GPREL22 PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_IA64_LTOFF22 PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_IA64_SECTION PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_IA64_SECREL22 PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_IA64_SECREL64I PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_REL_IA64_SECREL32 PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_REL_IA64_DIR32NB PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_REL_IA64_SREL14 PE_ARBITRARY (0x00000011)
+#define PE_IMAGE_REL_IA64_SREL22 PE_ARBITRARY (0x00000012)
+#define PE_IMAGE_REL_IA64_SREL32 PE_ARBITRARY (0x00000013)
+#define PE_IMAGE_REL_IA64_UREL32 PE_ARBITRARY (0x00000014)
+#define PE_IMAGE_REL_IA64_PCREL60X PE_ARBITRARY (0x00000015)
+#define PE_IMAGE_REL_IA64_PCREL60B PE_ARBITRARY (0x00000016)
+#define PE_IMAGE_REL_IA64_PCREL60F PE_ARBITRARY (0x00000017)
+#define PE_IMAGE_REL_IA64_PCREL60I PE_ARBITRARY (0x00000018)
+#define PE_IMAGE_REL_IA64_PCREL60M PE_ARBITRARY (0x00000019)
+#define PE_IMAGE_REL_IA64_IMMGPREL64 PE_ARBITRARY (0x0000001a)
+#define PE_IMAGE_REL_IA64_TOKEN PE_ARBITRARY (0x0000001b)
+#define PE_IMAGE_REL_IA64_GPREL32 PE_ARBITRARY (0x0000001c)
+#define PE_IMAGE_REL_IA64_ADDEND PE_ARBITRARY (0x0000001f)
+#define PE_IMAGE_REL_PPC_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_PPC_ADDR64 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_PPC_ADDR32 PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_PPC_ADDR24 PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_PPC_ADDR16 PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_PPC_ADDR14 PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_PPC_REL24 PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_PPC_REL14 PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_PPC_ADDR32NB PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_PPC_SECREL PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_PPC_SECTION PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_PPC_SECREL16 PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_REL_PPC_REFHI PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_REL_PPC_REFLO PE_ARBITRARY (0x00000011)
+#define PE_IMAGE_REL_PPC_PAIR PE_ARBITRARY (0x00000012)
+#define PE_IMAGE_REL_PPC_SECRELLO PE_ARBITRARY (0x00000013)
+#define PE_IMAGE_REL_PPC_GPREL PE_ARBITRARY (0x00000015)
+#define PE_IMAGE_REL_PPC_TOKEN PE_ARBITRARY (0x00000016)
+#define PE_IMAGE_REL_MIPS_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_MIPS_REFHALF PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_MIPS_REFWORD PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_MIPS_JMPADDR PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_MIPS_REFHI PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_MIPS_REFLO PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_MIPS_GPREL PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_MIPS_LITERAL PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_MIPS_SECTION PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_MIPS_SECREL PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_MIPS_SECRELLO PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_MIPS_SECRELHI PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_REL_MIPS_JMPADDR16 PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_REL_MIPS_REFWORDNB PE_ARBITRARY (0x00000022)
+#define PE_IMAGE_REL_MIPS_PAIR PE_ARBITRARY (0x00000025)
+#define PE_IMAGE_REL_M32R_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_M32R_ADDR32 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_M32R_ADDR32NB PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_M32R_ADDR24 PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_M32R_GPREL16 PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_M32R_PCREL24 PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_M32R_PCREL16 PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_M32R_PCREL8 PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_M32R_REFHALF PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_REL_M32R_REFHI PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_M32R_REFLO PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_M32R_PAIR PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_M32R_SECTION PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_M32R_SECREL PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_REL_M32R_TOKEN PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_REL_AMD64_ABSOLUTE PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_REL_AMD64_ADDR64 PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_REL_AMD64_ADDR32 PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_REL_AMD64_ADDR32NB PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_REL_AMD64_REL32 PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_REL_AMD64_REL32_1 PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_REL_AMD64_REL32_2 PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_REL_AMD64_REL32_3 PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_REL_AMD64_REL32_4 PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_REL_AMD64_REL32_5 PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_REL_AMD64_SECTION PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_REL_AMD64_SECREL PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_REL_AMD64_SECREL7 PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_REL_AMD64_TOKEN PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_REL_AMD64_SREL32 PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_REL_AMD64_PAIR PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_REL_AMD64_SSPAN32 PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_COMDAT_SELECT_NODUPLICATES PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_COMDAT_SELECT_ANY PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_COMDAT_SELECT_SAME_SIZE PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_COMDAT_SELECT_EXACT_MATCH PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_COMDAT_SELECT_ASSOCIATIVE PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_COMDAT_SELECT_LARGEST PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_DLL_RESERVED_X0001 PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_RESERVED_X0002 PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_RESERVED_X0004 PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_RESERVED_X0008 PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_NX_COMPAT PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_NO_SEH PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_NO_BIND PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_RESERVED_X1000 PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER PE_BITWISE (0x00000000)
+#define PE_IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_RELOCS_STRIPPED PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_EXECUTABLE_IMAGE PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_LINE_NUMS_STRIPPED PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_AGGRESSIVE_WS_TRIM PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_LARGE_ADDRESS_AWARE PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_RESERVED_CHARACTERISTIC PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_BYTES_REVERSED_LO PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_32BIT_MACHINE PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_DEBUG_STRIPPED PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_NET_RUN_FROM_SWAP PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_SYSTEM PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_DLL PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_UP_SYSTEM_ONLY PE_BITWISE (0x00000000)
+#define PE_IMAGE_FILE_BYTES_REVERSED_HI PE_BITWISE (0x00000000)
+#define PE_IMAGE_DEBUG_TYPE_UNKNOWN PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_DEBUG_TYPE_COFF PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_DEBUG_TYPE_CODEVIEW PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_DEBUG_TYPE_FPO PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_DEBUG_TYPE_MISC PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_DEBUG_TYPE_EXCEPTION PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_DEBUG_TYPE_FIXUP PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_DEBUG_TYPE_OMAP_TO_SRC PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_DEBUG_TYPE_OMAP_FROM_SRC PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_DEBUG_TYPE_BORLAND PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_DEBUG_TYPE_RESERVED10 PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_DEBUG_TYPE_CLSID PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_SUBSYSTEM_UNKNOWN PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_SUBSYSTEM_NATIVE PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_SUBSYSTEM_WINDOWS_GUI PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_SUBSYSTEM_WINDOWS_CUI PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_SUBSYSTEM_POSIX_CUI PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_SUBSYSTEM_EFI_APPLICATION PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_SUBSYSTEM_EFI_ROM PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_SUBSYSTEM_XBOX PE_ARBITRARY (0x0000000e)
+#define PE_IMPORT_ORDINAL PE_ARBITRARY (0x00000000)
+#define PE_IMPORT_NAME PE_ARBITRARY (0x00000001)
+#define PE_IMPORT_NAME_NOPREFIX PE_ARBITRARY (0x00000002)
+#define PE_IMPORT_NAME_UNDECORATE PE_ARBITRARY (0x00000003)
+#define PE_IMPORT_CODE PE_ARBITRARY (0x00000000)
+#define PE_IMPORT_DATA PE_ARBITRARY (0x00000001)
+#define PE_IMPORT_CONST PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_FILE_MACHINE_UNKNOWN PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_FILE_MACHINE_I386 PE_ARBITRARY (0x0000014c)
+#define PE_IMAGE_FILE_MACHINE_R4000 PE_ARBITRARY (0x00000166)
+#define PE_IMAGE_FILE_MACHINE_WCEMIPSV2 PE_ARBITRARY (0x00000169)
+#define PE_IMAGE_FILE_MACHINE_SH3 PE_ARBITRARY (0x000001a2)
+#define PE_IMAGE_FILE_MACHINE_SH3DSP PE_ARBITRARY (0x000001a3)
+#define PE_IMAGE_FILE_MACHINE_SH4 PE_ARBITRARY (0x000001a6)
+#define PE_IMAGE_FILE_MACHINE_SH5 PE_ARBITRARY (0x000001a8)
+#define PE_IMAGE_FILE_MACHINE_ARM PE_ARBITRARY (0x000001c0)
+#define PE_IMAGE_FILE_MACHINE_THUMB PE_ARBITRARY (0x000001c2)
+#define PE_IMAGE_FILE_MACHINE_ARMV7 PE_ARBITRARY (0x000001c4)
+#define PE_IMAGE_FILE_MACHINE_AM33 PE_ARBITRARY (0x000001d3)
+#define PE_IMAGE_FILE_MACHINE_POWERPC PE_ARBITRARY (0x000001f0)
+#define PE_IMAGE_FILE_MACHINE_POWERPCFP PE_ARBITRARY (0x000001f1)
+#define PE_IMAGE_FILE_MACHINE_IA64 PE_ARBITRARY (0x00000200)
+#define PE_IMAGE_FILE_MACHINE_MIPS16 PE_ARBITRARY (0x00000266)
+#define PE_IMAGE_FILE_MACHINE_MIPSFPU PE_ARBITRARY (0x00000366)
+#define PE_IMAGE_FILE_MACHINE_MIPSFPU16 PE_ARBITRARY (0x00000466)
+#define PE_IMAGE_FILE_MACHINE_EBC PE_ARBITRARY (0x00000ebc)
+#define PE_IMAGE_FILE_MACHINE_AMD64 PE_ARBITRARY (0x00008664)
+#define PE_IMAGE_FILE_MACHINE_M32R PE_ARBITRARY (0x00009041)
+#define PE_MAGIC_ROM_IMAGE PE_ARBITRARY (0x00000107)
+#define PE_MAGIC_PE32 PE_ARBITRARY (0x0000010b)
+#define PE_MAGIC_PE32_PLUS PE_ARBITRARY (0x0000020b)
+#define PE_IMAGE_SCN_RESERVED_X00000001 PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_RESERVED_X00000002 PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_RESERVED_X00000004 PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_TYPE_NO_PAD PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_RESERVED_X00000010 PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_CNT_CODE PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_CNT_INITIALIZED_DATA PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_CNT_UNINITIALIZED_DATA PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_LNK_OTHER PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_LNK_INFO PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_RESERVED_X00000400 PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_LNK_REMOVE PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_LNK_COMDAT PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_GPREL PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_PURGEABLE PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_16BIT PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_LOCKED PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_PRELOAD PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_1BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_2BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_4BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_8BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_16BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_32BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_64BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_128BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_256BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_512BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_1024BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_2048BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_4096BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_ALIGN_8192BYTES PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_LNK_NRELOC_OVFL PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_DISCARDABLE PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_NOT_CACHED PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_NOT_PAGED PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_SHARED PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_EXECUTE PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_READ PE_BITWISE (0x00000000)
+#define PE_IMAGE_SCN_MEM_WRITE PE_BITWISE (0x00000000)
+#define PE_IMAGE_SYM_DEBUG PE_ARBITRARY ( -2)
+#define PE_IMAGE_SYM_ABSOLUTE PE_ARBITRARY ( -1)
+#define PE_IMAGE_SYM_UNDEFINED PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_SYM_CLASS_NULL PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_SYM_CLASS_AUTOMATIC PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_SYM_CLASS_EXTERNAL PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_SYM_CLASS_STATIC PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_SYM_CLASS_REGISTER PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_SYM_CLASS_EXTERNAL_DEF PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_SYM_CLASS_LABEL PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_SYM_CLASS_UNDEFINED_LABEL PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_SYM_CLASS_ARGUMENT PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_SYM_CLASS_STRUCT_TAG PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_SYM_CLASS_MEMBER_OF_UNION PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_SYM_CLASS_UNION_TAG PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_SYM_CLASS_TYPE_DEFINITION PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_SYM_CLASS_UNDEFINED_STATIC PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_SYM_CLASS_ENUM_TAG PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_SYM_CLASS_MEMBER_OF_ENUM PE_ARBITRARY (0x00000010)
+#define PE_IMAGE_SYM_CLASS_REGISTER_PARAM PE_ARBITRARY (0x00000011)
+#define PE_IMAGE_SYM_CLASS_BIT_FIELD PE_ARBITRARY (0x00000012)
+#define PE_IMAGE_SYM_CLASS_BLOCK PE_ARBITRARY (0x00000064)
+#define PE_IMAGE_SYM_CLASS_FUNCTION PE_ARBITRARY (0x00000065)
+#define PE_IMAGE_SYM_CLASS_END_OF_STRUCT PE_ARBITRARY (0x00000066)
+#define PE_IMAGE_SYM_CLASS_FILE PE_ARBITRARY (0x00000067)
+#define PE_IMAGE_SYM_CLASS_SECTION PE_ARBITRARY (0x00000068)
+#define PE_IMAGE_SYM_CLASS_WEAK_EXTERN PE_ARBITRARY (0x00000069)
+#define PE_IMAGE_SYM_CLASS_CLR_TOKEN PE_ARBITRARY (0x0000006b)
+#define PE_IMAGE_SYM_CLASS_END_OF_FUNC PE_ARBITRARY (0x000000ff)
+#define PE_IMAGE_SYM_TYPE_NULL PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_SYM_TYPE_VOID PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_SYM_TYPE_CHAR PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_SYM_TYPE_SHORT PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_SYM_TYPE_INT PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_SYM_TYPE_LONG PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_SYM_TYPE_FLOAT PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_SYM_TYPE_DOUBLE PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_SYM_TYPE_STRUCT PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_SYM_TYPE_UNION PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_SYM_TYPE_ENUM PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_SYM_TYPE_MOE PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_SYM_TYPE_BYTE PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_SYM_TYPE_WORD PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_SYM_TYPE_UINT PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_SYM_TYPE_DWORD PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_SYM_DTYPE_NULL PE_ARBITRARY (0x00000000)
+#define PE_IMAGE_SYM_DTYPE_POINTER PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_SYM_DTYPE_FUNCTION PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_SYM_DTYPE_ARRAY PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_DATA_DIR_ORDINAL_EXPORT PE_ARBITRARY (0x00000001)
+#define PE_IMAGE_DATA_DIR_ORDINAL_IMPORT PE_ARBITRARY (0x00000002)
+#define PE_IMAGE_DATA_DIR_ORDINAL_RESOURCE PE_ARBITRARY (0x00000003)
+#define PE_IMAGE_DATA_DIR_ORDINAL_EXCEPTION PE_ARBITRARY (0x00000004)
+#define PE_IMAGE_DATA_DIR_ORDINAL_CERTIFICATE PE_ARBITRARY (0x00000005)
+#define PE_IMAGE_DATA_DIR_ORDINAL_BASE_RELOCATION PE_ARBITRARY (0x00000006)
+#define PE_IMAGE_DATA_DIR_ORDINAL_DEBUG PE_ARBITRARY (0x00000007)
+#define PE_IMAGE_DATA_DIR_ORDINAL_ARCHITECTURE PE_ARBITRARY (0x00000008)
+#define PE_IMAGE_DATA_DIR_ORDINAL_GLOBAL_PTR PE_ARBITRARY (0x00000009)
+#define PE_IMAGE_DATA_DIR_ORDINAL_TLS PE_ARBITRARY (0x0000000a)
+#define PE_IMAGE_DATA_DIR_ORDINAL_LOAD_CONFIG PE_ARBITRARY (0x0000000b)
+#define PE_IMAGE_DATA_DIR_ORDINAL_BOUND_IMPORT PE_ARBITRARY (0x0000000c)
+#define PE_IMAGE_DATA_DIR_ORDINAL_IAT PE_ARBITRARY (0x0000000d)
+#define PE_IMAGE_DATA_DIR_ORDINAL_DELAY_IMPORT_DESCRIPTOR PE_ARBITRARY (0x0000000e)
+#define PE_IMAGE_DATA_DIR_ORDINAL_CLR_RUNTIME_HEADER PE_ARBITRARY (0x0000000f)
+#define PE_IMAGE_DATA_DIR_ORDINAL_RESERVED PE_ARBITRARY (0x00000010)
+
+#endif
diff --git a/include/perk/perk_meta.h b/include/perk/perk_meta.h
new file mode 100644
index 0000000..e3f3375
--- /dev/null
+++ b/include/perk/perk_meta.h
@@ -0,0 +1,222 @@
+#ifndef PERK_META_H
+#define PERK_META_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/* generic block info / image directory header */
+struct pe_block {
+ uint32_t rva;
+ uint32_t size;
+};
+
+
+/* image dos header */
+struct pe_meta_image_dos_hdr {
+ unsigned char dos_magic[2];
+ uint16_t dos_cblp;
+ uint16_t dos_cp;
+ uint16_t dos_crlc;
+ uint16_t dos_cparhdr;
+ uint16_t dos_minalloc;
+ uint16_t dos_maxalloc;
+ uint16_t dos_ss;
+ uint16_t dos_sp;
+ uint16_t dos_csum;
+ uint16_t dos_ip;
+ uint16_t dos_cs;
+ uint16_t dos_lfarlc;
+ uint16_t dos_ovno;
+ uint16_t dos_res[4];
+ uint16_t dos_oemid;
+ uint16_t dos_oeminfo;
+ uint16_t dos_res2[10];
+ uint32_t dos_lfanew;
+};
+
+
+/* pe/coff file header */
+struct pe_meta_coff_file_hdr {
+ unsigned char signature[4];
+ uint16_t machine;
+ uint16_t num_of_sections;
+ uint32_t time_date_stamp;
+ uint32_t ptr_to_sym_tbl;
+ uint32_t num_of_syms;
+ uint16_t size_of_opt_hdr;
+ uint16_t characteristics;
+};
+
+
+/* image optional header */
+struct pe_meta_opt_hdr_std {
+ uint16_t magic;
+ uint8_t major_linker_ver;
+ uint8_t minor_linker_ver;
+ uint32_t size_of_code;
+ uint32_t size_of_initialized_data;
+ uint32_t size_of_uninitialized_data;
+ uint32_t entry_point;
+ uint32_t base_of_code;
+};
+
+struct pe_meta_opt_hdr_vers {
+ uint16_t major_os_ver;
+ uint16_t minor_or_ver;
+ uint16_t major_image_ver;
+ uint16_t minor_image_ver;
+ uint16_t major_subsys_ver;
+ uint16_t minor_subsys_ver;
+ uint32_t win32_ver;
+};
+
+struct pe_meta_opt_hdr_align {
+ uint32_t section_align;
+ uint32_t file_align;
+};
+
+struct pe_meta_opt_hdr_img {
+ uint32_t size_of_image;
+ uint32_t size_of_headers;
+ uint32_t checksum;
+ uint16_t subsystem;
+ uint16_t dll_characteristics;
+};
+
+struct pe_meta_opt_hdr_ldr {
+ uint32_t loader_flags;
+ uint32_t rva_and_sizes;
+};
+
+struct pe_meta_opt_hdr_dirs {
+ struct pe_block export_tbl;
+ struct pe_block import_tbl;
+ struct pe_block resource_tbl;
+ struct pe_block exception_tbl;
+ struct pe_block certificate_tbl;
+ struct pe_block base_reloc_tbl;
+ struct pe_block debug;
+ struct pe_block arch;
+ struct pe_block global_ptr;
+ struct pe_block tls_tbl;
+ struct pe_block load_config_tbl;
+ struct pe_block bound_import;
+ struct pe_block iat;
+ struct pe_block delay_import_descriptor;
+ struct pe_block clr_runtime_hdr;
+ struct pe_block reserved;
+};
+
+struct pe_meta_opt_hdr_mem_32 {
+ uint32_t base_of_data;
+ uint32_t image_base;
+ uint32_t size_of_stack_reserve;
+ uint32_t size_of_stack_commit;
+ uint32_t size_of_heap_reserve;
+ uint32_t size_of_heap_commit;
+};
+
+struct pe_meta_opt_hdr_mem_64 {
+ uint64_t image_base;
+ uint64_t size_of_stack_reserve;
+ uint64_t size_of_stack_commit;
+ uint64_t size_of_heap_reserve;
+ uint64_t size_of_heap_commit;
+};
+
+struct pe_meta_opt_hdr_mem {
+ uint64_t base_of_data;
+ uint64_t image_base;
+ uint64_t size_of_stack_reserve;
+ uint64_t size_of_stack_commit;
+ uint64_t size_of_heap_reserve;
+ uint64_t size_of_heap_commit;
+};
+
+struct pe_meta_opt_hdr {
+ struct pe_meta_opt_hdr_std std;
+ struct pe_meta_opt_hdr_vers vers;
+ struct pe_meta_opt_hdr_align align;
+ struct pe_meta_opt_hdr_img img;
+ struct pe_meta_opt_hdr_ldr ldr;
+ struct pe_meta_opt_hdr_mem mem;
+ struct pe_meta_opt_hdr_dirs dirs;
+};
+
+
+/* section header */
+struct pe_meta_sec_hdr {
+ char name[16];
+ char * long_name;
+ uint32_t virtual_size;
+ uint32_t virtual_addr;
+ uint32_t size_of_raw_data;
+ uint32_t ptr_to_raw_data;
+ uint32_t ptr_to_relocs;
+ uint32_t ptr_to_line_nums;
+ uint16_t num_of_relocs;
+ uint16_t num_of_line_nums;
+ uint32_t characteristics;
+};
+
+
+/* .edata section header*/
+struct pe_meta_export_hdr {
+ uint32_t export_flags;
+ uint32_t time_date_stamp;
+ uint16_t major_ver;
+ uint16_t minor_ver;
+ uint32_t name_rva;
+ uint32_t ordinal_base;
+ uint32_t addr_tbl_entries;
+ uint32_t num_of_name_ptrs;
+ uint32_t export_addr_tbl_rva;
+ uint32_t name_ptr_rva;
+ uint32_t ordinal_tbl_rva;
+};
+
+
+/* export rva */
+union pe_meta_export_addr_tbl {
+ uint32_t export_rva;
+ uint32_t forwarder_rva;
+};
+
+
+/* image: import table entry lookup item */
+struct pe_meta_import_lookup_item {
+ union {
+ uint64_t import_lookup_entry_64;
+ uint32_t import_lookup_entry_32;
+ uint32_t hint_name_tbl_rva;
+ uint16_t ordinal_number;
+ } u;
+
+ uint32_t flags;
+ uint16_t hint;
+ char * name;
+};
+
+
+/* image: import directory table entry */
+struct pe_meta_import_hdr {
+ uint32_t import_lookup_tbl_rva;
+ uint32_t time_date_stamp;
+ uint32_t forwarder_chain;
+ uint32_t name_rva;
+ uint32_t import_addr_tbl_rva;
+ uint32_t count;
+ char * name;
+ struct pe_meta_import_lookup_item * items;
+ struct pe_import_lookup_item * aitems;
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/perk/perk_output.h b/include/perk/perk_output.h
new file mode 100644
index 0000000..36c6922
--- /dev/null
+++ b/include/perk/perk_output.h
@@ -0,0 +1,12 @@
+#ifndef PERK_OUTPUT_H
+#define PERK_OUTPUT_H
+
+#define PERK_OUTPUT_FORMAT_LIST 0x00000001
+#define PERK_OUTPUT_FORMAT_TABLE 0x00000002
+#define PERK_OUTPUT_FORMAT_READOBJ 0x00000004
+#define PERK_OUTPUT_FORMAT_OBJDUMP 0x00000008
+
+#define PERK_OUTPUT_FIELD_NAME 0x00000100
+#define PERK_OUTPUT_FIELD_ALL 0x80000000
+
+#endif
diff --git a/include/perk/perk_structs.h b/include/perk/perk_structs.h
new file mode 100644
index 0000000..7254250
--- /dev/null
+++ b/include/perk/perk_structs.h
@@ -0,0 +1,615 @@
+#ifndef PERK_STRUCTS_H
+#define PERK_STRUCTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* pe_image_dos_header... */
+#define PE_DOS_MAGIC_BS 0x02
+#define PE_DOS_CBLP_BS 0x02
+#define PE_DOS_CP_BS 0x02
+#define PE_DOS_CRLC_BS 0x02
+#define PE_DOS_CPARHDR_BS 0x02
+#define PE_DOS_MINALLOC_BS 0x02
+#define PE_DOS_MAXALLOC_BS 0x02
+#define PE_DOS_SS_BS 0x02
+#define PE_DOS_SP_BS 0x02
+#define PE_DOS_CSUM_BS 0x02
+#define PE_DOS_IP_BS 0x02
+#define PE_DOS_CS_BS 0x02
+#define PE_DOS_LFARLC_BS 0x02
+#define PE_DOS_OVNO_BS 0x02
+#define PE_DOS_RES_BS 0x08
+#define PE_DOS_OEMID_BS 0x02
+#define PE_DOS_OEMINFO_BS 0x02
+#define PE_DOS_RES2_BS 0x14
+#define PE_DOS_LFANEW_BS 0x04
+
+struct pe_image_dos_hdr {
+ unsigned char dos_magic [PE_DOS_MAGIC_BS]; /* 0x00 */
+ unsigned char dos_cblp [PE_DOS_CBLP_BS]; /* 0x02 */
+ unsigned char dos_cp [PE_DOS_CP_BS]; /* 0x04 */
+ unsigned char dos_crlc [PE_DOS_CRLC_BS]; /* 0x06 */
+ unsigned char dos_cparhdr [PE_DOS_CPARHDR_BS]; /* 0x08 */
+ unsigned char dos_minalloc [PE_DOS_MINALLOC_BS]; /* 0x0a */
+ unsigned char dos_maxalloc [PE_DOS_MAXALLOC_BS]; /* 0x0c */
+ unsigned char dos_ss [PE_DOS_SS_BS]; /* 0x0e */
+ unsigned char dos_sp [PE_DOS_SP_BS]; /* 0x10 */
+ unsigned char dos_csum [PE_DOS_CSUM_BS]; /* 0x12 */
+ unsigned char dos_ip [PE_DOS_IP_BS]; /* 0x14 */
+ unsigned char dos_cs [PE_DOS_CS_BS]; /* 0x16 */
+ unsigned char dos_lfarlc [PE_DOS_LFARLC_BS]; /* 0x18 */
+ unsigned char dos_ovno [PE_DOS_OVNO_BS]; /* 0x1a */
+ unsigned char dos_res [PE_DOS_RES_BS]; /* 0x1c */
+ unsigned char dos_oemid [PE_DOS_OEMID_BS]; /* 0x24 */
+ unsigned char dos_oeminfo [PE_DOS_OEMINFO_BS]; /* 0x26 */
+ unsigned char dos_res2 [PE_DOS_RES2_BS]; /* 0x28 */
+ unsigned char dos_lfanew [PE_DOS_LFANEW_BS]; /* 0x3c */
+};
+
+#undef PE_DOS_MAGIC_BS
+#undef PE_DOS_CBLP_BS
+#undef PE_DOS_CP_BS
+#undef PE_DOS_CRLC_BS
+#undef PE_DOS_CPARHDR_BS
+#undef PE_DOS_MINALLOC_BS
+#undef PE_DOS_MAXALLOC_BS
+#undef PE_DOS_SS_BS
+#undef PE_DOS_SP_BS
+#undef PE_DOS_CSUM_BS
+#undef PE_DOS_IP_BS
+#undef PE_DOS_CS_BS
+#undef PE_DOS_LFARLC_BS
+#undef PE_DOS_OVNO_BS
+#undef PE_DOS_RES_BS
+#undef PE_DOS_OEMID_BS
+#undef PE_DOS_OEMINFO_BS
+#undef PE_DOS_RES2_BS
+#undef PE_DOS_LFANEW_BS
+
+
+/* pe_coff_file_header... */
+#define PE_SIGNATURE_BS 0x04
+#define PE_MACHINE_BS 0x02
+#define PE_NUMBER_OF_SECTIONS_BS 0x02
+#define PE_TIME_DATE_STAMP_BS 0x04
+#define PE_POINTER_TO_SYMBOL_TABLE_BS 0x04
+#define PE_NUMBER_OF_SYMBOLS_BS 0x04
+#define PE_SIZE_OF_OPTIONAL_HEADER_BS 0x02
+#define PE_CHARACTERISTICS_BS 0x02
+
+struct pe_coff_file_hdr {
+ unsigned char signature [PE_SIGNATURE_BS]; /* 0x00 */
+ unsigned char machine [PE_MACHINE_BS]; /* 0x04 */
+ unsigned char num_of_sections [PE_NUMBER_OF_SECTIONS_BS]; /* 0x06 */
+ unsigned char time_date_stamp [PE_TIME_DATE_STAMP_BS]; /* 0x08 */
+ unsigned char ptr_to_sym_tbl [PE_POINTER_TO_SYMBOL_TABLE_BS]; /* 0x0c */
+ unsigned char num_of_syms [PE_NUMBER_OF_SYMBOLS_BS]; /* 0x10 */
+ unsigned char size_of_opt_hdr [PE_SIZE_OF_OPTIONAL_HEADER_BS]; /* 0x14 */
+ unsigned char characteristics [PE_CHARACTERISTICS_BS]; /* 0x16 */
+};
+
+#undef PE_SIGNATURE_BS
+#undef PE_MACHINE_BS
+#undef PE_NUMBER_OF_SECTIONS_BS
+#undef PE_TIME_DATE_STAMP_BS
+#undef PE_POINTER_TO_SYMBOL_TABLE_BS
+#undef PE_NUMBER_OF_SYMBOLS_BS
+#undef PE_SIZE_OF_OPTIONAL_HEADER_BS
+#undef PE_CHARACTERISTICS_BS
+
+
+/* pe32_optional_header... */
+#define PE_MAGIC_BS 0x02
+#define PE_MAJOR_LINKER_VERSION_BS 0x01
+#define PE_MINOR_LINKER_VERSION_BS 0x01
+#define PE_SIZE_OF_CODE_BS 0x04
+#define PE_SIZE_OF_INITIALIZED_DATA_BS 0x04
+#define PE_SIZE_OF_UNINITIALIZED_DATA_BS 0x04
+#define PE_ADDRESS_OF_ENTRY_POINT_BS 0x04
+#define PE_BASE_OF_CODE_BS 0x04
+#define PE_BASE_OF_DATA_BS 0x04
+#define PE_IMAGE_BASE_BS 0x04
+#define PE_SECTION_ALIGNMENT_BS 0x04
+#define PE_FILE_ALIGNMENT_BS 0x04
+#define PE_MAJOR_OPERATING_SYSTEM_VERSION_BS 0x02
+#define PE_MINOR_OPERATING_SYSTEM_VERSION_BS 0x02
+#define PE_MAJOR_IMAGE_VERSION_BS 0x02
+#define PE_MINOR_IMAGE_VERSION_BS 0x02
+#define PE_MAJOR_SUBSYSTEM_VERSION_BS 0x02
+#define PE_MINOR_SUBSYSTEM_VERSION_BS 0x02
+#define PE_WIN32_VERSION_VALUE_BS 0x04
+#define PE_SIZE_OF_IMAGE_BS 0x04
+#define PE_SIZE_OF_HEADERS_BS 0x04
+#define PE_CHECK_SUM_BS 0x04
+#define PE_SUBSYSTEM_BS 0x02
+#define PE_DLL_CHARACTERISTICS_BS 0x02
+#define PE_SIZE_OF_STACK_RESERVE_BS 0x04
+#define PE_SIZE_OF_STACK_COMMIT_BS 0x04
+#define PE_SIZE_OF_HEAP_RESERVE_BS 0x04
+#define PE_SIZE_OF_HEAP_COMMIT_BS 0x04
+#define PE_LOADER_FLAGS_BS 0x04
+#define PE_NUMBER_OF_RVA_AND_SIZES_BS 0x04
+#define PE_EXPORT_TABLE_BS 0x08
+#define PE_IMPORT_TABLE_BS 0x08
+#define PE_RESOURCE_TABLE_BS 0x08
+#define PE_EXCEPTION_TABLE_BS 0x08
+#define PE_CERTIFICATE_TABLE_BS 0x08
+#define PE_BASE_RELOCATION_TABLE_BS 0x08
+#define PE_DEBUG_BS 0x08
+#define PE_ARCHITECTURE_BS 0x08
+#define PE_GLOBAL_PTR_BS 0x08
+#define PE_TLS_TABLE_BS 0x08
+#define PE_LOAD_CONFIG_TABLE_BS 0x08
+#define PE_BOUND_IMPORT_BS 0x08
+#define PE_IAT_BS 0x08
+#define PE_DELAY_IMPORT_DESCRIPTOR_BS 0x08
+#define PE_CLR_RUNTIME_HEADER_BS 0x08
+#define PE_RESERVED__MUST_BE_ZERO_BS 0x08
+
+struct pe_opt_hdr_std {
+ unsigned char magic [PE_MAGIC_BS]; /* 0x00 */
+ unsigned char major_linker_ver [PE_MAJOR_LINKER_VERSION_BS]; /* 0x02 */
+ unsigned char minor_linker_ver [PE_MINOR_LINKER_VERSION_BS]; /* 0x03 */
+ unsigned char size_of_code [PE_SIZE_OF_CODE_BS]; /* 0x04 */
+ unsigned char size_of_initialized_data [PE_SIZE_OF_INITIALIZED_DATA_BS]; /* 0x08 */
+ unsigned char size_of_uninitialized_data [PE_SIZE_OF_UNINITIALIZED_DATA_BS]; /* 0x0c */
+ unsigned char entry_point [PE_ADDRESS_OF_ENTRY_POINT_BS]; /* 0x10 */
+ unsigned char base_of_code [PE_BASE_OF_CODE_BS]; /* 0x14 */
+};
+
+struct pe_opt_hdr_align {
+ unsigned char section_align [PE_SECTION_ALIGNMENT_BS]; /* 0x20 */
+ unsigned char file_align [PE_FILE_ALIGNMENT_BS]; /* 0x24 */
+};
+
+struct pe_opt_hdr_vers {
+ unsigned char major_os_ver [PE_MAJOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x28 */
+ unsigned char minor_or_ver [PE_MINOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x2a */
+ unsigned char major_image_ver [PE_MAJOR_IMAGE_VERSION_BS]; /* 0x2c */
+ unsigned char minor_image_ver [PE_MINOR_IMAGE_VERSION_BS]; /* 0x2e */
+ unsigned char major_subsys_ver [PE_MAJOR_SUBSYSTEM_VERSION_BS]; /* 0x30 */
+ unsigned char minor_subsys_ver [PE_MINOR_SUBSYSTEM_VERSION_BS]; /* 0x32 */
+ unsigned char win32_ver [PE_WIN32_VERSION_VALUE_BS]; /* 0x34 */
+};
+
+struct pe_opt_hdr_img {
+ unsigned char size_of_image [PE_SIZE_OF_IMAGE_BS]; /* 0x38 */
+ unsigned char size_of_headers [PE_SIZE_OF_HEADERS_BS]; /* 0x3c */
+ unsigned char checksum [PE_CHECK_SUM_BS]; /* 0x40 */
+ unsigned char subsystem [PE_SUBSYSTEM_BS]; /* 0x44 */
+ unsigned char dll_characteristics [PE_DLL_CHARACTERISTICS_BS]; /* 0x46 */
+};
+
+struct pe_opt_hdr_ldr {
+ unsigned char loader_flags [PE_LOADER_FLAGS_BS];
+ unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS];
+};
+
+struct pe_opt_hdr_dirs {
+ unsigned char export_tbl [PE_EXPORT_TABLE_BS];
+ unsigned char import_tbl [PE_IMPORT_TABLE_BS];
+ unsigned char resource_tbl [PE_RESOURCE_TABLE_BS];
+ unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS];
+ unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS];
+ unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS];
+ unsigned char debug [PE_DEBUG_BS];
+ unsigned char arch [PE_ARCHITECTURE_BS];
+ unsigned char global_ptr [PE_GLOBAL_PTR_BS];
+ unsigned char tls_tbl [PE_TLS_TABLE_BS];
+ unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS];
+ unsigned char bound_import [PE_BOUND_IMPORT_BS];
+ unsigned char iat [PE_IAT_BS];
+ unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS];
+ unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS];
+ unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS];
+};
+
+struct pe_opt_hdr_32 {
+ unsigned char magic [PE_MAGIC_BS]; /* 0x00 */
+ unsigned char major_linker_ver [PE_MAJOR_LINKER_VERSION_BS]; /* 0x02 */
+ unsigned char minor_linker_ver [PE_MINOR_LINKER_VERSION_BS]; /* 0x03 */
+ unsigned char size_of_code [PE_SIZE_OF_CODE_BS]; /* 0x04 */
+ unsigned char size_of_initialized_data [PE_SIZE_OF_INITIALIZED_DATA_BS]; /* 0x08 */
+ unsigned char size_of_uninitialized_data [PE_SIZE_OF_UNINITIALIZED_DATA_BS]; /* 0x0c */
+ unsigned char entry_point [PE_ADDRESS_OF_ENTRY_POINT_BS]; /* 0x10 */
+ unsigned char base_of_code [PE_BASE_OF_CODE_BS]; /* 0x14 */
+ unsigned char base_of_data [PE_BASE_OF_DATA_BS]; /* 0x18 */
+ unsigned char image_base [PE_IMAGE_BASE_BS]; /* 0x1c */
+ unsigned char section_align [PE_SECTION_ALIGNMENT_BS]; /* 0x20 */
+ unsigned char file_align [PE_FILE_ALIGNMENT_BS]; /* 0x24 */
+ unsigned char major_os_ver [PE_MAJOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x28 */
+ unsigned char minor_or_ver [PE_MINOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x2a */
+ unsigned char major_image_ver [PE_MAJOR_IMAGE_VERSION_BS]; /* 0x2c */
+ unsigned char minor_image_ver [PE_MINOR_IMAGE_VERSION_BS]; /* 0x2e */
+ unsigned char major_subsys_ver [PE_MAJOR_SUBSYSTEM_VERSION_BS]; /* 0x30 */
+ unsigned char minor_subsys_ver [PE_MINOR_SUBSYSTEM_VERSION_BS]; /* 0x32 */
+ unsigned char win32_ver [PE_WIN32_VERSION_VALUE_BS]; /* 0x34 */
+ unsigned char size_of_image [PE_SIZE_OF_IMAGE_BS]; /* 0x38 */
+ unsigned char size_of_headers [PE_SIZE_OF_HEADERS_BS]; /* 0x3c */
+ unsigned char checksum [PE_CHECK_SUM_BS]; /* 0x40 */
+ unsigned char subsystem [PE_SUBSYSTEM_BS]; /* 0x44 */
+ unsigned char dll_characteristics [PE_DLL_CHARACTERISTICS_BS]; /* 0x46 */
+ unsigned char size_of_stack_reserve [PE_SIZE_OF_STACK_RESERVE_BS]; /* 0x48 */
+ unsigned char size_of_stack_commit [PE_SIZE_OF_STACK_COMMIT_BS]; /* 0x4c */
+ unsigned char size_of_heap_reserve [PE_SIZE_OF_HEAP_RESERVE_BS]; /* 0x50 */
+ unsigned char size_of_heap_commit [PE_SIZE_OF_HEAP_COMMIT_BS]; /* 0x54 */
+ unsigned char loader_flags [PE_LOADER_FLAGS_BS]; /* 0x58 */
+ unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS]; /* 0x5c */
+ unsigned char export_tbl [PE_EXPORT_TABLE_BS]; /* 0x60 */
+ unsigned char import_tbl [PE_IMPORT_TABLE_BS]; /* 0x68 */
+ unsigned char resource_tbl [PE_RESOURCE_TABLE_BS]; /* 0x70 */
+ unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS]; /* 0x78 */
+ unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS]; /* 0x80 */
+ unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS]; /* 0x88 */
+ unsigned char debug [PE_DEBUG_BS]; /* 0x90 */
+ unsigned char arch [PE_ARCHITECTURE_BS]; /* 0x98 */
+ unsigned char global_ptr [PE_GLOBAL_PTR_BS]; /* 0xa0 */
+ unsigned char tls_tbl [PE_TLS_TABLE_BS]; /* 0xa8 */
+ unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS]; /* 0xb0 */
+ unsigned char bound_import [PE_BOUND_IMPORT_BS]; /* 0xb8 */
+ unsigned char iat [PE_IAT_BS]; /* 0xc0 */
+ unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS]; /* 0xc8 */
+ unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS]; /* 0xd0 */
+ unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS]; /* 0xd8 */
+};
+
+#undef PE_MAGIC_BS
+#undef PE_MAJOR_LINKER_VERSION_BS
+#undef PE_MINOR_LINKER_VERSION_BS
+#undef PE_SIZE_OF_CODE_BS
+#undef PE_SIZE_OF_INITIALIZED_DATA_BS
+#undef PE_SIZE_OF_UNINITIALIZED_DATA_BS
+#undef PE_ADDRESS_OF_ENTRY_POINT_BS
+#undef PE_BASE_OF_CODE_BS
+#undef PE_BASE_OF_DATA_BS
+#undef PE_IMAGE_BASE_BS
+#undef PE_SECTION_ALIGNMENT_BS
+#undef PE_FILE_ALIGNMENT_BS
+#undef PE_MAJOR_OPERATING_SYSTEM_VERSION_BS
+#undef PE_MINOR_OPERATING_SYSTEM_VERSION_BS
+#undef PE_MAJOR_IMAGE_VERSION_BS
+#undef PE_MINOR_IMAGE_VERSION_BS
+#undef PE_MAJOR_SUBSYSTEM_VERSION_BS
+#undef PE_MINOR_SUBSYSTEM_VERSION_BS
+#undef PE_WIN32_VERSION_VALUE_BS
+#undef PE_SIZE_OF_IMAGE_BS
+#undef PE_SIZE_OF_HEADERS_BS
+#undef PE_CHECK_SUM_BS
+#undef PE_SUBSYSTEM_BS
+#undef PE_DLL_CHARACTERISTICS_BS
+#undef PE_SIZE_OF_STACK_RESERVE_BS
+#undef PE_SIZE_OF_STACK_COMMIT_BS
+#undef PE_SIZE_OF_HEAP_RESERVE_BS
+#undef PE_SIZE_OF_HEAP_COMMIT_BS
+#undef PE_LOADER_FLAGS_BS
+#undef PE_NUMBER_OF_RVA_AND_SIZES_BS
+#undef PE_EXPORT_TABLE_BS
+#undef PE_IMPORT_TABLE_BS
+#undef PE_RESOURCE_TABLE_BS
+#undef PE_EXCEPTION_TABLE_BS
+#undef PE_CERTIFICATE_TABLE_BS
+#undef PE_BASE_RELOCATION_TABLE_BS
+#undef PE_DEBUG_BS
+#undef PE_ARCHITECTURE_BS
+#undef PE_GLOBAL_PTR_BS
+#undef PE_TLS_TABLE_BS
+#undef PE_LOAD_CONFIG_TABLE_BS
+#undef PE_BOUND_IMPORT_BS
+#undef PE_IAT_BS
+#undef PE_DELAY_IMPORT_DESCRIPTOR_BS
+#undef PE_CLR_RUNTIME_HEADER_BS
+#undef PE_RESERVED__MUST_BE_ZERO_BS
+
+
+/* pe64_optional_header... */
+#define PE_MAGIC_BS 0x02
+#define PE_MAJOR_LINKER_VERSION_BS 0x01
+#define PE_MINOR_LINKER_VERSION_BS 0x01
+#define PE_SIZE_OF_CODE_BS 0x04
+#define PE_SIZE_OF_INITIALIZED_DATA_BS 0x04
+#define PE_SIZE_OF_UNINITIALIZED_DATA_BS 0x04
+#define PE_ADDRESS_OF_ENTRY_POINT_BS 0x04
+#define PE_BASE_OF_CODE_BS 0x04
+#define PE_IMAGE_BASE_BS 0x08
+#define PE_SECTION_ALIGNMENT_BS 0x04
+#define PE_FILE_ALIGNMENT_BS 0x04
+#define PE_MAJOR_OPERATING_SYSTEM_VERSION_BS 0x02
+#define PE_MINOR_OPERATING_SYSTEM_VERSION_BS 0x02
+#define PE_MAJOR_IMAGE_VERSION_BS 0x02
+#define PE_MINOR_IMAGE_VERSION_BS 0x02
+#define PE_MAJOR_SUBSYSTEM_VERSION_BS 0x02
+#define PE_MINOR_SUBSYSTEM_VERSION_BS 0x02
+#define PE_WIN32_VERSION_VALUE_BS 0x04
+#define PE_SIZE_OF_IMAGE_BS 0x04
+#define PE_SIZE_OF_HEADERS_BS 0x04
+#define PE_CHECK_SUM_BS 0x04
+#define PE_SUBSYSTEM_BS 0x02
+#define PE_DLL_CHARACTERISTICS_BS 0x02
+#define PE_SIZE_OF_STACK_RESERVE_BS 0x08
+#define PE_SIZE_OF_STACK_COMMIT_BS 0x08
+#define PE_SIZE_OF_HEAP_RESERVE_BS 0x08
+#define PE_SIZE_OF_HEAP_COMMIT_BS 0x08
+#define PE_LOADER_FLAGS_BS 0x04
+#define PE_NUMBER_OF_RVA_AND_SIZES_BS 0x04
+#define PE_EXPORT_TABLE_BS 0x08
+#define PE_IMPORT_TABLE_BS 0x08
+#define PE_RESOURCE_TABLE_BS 0x08
+#define PE_EXCEPTION_TABLE_BS 0x08
+#define PE_CERTIFICATE_TABLE_BS 0x08
+#define PE_BASE_RELOCATION_TABLE_BS 0x08
+#define PE_DEBUG_BS 0x08
+#define PE_ARCHITECTURE_BS 0x08
+#define PE_GLOBAL_PTR_BS 0x08
+#define PE_TLS_TABLE_BS 0x08
+#define PE_LOAD_CONFIG_TABLE_BS 0x08
+#define PE_BOUND_IMPORT_BS 0x08
+#define PE_IAT_BS 0x08
+#define PE_DELAY_IMPORT_DESCRIPTOR_BS 0x08
+#define PE_CLR_RUNTIME_HEADER_BS 0x08
+#define PE_RESERVED__MUST_BE_ZERO_BS 0x08
+
+struct pe_opt_hdr_64 {
+ unsigned char magic [PE_MAGIC_BS]; /* 0x00 */
+ unsigned char major_linker_ver [PE_MAJOR_LINKER_VERSION_BS]; /* 0x02 */
+ unsigned char minor_linker_ver [PE_MINOR_LINKER_VERSION_BS]; /* 0x03 */
+ unsigned char size_of_code [PE_SIZE_OF_CODE_BS]; /* 0x04 */
+ unsigned char size_of_initialized_data [PE_SIZE_OF_INITIALIZED_DATA_BS]; /* 0x08 */
+ unsigned char size_of_uninitialized_data [PE_SIZE_OF_UNINITIALIZED_DATA_BS]; /* 0x0c */
+ unsigned char entry_point [PE_ADDRESS_OF_ENTRY_POINT_BS]; /* 0x10 */
+ unsigned char base_of_code [PE_BASE_OF_CODE_BS]; /* 0x14 */
+ unsigned char image_base [PE_IMAGE_BASE_BS]; /* 0x18 */
+ unsigned char section_align [PE_SECTION_ALIGNMENT_BS]; /* 0x20 */
+ unsigned char file_align [PE_FILE_ALIGNMENT_BS]; /* 0x24 */
+ unsigned char major_os_ver [PE_MAJOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x28 */
+ unsigned char minor_or_ver [PE_MINOR_OPERATING_SYSTEM_VERSION_BS]; /* 0x2a */
+ unsigned char major_image_ver [PE_MAJOR_IMAGE_VERSION_BS]; /* 0x2c */
+ unsigned char minor_image_ver [PE_MINOR_IMAGE_VERSION_BS]; /* 0x2e */
+ unsigned char major_subsys_ver [PE_MAJOR_SUBSYSTEM_VERSION_BS]; /* 0x30 */
+ unsigned char minor_subsys_ver [PE_MINOR_SUBSYSTEM_VERSION_BS]; /* 0x32 */
+ unsigned char win32_ver [PE_WIN32_VERSION_VALUE_BS]; /* 0x34 */
+ unsigned char size_of_image [PE_SIZE_OF_IMAGE_BS]; /* 0x38 */
+ unsigned char size_of_headers [PE_SIZE_OF_HEADERS_BS]; /* 0x3c */
+ unsigned char checksum [PE_CHECK_SUM_BS]; /* 0x40 */
+ unsigned char subsystem [PE_SUBSYSTEM_BS]; /* 0x44 */
+ unsigned char dll_characteristics [PE_DLL_CHARACTERISTICS_BS]; /* 0x46 */
+ unsigned char size_of_stack_reserve [PE_SIZE_OF_STACK_RESERVE_BS]; /* 0x48 */
+ unsigned char size_of_stack_commit [PE_SIZE_OF_STACK_COMMIT_BS]; /* 0x50 */
+ unsigned char size_of_heap_reserve [PE_SIZE_OF_HEAP_RESERVE_BS]; /* 0x58 */
+ unsigned char size_of_heap_commit [PE_SIZE_OF_HEAP_COMMIT_BS]; /* 0x60 */
+ unsigned char loader_flags [PE_LOADER_FLAGS_BS]; /* 0x68 */
+ unsigned char rva_and_sizes [PE_NUMBER_OF_RVA_AND_SIZES_BS]; /* 0x6c */
+ unsigned char export_tbl [PE_EXPORT_TABLE_BS]; /* 0x70 */
+ unsigned char import_tbl [PE_IMPORT_TABLE_BS]; /* 0x78 */
+ unsigned char resource_tbl [PE_RESOURCE_TABLE_BS]; /* 0x80 */
+ unsigned char exception_tbl [PE_EXCEPTION_TABLE_BS]; /* 0x88 */
+ unsigned char certificate_tbl [PE_CERTIFICATE_TABLE_BS]; /* 0x90 */
+ unsigned char base_reloc_tbl [PE_BASE_RELOCATION_TABLE_BS]; /* 0x98 */
+ unsigned char debug [PE_DEBUG_BS]; /* 0xa0 */
+ unsigned char arch [PE_ARCHITECTURE_BS]; /* 0xa8 */
+ unsigned char global_ptr [PE_GLOBAL_PTR_BS]; /* 0xb0 */
+ unsigned char tls_tbl [PE_TLS_TABLE_BS]; /* 0xb8 */
+ unsigned char load_config_tbl [PE_LOAD_CONFIG_TABLE_BS]; /* 0xc0 */
+ unsigned char bound_import [PE_BOUND_IMPORT_BS]; /* 0xc8 */
+ unsigned char iat [PE_IAT_BS]; /* 0xd0 */
+ unsigned char delay_import_descriptor [PE_DELAY_IMPORT_DESCRIPTOR_BS]; /* 0xd8 */
+ unsigned char clr_runtime_hdr [PE_CLR_RUNTIME_HEADER_BS]; /* 0xe0 */
+ unsigned char reserved [PE_RESERVED__MUST_BE_ZERO_BS]; /* 0xe8 */
+};
+
+#undef PE_MAGIC_BS
+#undef PE_MAJOR_LINKER_VERSION_BS
+#undef PE_MINOR_LINKER_VERSION_BS
+#undef PE_SIZE_OF_CODE_BS
+#undef PE_SIZE_OF_INITIALIZED_DATA_BS
+#undef PE_SIZE_OF_UNINITIALIZED_DATA_BS
+#undef PE_ADDRESS_OF_ENTRY_POINT_BS
+#undef PE_BASE_OF_CODE_BS
+#undef PE_IMAGE_BASE_BS
+#undef PE_SECTION_ALIGNMENT_BS
+#undef PE_FILE_ALIGNMENT_BS
+#undef PE_MAJOR_OPERATING_SYSTEM_VERSION_BS
+#undef PE_MINOR_OPERATING_SYSTEM_VERSION_BS
+#undef PE_MAJOR_IMAGE_VERSION_BS
+#undef PE_MINOR_IMAGE_VERSION_BS
+#undef PE_MAJOR_SUBSYSTEM_VERSION_BS
+#undef PE_MINOR_SUBSYSTEM_VERSION_BS
+#undef PE_WIN32_VERSION_VALUE_BS
+#undef PE_SIZE_OF_IMAGE_BS
+#undef PE_SIZE_OF_HEADERS_BS
+#undef PE_CHECK_SUM_BS
+#undef PE_SUBSYSTEM_BS
+#undef PE_DLL_CHARACTERISTICS_BS
+#undef PE_SIZE_OF_STACK_RESERVE_BS
+#undef PE_SIZE_OF_STACK_COMMIT_BS
+#undef PE_SIZE_OF_HEAP_RESERVE_BS
+#undef PE_SIZE_OF_HEAP_COMMIT_BS
+#undef PE_LOADER_FLAGS_BS
+#undef PE_NUMBER_OF_RVA_AND_SIZES_BS
+#undef PE_EXPORT_TABLE_BS
+#undef PE_IMPORT_TABLE_BS
+#undef PE_RESOURCE_TABLE_BS
+#undef PE_EXCEPTION_TABLE_BS
+#undef PE_CERTIFICATE_TABLE_BS
+#undef PE_BASE_RELOCATION_TABLE_BS
+#undef PE_DEBUG_BS
+#undef PE_ARCHITECTURE_BS
+#undef PE_GLOBAL_PTR_BS
+#undef PE_TLS_TABLE_BS
+#undef PE_LOAD_CONFIG_TABLE_BS
+#undef PE_BOUND_IMPORT_BS
+#undef PE_IAT_BS
+#undef PE_DELAY_IMPORT_DESCRIPTOR_BS
+#undef PE_CLR_RUNTIME_HEADER_BS
+#undef PE_RESERVED__MUST_BE_ZERO_BS
+
+union pe_opt_hdr {
+ struct pe_opt_hdr_32 opt_hdr_32;
+ struct pe_opt_hdr_64 opt_hdr_64;
+};
+
+
+/* pe_image_data_directory... */
+#define PE_VIRTUAL_ADDRESS_BS 0x04
+#define PE_SIZE_BS 0x04
+
+struct pe_image_data_dir {
+ unsigned char rva [PE_VIRTUAL_ADDRESS_BS]; /* 0x00 */
+ unsigned char size [PE_SIZE_BS]; /* 0x04 */
+};
+
+#undef PE_VIRTUAL_ADDRESS_BS
+#undef PE_SIZE_BS
+
+
+/* pe_section_table... */
+#define PE_NAME_BS 0x08
+#define PE_VIRTUAL_SIZE_BS 0x04
+#define PE_VIRTUAL_ADDRESS_BS 0x04
+#define PE_SIZE_OF_RAW_DATA_BS 0x04
+#define PE_POINTER_TO_RAW_DATA_BS 0x04
+#define PE_POINTER_TO_RELOCATIONS_BS 0x04
+#define PE_POINTER_TO_LINENUMBERS_BS 0x04
+#define PE_NUMBER_OF_RELOCATIONS_BS 0x02
+#define PE_NUMBER_OF_LINENUMBERS_BS 0x02
+#define PE_CHARACTERISTICS_BS 0x04
+
+struct pe_sec_hdr {
+ unsigned char name [PE_NAME_BS]; /* 0x00 */
+ unsigned char virtual_size [PE_VIRTUAL_SIZE_BS]; /* 0x08 */
+ unsigned char virtual_addr [PE_VIRTUAL_ADDRESS_BS]; /* 0x0c */
+ unsigned char size_of_raw_data [PE_SIZE_OF_RAW_DATA_BS]; /* 0x10 */
+ unsigned char ptr_to_raw_data [PE_POINTER_TO_RAW_DATA_BS]; /* 0x14 */
+ unsigned char ptr_to_relocs [PE_POINTER_TO_RELOCATIONS_BS]; /* 0x18 */
+ unsigned char ptr_to_line_nums [PE_POINTER_TO_LINENUMBERS_BS]; /* 0x1c */
+ unsigned char num_of_relocs [PE_NUMBER_OF_RELOCATIONS_BS]; /* 0x20 */
+ unsigned char num_of_line_nums [PE_NUMBER_OF_LINENUMBERS_BS]; /* 0x22 */
+ unsigned char characteristics [PE_CHARACTERISTICS_BS]; /* 0x24 */
+};
+
+#undef PE_NAME_BS
+#undef PE_VIRTUAL_SIZE_BS
+#undef PE_VIRTUAL_ADDRESS_BS
+#undef PE_SIZE_OF_RAW_DATA_BS
+#undef PE_POINTER_TO_RAW_DATA_BS
+#undef PE_POINTER_TO_RELOCATIONS_BS
+#undef PE_POINTER_TO_LINENUMBERS_BS
+#undef PE_NUMBER_OF_RELOCATIONS_BS
+#undef PE_NUMBER_OF_LINENUMBERS_BS
+#undef PE_CHARACTERISTICS_BS
+
+
+/* pe_export_directory_table... */
+#define PE_EXPORT_FLAGS_BS 0x04
+#define PE_TIME_DATE_STAMP_BS 0x04
+#define PE_MAJOR_VERSION_BS 0x02
+#define PE_MINOR_VERSION_BS 0x02
+#define PE_NAME_RVA_BS 0x04
+#define PE_ORDINAL_BASE_BS 0x04
+#define PE_ADDRESS_TABLE_ENTRIES_BS 0x04
+#define PE_NUMBER_OF_NAME_POINTERS_BS 0x04
+#define PE_EXPORT_ADDRESS_TABLE_RVA_BS 0x04
+#define PE_NAME_POINTER_RVA_BS 0x04
+#define PE_ORDINAL_TABLE_RVA_BS 0x04
+
+struct pe_export_hdr {
+ unsigned char export_flags [PE_EXPORT_FLAGS_BS]; /* 0x00 */
+ unsigned char time_date_stamp [PE_TIME_DATE_STAMP_BS]; /* 0x04 */
+ unsigned char major_ver [PE_MAJOR_VERSION_BS]; /* 0x08 */
+ unsigned char minor_ver [PE_MINOR_VERSION_BS]; /* 0x0a */
+ unsigned char name_rva [PE_NAME_RVA_BS]; /* 0x0c */
+ unsigned char ordinal_base [PE_ORDINAL_BASE_BS]; /* 0x10 */
+ unsigned char addr_tbl_entries [PE_ADDRESS_TABLE_ENTRIES_BS]; /* 0x14 */
+ unsigned char num_of_name_ptrs [PE_NUMBER_OF_NAME_POINTERS_BS]; /* 0x18 */
+ unsigned char export_addr_tbl_rva [PE_EXPORT_ADDRESS_TABLE_RVA_BS]; /* 0x1c */
+ unsigned char name_ptr_rva [PE_NAME_POINTER_RVA_BS]; /* 0x20 */
+ unsigned char ordinal_tbl_rva [PE_ORDINAL_TABLE_RVA_BS]; /* 0x24 */
+};
+
+#undef PE_EXPORT_FLAGS_BS
+#undef PE_TIME_DATE_STAMP_BS
+#undef PE_MAJOR_VERSION_BS
+#undef PE_MINOR_VERSION_BS
+#undef PE_NAME_RVA_BS
+#undef PE_ORDINAL_BASE_BS
+#undef PE_ADDRESS_TABLE_ENTRIES_BS
+#undef PE_NUMBER_OF_NAME_POINTERS_BS
+#undef PE_EXPORT_ADDRESS_TABLE_RVA_BS
+#undef PE_NAME_POINTER_RVA_BS
+#undef PE_ORDINAL_TABLE_RVA_BS
+
+
+/* pe_export_address_table... */
+#define PE_EXPORT_RVA_BS 0x04
+#define PE_FORWARDER_RVA_BS 0x04
+
+union pe_export_addr_tbl {
+ unsigned char export_rva [PE_EXPORT_RVA_BS]; /* 0x00 */
+ unsigned char forwarder_rva [PE_FORWARDER_RVA_BS]; /* 0x00 */
+};
+
+#undef PE_EXPORT_RVA_BS
+#undef PE_FORWARDER_RVA_BS
+
+
+/* image: pe_import_table_entry_lookup_item... */
+#define PE_IMPORT_LOOKUP_ENTRY_PE64_BS 0x08
+#define PE_IMPORT_LOOKUP_ENTRY_PE32_BS 0x04
+#define PE_HINT_NAME_TABLE_RVA_BS 0x04
+#define PE_ORDINAL_NUMBER_BS 0x02
+
+struct pe_import_lookup_item {
+ union {
+ unsigned char import_lookup_entry_64 [PE_IMPORT_LOOKUP_ENTRY_PE64_BS]; /* 0x00 */
+ unsigned char import_lookup_entry_32 [PE_IMPORT_LOOKUP_ENTRY_PE32_BS]; /* 0x00 */
+ unsigned char hint_name_tbl_rva [PE_HINT_NAME_TABLE_RVA_BS]; /* 0x00 */
+ unsigned char ordinal_number [PE_ORDINAL_NUMBER_BS]; /* 0x00 */
+ } u;
+};
+
+#undef PE_IMPORT_LOOKUP_ENTRY_PE64_BS
+#undef PE_IMPORT_LOOKUP_ENTRY_PE32_BS
+#undef PE_HINT_NAME_TABLE_RVA_BS
+#undef PE_ORDINAL_NUMBER_BS
+
+
+/* image: pe_import_directory_table_entry... */
+#define PE_IMPORT_LOOKUP_TABLE_RVA_BS 0x04
+#define PE_TIME_DATE_STAMP_BS 0x04
+#define PE_FORWARDER_CHAIN_BS 0x04
+#define PE_NAME_RVA_BS 0x04
+#define PE_IMPORT_ADDRESS_TABLE_RVA_BS 0x04
+
+struct pe_import_hdr {
+ unsigned char import_lookup_tbl_rva [PE_IMPORT_LOOKUP_TABLE_RVA_BS]; /* 0x00 */
+ unsigned char time_date_stamp [PE_TIME_DATE_STAMP_BS]; /* 0x04 */
+ unsigned char forwarder_chain [PE_FORWARDER_CHAIN_BS]; /* 0x08 */
+ unsigned char name_rva [PE_NAME_RVA_BS]; /* 0x0c */
+ unsigned char import_addr_tbl_rva [PE_IMPORT_ADDRESS_TABLE_RVA_BS]; /* 0x10 */
+};
+
+#undef PE_IMPORT_LOOKUP_TABLE_RVA_BS
+#undef PE_TIME_DATE_STAMP_BS
+#undef PE_FORWARDER_CHAIN_BS
+#undef PE_NAME_RVA_BS
+#undef PE_IMPORT_ADDRESS_TABLE_RVA_BS
+
+
+/* pe_hint_name_table_padded... */
+#define PE_HINT_BS 0x02
+#define PE_NAME_BS 0x02
+
+struct pe_hint_name_entry {
+ unsigned char hint [PE_HINT_BS]; /* 0x00 */
+ unsigned char name [PE_NAME_BS]; /* 0x02 */
+};
+
+#undef PE_HINT_BS
+#undef PE_NAME_BS
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/internal/perk_impl.h b/src/internal/perk_impl.h
new file mode 100644
index 0000000..497ddbe
--- /dev/null
+++ b/src/internal/perk_impl.h
@@ -0,0 +1,64 @@
+#ifndef PERK_IMPL_H
+#define PERK_IMPL_H
+
+#include <stdint.h>
+#include <endian.h>
+
+/* internal structures */
+struct perk_ctx {
+ int argc;
+ char ** argv;
+ char ** envp;
+ const char * fname;
+ int status;
+ int flags;
+ int fd;
+ FILE * fout;
+ FILE * tmp;
+ struct pe_raw_image map;
+};
+
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+
+static inline uint16_t pe_read_short(const unsigned char * raw)
+{
+ return *(uint16_t *)raw;
+}
+
+static inline uint32_t pe_read_long(const unsigned char * raw)
+{
+ return *(uint32_t *)raw;
+}
+
+static inline uint64_t pe_read_quad(const unsigned char * raw)
+{
+ return *(uint64_t *)raw;
+}
+
+#else
+
+static inline uint16_t pe_read_short(unsigned char * raw)
+{
+ uint16_t x = *(uint16_t *)raw;
+ return x<<8 | x>>8;
+}
+
+static inline uint32_t pe_swap_long(uint32_t x)
+{
+ return x<<24 | (x<<8) & 0xff0000 | (x>>8) & 0xff00 | x>>24;
+}
+
+static inline uint32_t pe_read_long(unsigned char * raw)
+{
+ return pe_swap_long(*(uint32_t *)raw);
+}
+
+static inline uint64_t pe_read_quad(unsigned char * raw)
+{
+ uint64_t x = *(uint64_t *)raw;
+ return ((uint64_t)pe_swap_long(x)<<32) | pe_swap_long(x>>32);
+}
+
+#endif
+
+#endif
diff --git a/src/main/pe_get_image_meta.c b/src/main/pe_get_image_meta.c
new file mode 100644
index 0000000..454f233
--- /dev/null
+++ b/src/main/pe_get_image_meta.c
@@ -0,0 +1,184 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+static int pe_free_image_meta_impl (struct pe_image_meta * meta, int status)
+{
+ if (!meta) return 0;
+
+ free(meta->sectbl);
+ free(meta);
+
+ return status;
+}
+
+int pe_free_image_meta (struct pe_image_meta * meta)
+{
+ return pe_free_image_meta_impl(meta,0);
+}
+
+int pe_get_named_section_index (const struct pe_image_meta * m, const char * name)
+{
+ int i; for (i=0; i<m->coff.num_of_sections; i++)
+ if (!(strcmp(name,m->sectbl[i].name)))
+ return i;
+
+ return -1;
+}
+
+int pe_get_block_section_index (const struct pe_image_meta * m, const struct pe_block * block)
+{
+ int i;
+ uint32_t low,high;
+
+ for (i=0; i<m->coff.num_of_sections; i++) {
+ low = m->sectbl[i].virtual_addr;
+ high = low + m->sectbl[i].virtual_size;
+
+ if ((block->rva >= low) && (block->rva + block->size <= high))
+ return i;
+ }
+
+ return -1;
+}
+
+int pe_get_image_meta (const struct pe_raw_image * image, struct pe_image_meta ** meta)
+{
+ int i,j,s,status;
+ struct pe_image_meta * m;
+ char * base = image->addr;
+
+ if (!(m = calloc(1,sizeof(*m))))
+ return errno;
+
+ m->ados = (struct pe_image_dos_hdr *)base;
+
+ if ((status = (pe_read_dos_header(m->ados,&m->dos))))
+ return pe_free_image_meta_impl(m,status);
+
+ m->acoff = (struct pe_coff_file_hdr *)(base + m->dos.dos_lfanew);
+
+ if ((status = (pe_read_coff_header(m->acoff,&m->coff))))
+ return pe_free_image_meta_impl(m,status);
+
+ m->aopt = (union pe_opt_hdr *)((char *)m->acoff + sizeof(m->coff));
+
+ if ((status = (pe_read_optional_header(m->aopt,&m->opt))))
+ return pe_free_image_meta_impl(m,status);
+
+ m->asectbl = (struct pe_sec_hdr *)((char *)m->aopt + m->coff.size_of_opt_hdr);
+
+ if (!(m->sectbl = calloc(m->coff.num_of_sections,sizeof(*(m->sectbl)))))
+ return pe_free_image_meta_impl(m,status);
+
+ for (i=0; i<m->coff.num_of_sections; i++)
+ pe_read_section_header(&m->asectbl[i],&m->sectbl[i]);
+
+ /* .edata */
+ i = pe_get_named_section_index(m,".edata");
+ s = pe_get_block_section_index(m,&m->opt.dirs.export_tbl);
+
+ if ((i >= 0) && (i != s))
+ return pe_free_image_meta_impl(m,PERK_MALFORMED_IMAGE);
+
+ if (i >= 0 ) {
+ m->hedata = &m->sectbl[i];
+ m->aedata = (struct pe_export_hdr *)(base + m->sectbl[i].ptr_to_raw_data);
+ } else if (s >= 0) {
+ m->hedata = &m->sectbl[s];
+ m->aedata = (struct pe_export_hdr *)(base + m->sectbl[s].ptr_to_raw_data
+ + m->opt.dirs.export_tbl.rva - m->sectbl[s].virtual_addr);
+ }
+
+ if (m->aedata)
+ pe_read_export_header(m->aedata,&m->edata);
+
+ /* .idata */
+ struct pe_import_hdr * pidata;
+ struct pe_import_lookup_item * pitem;
+
+ i = pe_get_named_section_index(m,".idata");
+ s = pe_get_block_section_index(m,&m->opt.dirs.import_tbl);
+
+ if ((i >= 0) && (i != s))
+ return pe_free_image_meta_impl(m,PERK_MALFORMED_IMAGE);
+
+ if (i >= 0 ) {
+ m->hidata = &m->sectbl[i];
+ m->aidata = (struct pe_import_hdr *)(base + m->sectbl[i].ptr_to_raw_data);
+ } else if (s >= 0) {
+ m->hidata = &m->sectbl[s];
+ m->aidata = (struct pe_import_hdr *)(base + m->sectbl[s].ptr_to_raw_data
+ + m->opt.dirs.import_tbl.rva - m->sectbl[s].virtual_addr);
+ }
+
+ if (m->aidata) {
+ /* num of implibs */
+ for (pidata=m->aidata; pidata->name_rva[0]; pidata++,m->summary.num_of_implibs++);
+
+ /* import headers */
+ if (!(m->idata = calloc(m->summary.num_of_implibs,sizeof(*(m->idata)))))
+ return pe_free_image_meta_impl(m,status);
+
+ for (i=0; i<m->summary.num_of_implibs; i++) {
+ pe_read_import_header(&m->aidata[i],&m->idata[i]);
+
+ m->idata[i].name = base + m->hidata->ptr_to_raw_data
+ + m->idata[i].name_rva - m->hidata->virtual_addr;
+
+ m->idata[i].aitems = (struct pe_import_lookup_item *)(base + m->hidata->ptr_to_raw_data
+ + m->idata[i].import_lookup_tbl_rva - m->hidata->virtual_addr);
+
+ printf("%s\n",m->idata[i].name);
+
+ /* items */
+ m->idata[i].count = 0;
+ for (pitem=m->idata[i].aitems; *(uint32_t *)pitem->u.hint_name_tbl_rva; pitem++)
+ m->idata[i].count++;
+
+ if (!(m->idata[i].items = calloc(m->idata[i].count,sizeof(*(m->idata[i].items)))))
+ return pe_free_image_meta_impl(m,status);
+
+ for (j=0; j<m->idata[i].count; j++) {
+ if ((status = pe_read_import_lookup_item(
+ &(m->idata[i].aitems[j]),
+ &(m->idata[i].items[j]),
+ m->opt.std.magic)))
+ return pe_free_image_meta_impl(m,status);
+
+ switch (m->opt.std.magic) {
+ case PE_MAGIC_PE32:
+ m->idata[i].items[j].flags = m->idata[i].items[j].u.import_lookup_entry_32;
+ break;
+
+ case PE_MAGIC_PE32_PLUS:
+ m->idata[i].items[j].flags = (m->idata[i].items[j].u.import_lookup_entry_64 >> 32);
+ break;
+ }
+
+ struct pe_hint_name_entry * pentry = (struct pe_hint_name_entry *)(base + m->hidata->ptr_to_raw_data
+ + m->idata[i].items[j].u.hint_name_tbl_rva - m->hidata->virtual_addr);
+
+ if (m->idata[i].items[j].flags)
+ m->idata[i].items[j].hint = pe_read_short(pentry->hint);
+ else {
+ m->idata[i].items[j].name = (char *)pentry->name;
+ printf("%s\n",m->idata[i].items[j].name);
+ }
+ }
+ }
+ }
+
+ /* image */
+ m->image.addr = image->addr;
+ m->image.size = image->size;
+
+ /* all done */
+ *meta = m;
+ return 0;
+}
diff --git a/src/main/pe_map_raw_image.c b/src/main/pe_map_raw_image.c
new file mode 100644
index 0000000..8ae95d9
--- /dev/null
+++ b/src/main/pe_map_raw_image.c
@@ -0,0 +1,40 @@
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <perk/perk.h>
+
+int pe_map_raw_image (int fd, const char * fname, struct pe_raw_image * map)
+{
+ struct stat stat;
+ int nfd, ret;
+
+ if ((nfd = !fd))
+ fd = open(fname,O_RDONLY | O_CLOEXEC);
+
+ if ((fd < 0) || (fstat(fd,&stat) < 0))
+ return errno;
+
+ map->size = stat.st_size;
+ map->addr = (char *)mmap(0,map->size,PROT_READ,MAP_PRIVATE,fd,0);
+
+ if (map->addr == MAP_FAILED) {
+ map->addr = 0;
+ ret = PERK_MAP_ERROR;
+ } else
+ ret = 0;
+
+ if (nfd) close(fd);
+
+ return ret;
+}
+
+int pe_unmap_raw_image (struct pe_raw_image * map)
+{
+ return munmap(map->addr, map->size);
+};
diff --git a/src/main/perk.c b/src/main/perk.c
new file mode 100644
index 0000000..5fe8f17
--- /dev/null
+++ b/src/main/perk.c
@@ -0,0 +1,116 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+static int perk_parse_opts(struct perk_ctx * ctx)
+{
+ int i;
+ char * ch;
+ const char ** popt;
+
+ for (i=1; i<ctx->argc; i++) {
+ ch = ctx->argv[i];
+
+ if (*ch == '-') {
+ switch (*++ch) {
+ case 'i':
+ popt = &ctx->fname;
+ break;
+ case 'h':
+ ctx->flags = PERK_HELP;
+ return 0;
+ default:
+ ctx->status = PERK_BAD_OPT;
+ return ctx->status;
+ }
+
+ while ((*++ch == '\t') || (*ch == ' '));
+
+ if (!*ch) {
+ if (++i < ctx->argc)
+ *popt = ctx->argv[i];
+ else
+ ctx->status = PERK_BAD_OPT_VAL;
+ } else
+ *popt = ch;
+ } else if (!ctx->fname)
+ ctx->fname = ch;
+ else
+ ctx->status = PERK_BAD_OPT;
+
+ }
+
+ return ctx->status;
+}
+
+
+static int perk_map_input(struct perk_ctx * ctx)
+{
+ ctx->fd = open(ctx->fname,O_RDONLY | O_CLOEXEC);
+
+ if (ctx->fd < 0) {
+ ctx->status = PERK_IO_ERROR;
+ return ctx->status;
+ }
+
+ ctx->status = pe_map_raw_image(ctx->fd,0,&ctx->map);
+
+ return ctx->status;
+}
+
+
+static int perk_exit(struct perk_ctx * ctx)
+{
+ if (ctx->map.addr)
+ pe_unmap_raw_image(&ctx->map);
+
+ return ctx->status;
+}
+
+
+static int perk_run(struct perk_ctx * ctx)
+{
+ struct pe_image_meta * meta;
+
+ if (perk_map_input(ctx))
+ return perk_exit(ctx);
+
+ if ((ctx->status = pe_get_image_meta(&ctx->map,&meta)))
+ return perk_exit(ctx);
+
+ /* pre-alpha default output */
+ pe_output_export_symbols(
+ meta,
+ PERK_OUTPUT_FORMAT_LIST | PERK_OUTPUT_FIELD_NAME,
+ stdout);
+
+ ctx->status = pe_free_image_meta(meta);
+
+ return perk_exit(ctx);
+}
+
+static int perk_main(int argc, char * argv[], char * envp[])
+{
+ struct perk_ctx ctx = {argc,argv,envp};
+
+ if (perk_parse_opts(&ctx))
+ return ctx.status;
+ else
+ return perk_run(&ctx);
+}
+
+#ifdef PERK_APP
+extern __typeof(perk_main) main __attribute__((alias("perk_main")));
+#endif
diff --git a/src/output/pe_output_export_symbols.c b/src/output/pe_output_export_symbols.c
new file mode 100644
index 0000000..192bca3
--- /dev/null
+++ b/src/output/pe_output_export_symbols.c
@@ -0,0 +1,24 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <perk/perk.h>
+
+int pe_output_export_symbols (const struct pe_image_meta * m, uint32_t flags, FILE * f)
+{
+ uint32_t offset;
+ uint32_t * symrva;
+ int i;
+
+ if (!m->hedata) return 0;
+
+ offset = m->hedata->virtual_addr - m->hedata->ptr_to_raw_data;
+ symrva = (uint32_t *)(m->image.addr + (m->edata.name_ptr_rva - offset));
+
+ for (i=0; i<m->edata.num_of_name_ptrs; i++)
+ fprintf(f,"%s\n",(char *)(m->image.addr + symrva[i] - offset));
+
+ return 0;
+}
diff --git a/src/reader/pe_read_coff_header.c b/src/reader/pe_read_coff_header.c
new file mode 100644
index 0000000..e7bdf8a
--- /dev/null
+++ b/src/reader/pe_read_coff_header.c
@@ -0,0 +1,37 @@
+#include <endian.h>
+#include <string.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+int pe_read_coff_header(const struct pe_coff_file_hdr * p, struct pe_meta_coff_file_hdr * m)
+{
+ if ((p->signature[0] != 'P') || (p->signature[1] != 'E')
+ || *(uint16_t *)&p->signature[2])
+ return PERK_BAD_COFF_HEADER;
+
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+
+ memcpy(m,p,sizeof(*p));
+
+ #else
+
+ m->signature[0] = p->signature[0];
+ m->signature[1] = p->signature[1];
+ m->signature[2] = p->signature[2];
+ m->signature[3] = p->signature[3];
+
+ m->machine = pe_read_short(p->machine);
+ m->num_of_sections = pe_read_short(p->num_of_sections);
+
+ m->time_date_stamp = pe_read_long(p->time_date_stamp);
+ m->ptr_to_sym_tbl = pe_read_long(p->ptr_to_sym_tbl);
+ m->num_of_syms = pe_read_long(p->num_of_syms);
+
+ m->size_of_opt_hdr = pe_read_short(p->size_of_opt_hdr);
+ m->characteristics = pe_read_short(p->characteristics);
+
+ #endif
+
+ return 0;
+};
diff --git a/src/reader/pe_read_dos_header.c b/src/reader/pe_read_dos_header.c
new file mode 100644
index 0000000..75b7d31
--- /dev/null
+++ b/src/reader/pe_read_dos_header.c
@@ -0,0 +1,52 @@
+#include <endian.h>
+#include <string.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+int pe_read_dos_header(const struct pe_image_dos_hdr * p, struct pe_meta_image_dos_hdr * m)
+{
+ int i;
+
+ if ((p->dos_magic[0] != 'M') || (p->dos_magic[1] != 'Z'))
+ return PERK_BAD_DOS_HEADER;
+
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+
+ memcpy(m,p,sizeof(*p));
+
+ #else
+
+ m->dos_magic[0] = p->dos_magic[0];
+ m->dos_magic[1] = p->dos_magic[1];
+
+ m->dos_cblp = pe_read_short(p->dos_cblp);
+ m->dos_cp = pe_read_short(p->dos_cp);
+ m->dos_crlc = pe_read_short(p->dos_crlc);
+ m->dos_cparhdr = pe_read_short(p->dos_cparhdr);
+ m->dos_minalloc = pe_read_short(p->dos_minalloc);
+ m->dos_maxalloc = pe_read_short(p->dos_maxalloc);
+ m->dos_ss = pe_read_short(p->dos_ss);
+ m->dos_sp = pe_read_short(p->dos_sp);
+ m->dos_csum = pe_read_short(p->dos_csum);
+ m->dos_ip = pe_read_short(p->dos_ip);
+ m->dos_cs = pe_read_short(p->dos_cs);
+ m->dos_lfarlc = pe_read_short(p->dos_lfarlc);
+ m->dos_ovno = pe_read_short(p->dos_ovno);
+
+
+ for (i=0; i<4; i++)
+ m->dos_res[i] = pe_read_short(&p->dos_res[2*i]);
+
+ m->dos_oemid = pe_read_short(p->dos_oemid);
+ m->dos_oeminfo = pe_read_short(p->dos_oeminfo);
+
+ for (i=0; i<10; i++)
+ m->dos_res2[i] = pe_read_short(&p->dos_res2[2*i]);
+
+ m->dos_lfanew = pe_read_long(p->dos_lfanew);
+
+ #endif
+
+ return 0;
+};
diff --git a/src/reader/pe_read_export_header.c b/src/reader/pe_read_export_header.c
new file mode 100644
index 0000000..6a959c9
--- /dev/null
+++ b/src/reader/pe_read_export_header.c
@@ -0,0 +1,32 @@
+#include <endian.h>
+#include <string.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+int pe_read_export_header(const struct pe_export_hdr * p, struct pe_meta_export_hdr * m)
+{
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+
+ memcpy(m,p,sizeof(*p));
+
+ #else
+
+ m->export_flags = pe_read_long(p->export_flags);
+ m->time_date_stamp = pe_read_long(p->time_date_stamp);
+
+ m->major_ver = pe_read_short(p->major_ver);
+ m->minor_ver = pe_read_short(p->minor_ver);
+
+ m->name_rva = pe_read_long(p->name_rva);
+ m->ordinal_base = pe_read_long(p->ordinal_base);
+ m->addr_tbl_entries = pe_read_long(p->addr_tbl_entries);
+ m->num_of_name_ptrs = pe_read_long(p->num_of_name_ptrs);
+ m->export_addr_tbl_rva = pe_read_long(p->export_addr_tbl_rva);
+ m->name_ptr_rva = pe_read_long(p->name_ptr_rva);
+ m->ordinal_tbl_rva = pe_read_long(p->ordinal_tbl_rva);
+
+ #endif
+
+ return 0;
+};
diff --git a/src/reader/pe_read_import_header.c b/src/reader/pe_read_import_header.c
new file mode 100644
index 0000000..7d71143
--- /dev/null
+++ b/src/reader/pe_read_import_header.c
@@ -0,0 +1,46 @@
+#include <endian.h>
+#include <string.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+int pe_read_import_header(const struct pe_import_hdr * p, struct pe_meta_import_hdr * m)
+{
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+
+ memcpy(m,p,sizeof(*p));
+
+ #else
+
+ m->import_lookup_tbl_rva = pe_read_long(p->import_lookup_tbl_rva);
+ m->time_date_stamp = pe_read_long(p->time_date_stamp);
+ m->forwarder_chain = pe_read_long(p>forwarder_chain);
+ m->name_rva = pe_read_long(p->name_rva);
+ m->import_addr_tbl_rva = pe_read_long(p>import_addr_tbl_rva);
+
+ #endif
+
+ m->name = 0;
+ m->aitems = 0;
+
+ return 0;
+};
+
+int pe_read_import_lookup_item(
+ const struct pe_import_lookup_item * p,
+ struct pe_meta_import_lookup_item * m,
+ uint32_t magic)
+{
+ switch (magic) {
+ case PE_MAGIC_PE32:
+ m->u.import_lookup_entry_64 = pe_read_long(p->u.import_lookup_entry_32);
+ return 0;
+
+ case PE_MAGIC_PE32_PLUS:
+ m->u.import_lookup_entry_64 = pe_read_quad(p->u.import_lookup_entry_64);
+ return 0;
+
+ default:
+ return PERK_BAD_IMAGE_TYPE;
+ }
+};
diff --git a/src/reader/pe_read_optional_header.c b/src/reader/pe_read_optional_header.c
new file mode 100644
index 0000000..701c6a9
--- /dev/null
+++ b/src/reader/pe_read_optional_header.c
@@ -0,0 +1,139 @@
+#include <endian.h>
+#include <string.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+int pe_read_optional_header(const union pe_opt_hdr * p, struct pe_meta_opt_hdr * m)
+{
+ struct pe_opt_hdr_std * astd;
+ struct pe_opt_hdr_vers * avers;
+ struct pe_opt_hdr_align * aalign;
+ struct pe_opt_hdr_img * aimg;
+ struct pe_opt_hdr_ldr * aldr;
+ struct pe_opt_hdr_dirs * adirs;
+ size_t sdirs;
+
+ m->std.magic = pe_read_short(p->opt_hdr_32.magic);
+ memset(&m->dirs,0,sizeof(m->dirs));
+
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+
+ memcpy(&m->std,p,sizeof(struct pe_meta_opt_hdr_std));
+
+ switch (m->std.magic) {
+ case PE_MAGIC_PE32:
+ memcpy(&m->vers,&p->opt_hdr_32.major_os_ver,sizeof(struct pe_meta_opt_hdr_vers));
+ memcpy(&m->align,&p->opt_hdr_32.section_align,sizeof(struct pe_meta_opt_hdr_align));
+ memcpy(&m->img,&p->opt_hdr_32.size_of_image,sizeof(struct pe_meta_opt_hdr_img));
+ memcpy(&m->ldr,&p->opt_hdr_32.loader_flags,sizeof(struct pe_meta_opt_hdr_ldr));
+
+ if (m->ldr.rva_and_sizes > 0x10)
+ return PERK_BAD_IMAGE_TYPE;
+ else
+ memcpy(&m->dirs,&p->opt_hdr_32.export_tbl,sizeof(struct pe_meta_opt_hdr_dirs));
+
+ break;
+
+ case PE_MAGIC_PE32_PLUS:
+ memcpy(&m->vers,&p->opt_hdr_64.major_os_ver,sizeof(struct pe_meta_opt_hdr_vers));
+ memcpy(&m->align,&p->opt_hdr_64.section_align,sizeof(struct pe_meta_opt_hdr_align));
+ memcpy(&m->img,&p->opt_hdr_64.size_of_image,sizeof(struct pe_meta_opt_hdr_img));
+ memcpy(&m->ldr,&p->opt_hdr_64.loader_flags,sizeof(struct pe_meta_opt_hdr_ldr));
+
+ if (m->ldr.rva_and_sizes > 0x10)
+ return PERK_BAD_IMAGE_TYPE;
+ else
+ memcpy(&m->dirs,&p->opt_hdr_64.export_tbl,sizeof(struct pe_meta_opt_hdr_dirs));
+
+ break;
+
+ default:
+ return PERK_BAD_IMAGE_TYPE;
+ };
+
+ #else
+
+ astd = (struct pe_opt_hdr_std *)p;
+
+ switch (m->std.magic) {
+ case PE_MAGIC_PE32:
+ avers = (struct pe_opt_hdr_std *)&p->opt_hdr_32.major_os_ver;
+ aalign = (struct pe_opt_hdr_std *)&p->opt_hdr_32.section_align;
+ aimg = (struct pe_opt_hdr_img *)&p->opt_hdr_32.size_of_image;
+ aldr = (struct pe_opt_hdr_ldr *)&p->opt_hdr_32.loader_flags;
+ adirs = (struct pe_opt_hdr_dirs *)&p->opt_hdr_32.export_tbl;
+ break;
+
+ case PE_MAGIC_PE32_PLUS:
+ avers = (struct pe_opt_hdr_std *)&p->opt_hdr_64.major_os_ver;
+ aalign = (struct pe_opt_hdr_std *)&p->opt_hdr_64.section_align;
+ aimg = (struct pe_opt_hdr_img *)&p->opt_hdr_64.size_of_image;
+ aldr = (struct pe_opt_hdr_ldr *)&p->opt_hdr_64.loader_flags;
+ adirs = (struct pe_opt_hdr_dirs *)&p->opt_hdr_64.export_tbl;
+ break;
+
+ default:
+ return PERK_BAD_IMAGE_TYPE;
+ }
+
+ /* std */
+ m->std.major_linker_ver = astd->major_linker_ver;
+ m->std.minor_linker_ver = astd->minor_linker_ver;
+
+ m->std.size_of_code = pe_read_long(astd->size_of_code);
+ m->std.size_of_initialized_data = pe_read_long(astd->size_of_initialized_data);
+ m->std.size_of_uninitialized_data = pe_read_long(astd->size_of_uninitialized_data);
+ m->std.entry_point = pe_read_long(astd->entry_point);
+ m->std.base_of_code = pe_read_long(astd->base_of_code);
+
+ /* vers */
+ m->vers.major_os_ver = pe_read_short(avers->major_os_ver);
+ m->vers.minor_os_ver = pe_read_short(avers->minor_os_ver);
+ m->vers.major_image_ver = pe_read_short(avers->major_image_ver);
+ m->vers.minor_image_ver = pe_read_short(avers->minor_image_ver);
+ m->vers.major_subsys_ver = pe_read_short(avers->major_subsys_ver);
+ m->vers.minor_subsys_ver = pe_read_short(avers->minor_subsys_ver);
+
+ m->vers.win32_ver = pe_read_long(avers->win32_ver);
+
+ /* align */
+ m->align.section_align = pe_read_long(aalign->section_align);
+ m->align.file_align = pe_read_long(aalign->file_align);
+
+ /* img */
+ m->img.size_of_image = pe_read_long(aimg->size_of_image);
+ m->img.size_of_headers = pe_read_long(aimg->size_of_headers);
+ m->img.checksum = pe_read_long(aimg->checksum);
+
+ m->img.subsystem = pe_read_short(aimg->subsystem);
+ m->img.dll_characteristics = pe_read_short(aimg->dll_characteristics);
+
+ /* ldr */
+ m->ldr.loader_flags = pe_read_long(aldr->loader_flags);
+ m->ldr.rva_and_sizes = pe_read_long(aldr->rva_and_sizes);
+
+ #endif
+
+ switch (m->std.magic) {
+ case PE_MAGIC_PE32:
+ m->mem.base_of_data = pe_read_long(p->opt_hdr_32.base_of_data);
+ m->mem.image_base = pe_read_long(p->opt_hdr_32.image_base);
+ m->mem.size_of_stack_reserve = pe_read_long(p->opt_hdr_32.size_of_stack_reserve);
+ m->mem.size_of_stack_commit = pe_read_long(p->opt_hdr_32.size_of_stack_commit);
+ m->mem.size_of_heap_reserve = pe_read_long(p->opt_hdr_32.size_of_heap_reserve);
+ m->mem.size_of_heap_commit = pe_read_long(p->opt_hdr_32.size_of_heap_commit);
+ break;
+
+ case PE_MAGIC_PE32_PLUS:
+ m->mem.base_of_data = (uint64_t)-1;
+ m->mem.image_base = pe_read_quad(p->opt_hdr_64.image_base);
+ m->mem.size_of_stack_reserve = pe_read_quad(p->opt_hdr_64.size_of_stack_reserve);
+ m->mem.size_of_stack_commit = pe_read_quad(p->opt_hdr_64.size_of_stack_commit);
+ m->mem.size_of_heap_reserve = pe_read_quad(p->opt_hdr_64.size_of_heap_reserve);
+ m->mem.size_of_heap_commit = pe_read_quad(p->opt_hdr_64.size_of_heap_commit);
+ break;
+ };
+
+ return 0;
+};
diff --git a/src/reader/pe_read_section_header.c b/src/reader/pe_read_section_header.c
new file mode 100644
index 0000000..1a37f63
--- /dev/null
+++ b/src/reader/pe_read_section_header.c
@@ -0,0 +1,37 @@
+#include <endian.h>
+#include <string.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+int pe_read_section_header(const struct pe_sec_hdr * p, struct pe_meta_sec_hdr * m)
+{
+ /* name: meta struct conveniently contains null termination */
+ memset(m,0,sizeof(m->name));
+ memcpy(m,p,sizeof(p->name));
+
+ /* todo: long name support */
+ m->long_name = 0;
+
+ #if (BYTE_ORDER == LITTLE_ENDIAN)
+
+ memcpy(&m->virtual_size,&p->virtual_size,sizeof(*p)-sizeof(p->name));
+
+ #else
+
+ m->virtual_size = pe_read_long(p->virtual_size);
+ m->virtual_addr = pe_read_long(p->virtual_addr);
+ m->size_of_raw_data = pe_read_long(p->size_of_raw_data);
+ m->ptr_to_raw_data = pe_read_long(p->ptr_to_raw_data);
+ m->ptr_to_relocs = pe_read_long(p->ptr_to_relocs);
+ m->ptr_to_line_nums = pe_read_long(p->ptr_to_linu_nums);
+
+ m->num_of_relocs = pe_read_short(p->num_of_relocs);
+ m->num_of_line_nums = pe_read_short(p->num_of_line_nums);
+
+ m->characteristics = pe_read_long(p->characteristics);
+
+ #endif
+
+ return 0;
+};