From 9f74016e0deb3e5052bdc8f9a957c643fcc019cd Mon Sep 17 00:00:00 2001 From: Jozef Kolek <jkolek@gmail.com> Date: Wed, 12 Apr 2017 00:24:03 +0200 Subject: [PATCH 1/2] Perform endian swap as needed --- parser-library/buffer.cpp | 47 ++++++++++++++++++++++++++++++------- parser-library/nt-headers.h | 43 +++++++++++++++++++++++++++++++++ parser-library/parse.cpp | 30 +++++++++++++++++++++++ parser-library/parse.h | 4 ++++ 4 files changed, 116 insertions(+), 8 deletions(-) diff --git a/parser-library/buffer.cpp b/parser-library/buffer.cpp index 309d6ab..90fb98f 100644 --- a/parser-library/buffer.cpp +++ b/parser-library/buffer.cpp @@ -36,6 +36,28 @@ THE SOFTWARE. #include <unistd.h> #endif +namespace { + +inline uint16_t byteSwapUint16(uint16_t val) { + uint16_t a = (val >> 8) & 0x00FFU; + uint16_t b = (val << 8) & 0xFF00U; + return a | b; +} + +inline uint32_t byteSwapUint32(uint32_t val) { + uint32_t a = byteSwapUint16(val >> 16) & 0x0000FFFFU; + uint32_t b = ((static_cast<uint32_t>(byteSwapUint16(val))) << 16) & 0xFFFF0000U; + return a | b; +} + +inline uint64_t byteSwapUint64(uint64_t val) { + uint64_t a = byteSwapUint32(val >> 32) & 0x00000000FFFFFFFFUL; + uint64_t b = ((static_cast<uint64_t>(byteSwapUint32(val))) << 32) & 0xFFFFFFFF00000000UL; + return a | b; +} + +} // anonymous namespace + using namespace std; namespace peparse { @@ -67,7 +89,6 @@ bool readByte(bounded_buffer *b, ::uint32_t offset, ::uint8_t &out) { return true; } -// TODO: perform endian swap as needed bool readWord(bounded_buffer *b, ::uint32_t offset, ::uint16_t &out) { if (b == nullptr) { return false; @@ -78,12 +99,15 @@ bool readWord(bounded_buffer *b, ::uint32_t offset, ::uint16_t &out) { } ::uint16_t *tmp = reinterpret_cast<uint16_t *>(b->buf + offset); - out = *tmp; + if (b->swapBytes) { + out = byteSwapUint16(*tmp); + } else { + out = *tmp; + } return true; } -// TODO: perform endian swap as needed bool readDword(bounded_buffer *b, ::uint32_t offset, ::uint32_t &out) { if (b == nullptr) { return false; @@ -94,12 +118,15 @@ bool readDword(bounded_buffer *b, ::uint32_t offset, ::uint32_t &out) { } ::uint32_t *tmp = reinterpret_cast<uint32_t *>(b->buf + offset); - out = *tmp; + if (b->swapBytes) { + out = byteSwapUint32(*tmp); + } else { + out = *tmp; + } return true; } -// TODO: perform endian swap as needed bool readQword(bounded_buffer *b, ::uint32_t offset, ::uint64_t &out) { if (b == nullptr) { return false; @@ -110,7 +137,11 @@ bool readQword(bounded_buffer *b, ::uint32_t offset, ::uint64_t &out) { } ::uint64_t *tmp = reinterpret_cast<uint64_t *>(b->buf + offset); - out = *tmp; + if (b->swapBytes) { + out = byteSwapUint64(*tmp); + } else { + out = *tmp; + } return true; } @@ -187,7 +218,6 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) { p->buf = (::uint8_t *) ptr; p->bufLen = fileSize; - p->copy = false; #else p->detail->fd = fd; @@ -213,8 +243,9 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) { p->buf = reinterpret_cast<uint8_t *>(maddr); p->bufLen = s.st_size; - p->copy = false; #endif + p->copy = false; + p->swapBytes = false; return p; } diff --git a/parser-library/nt-headers.h b/parser-library/nt-headers.h index 993ff63..7adb3b6 100644 --- a/parser-library/nt-headers.h +++ b/parser-library/nt-headers.h @@ -55,6 +55,49 @@ const std::uint16_t DIR_IAT = 12; const std::uint16_t DIR_DELAY_IMPORT = 13; const std::uint16_t DIR_COM_DESCRIPTOR = 14; +// Machine Types +const std::uint16_t IMAGE_FILE_MACHINE_UNKNOWN = 0x0; +const std::uint16_t IMAGE_FILE_MACHINE_AM33 = 0x1d3; // Matsushita AM33 +const std::uint16_t IMAGE_FILE_MACHINE_AMD64 = 0x8664; // x64 +const std::uint16_t IMAGE_FILE_MACHINE_ARM = 0x1c0; // ARM little endian +const std::uint16_t IMAGE_FILE_MACHINE_ARM64 = 0xaa64; // ARM64 little endian +const std::uint16_t IMAGE_FILE_MACHINE_ARMNT = 0x1c4; // ARM Thumb-2 little endian +const std::uint16_t IMAGE_FILE_MACHINE_EBC = 0xebc; // EFI byte code +const std::uint16_t IMAGE_FILE_MACHINE_I386 = 0x14c; // Intel 386 or later processors and compatible processors +const std::uint16_t IMAGE_FILE_MACHINE_IA64 = 0x200; // Intel Itanium processor family +const std::uint16_t IMAGE_FILE_MACHINE_M32R = 0x9041; // Mitsubishi M32R little endian +const std::uint16_t IMAGE_FILE_MACHINE_MIPS16 = 0x266; // MIPS16 +const std::uint16_t IMAGE_FILE_MACHINE_MIPSFPU = 0x366; // MIPS with FPU +const std::uint16_t IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466; // MIPS16 with FPU +const std::uint16_t IMAGE_FILE_MACHINE_POWERPC = 0x1f0; // Power PC little endian +const std::uint16_t IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1; // Power PC with floating point support +const std::uint16_t IMAGE_FILE_MACHINE_R4000 = 0x166; // MIPS little endian +const std::uint16_t IMAGE_FILE_MACHINE_RISCV32 = 0x5032; // RISC-V 32-bit address space +const std::uint16_t IMAGE_FILE_MACHINE_RISCV64 = 0x5064; // RISC-V 64-bit address space +const std::uint16_t IMAGE_FILE_MACHINE_RISCV128 = 0x5128; // RISC-V 128-bit address space +const std::uint16_t IMAGE_FILE_MACHINE_SH3 = 0x1a2; // Hitachi SH3 +const std::uint16_t IMAGE_FILE_MACHINE_SH3DSP = 0x1a3; // Hitachi SH3 DSP +const std::uint16_t IMAGE_FILE_MACHINE_SH4 = 0x1a6; // Hitachi SH4 +const std::uint16_t IMAGE_FILE_MACHINE_SH5 = 0x1a8; // Hitachi SH5 +const std::uint16_t IMAGE_FILE_MACHINE_THUMB = 0x1c2; // Thumb +const std::uint16_t IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169; // MIPS little-endian WCE v2 + +const std::uint16_t IMAGE_FILE_RELOCS_STRIPPED = 0x0001; +const std::uint16_t IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002; +const std::uint16_t IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004; +const std::uint16_t IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008; +const std::uint16_t IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010; +const std::uint16_t IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020; +const std::uint16_t IMAGE_FILE_BYTES_REVERSED_LO = 0x0080; +const std::uint16_t IMAGE_FILE_32BIT_MACHINE = 0x0100; +const std::uint16_t IMAGE_FILE_DEBUG_STRIPPED = 0x0200; +const std::uint16_t IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400; +const std::uint16_t IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800; +const std::uint16_t IMAGE_FILE_SYSTEM = 0x1000; +const std::uint16_t IMAGE_FILE_DLL = 0x2000; +const std::uint16_t IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000; +const std::uint16_t IMAGE_FILE_BYTES_REVERSED_HI = 0x8000; + const std::uint32_t IMAGE_SCN_TYPE_NO_PAD = 0x00000008; const std::uint32_t IMAGE_SCN_CNT_CODE = 0x00000020; const std::uint32_t IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040; diff --git a/parser-library/parse.cpp b/parser-library/parse.cpp index d90714f..2dc7c1e 100644 --- a/parser-library/parse.cpp +++ b/parser-library/parse.cpp @@ -585,6 +585,36 @@ bool readNtHeader(bounded_buffer *b, nt_header_32 &header) { return false; } + if (TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_AMD64, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_ARM, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_ARM64, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_ARMNT, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_I386, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_M32R, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_POWERPC, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_R4000, + IMAGE_FILE_BYTES_REVERSED_HI) || + TEST_MACHINE_CHARACTERISTICS(header, + IMAGE_FILE_MACHINE_WCEMIPSV2, + IMAGE_FILE_BYTES_REVERSED_HI)) { + b->swapBytes = true; + } + /* * The buffer is split using the OptionalHeader offset, even if it turns * out to be a PE32+. The start of the buffer is at the same spot in the diff --git a/parser-library/parse.h b/parser-library/parse.h index 4a72cd7..842fcf0 100644 --- a/parser-library/parse.h +++ b/parser-library/parse.h @@ -76,6 +76,9 @@ THE SOFTWARE. return NULL; \ } +#define TEST_MACHINE_CHARACTERISTICS(h, m, ch) \ + ((h.FileHeader.Machine == m) && (h.FileHeader.Characteristics & ch)) + namespace peparse { typedef std::uint32_t RVA; @@ -87,6 +90,7 @@ typedef struct _bounded_buffer { std::uint8_t *buf; std::uint32_t bufLen; bool copy; + bool swapBytes; buffer_detail *detail; } bounded_buffer; From 974494f622d6185c9cb86c99632245a5bb9772af Mon Sep 17 00:00:00 2001 From: Jozef Kolek <jkolek@gmail.com> Date: Wed, 12 Apr 2017 17:39:59 +0200 Subject: [PATCH 2/2] const replaced by constexpr in nt-headers.h --- parser-library/nt-headers.h | 300 ++++++++++++++++++------------------ 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/parser-library/nt-headers.h b/parser-library/nt-headers.h index 7adb3b6..47fa48e 100644 --- a/parser-library/nt-headers.h +++ b/parser-library/nt-headers.h @@ -32,166 +32,166 @@ THE SOFTWARE. // some constant definitions namespace peparse { -const std::uint16_t MZ_MAGIC = 0x5A4D; -const std::uint32_t NT_MAGIC = 0x00004550; -const std::uint16_t NUM_DIR_ENTRIES = 16; -const std::uint16_t NT_OPTIONAL_32_MAGIC = 0x10B; -const std::uint16_t NT_OPTIONAL_64_MAGIC = 0x20B; -const std::uint16_t NT_SHORT_NAME_LEN = 8; -const std::uint16_t SYMTAB_RECORD_LEN = 18; -const std::uint16_t DIR_EXPORT = 0; -const std::uint16_t DIR_IMPORT = 1; -const std::uint16_t DIR_RESOURCE = 2; -const std::uint16_t DIR_EXCEPTION = 3; -const std::uint16_t DIR_SECURITY = 4; -const std::uint16_t DIR_BASERELOC = 5; -const std::uint16_t DIR_DEBUG = 6; -const std::uint16_t DIR_ARCHITECTURE = 7; -const std::uint16_t DIR_GLOBALPTR = 8; -const std::uint16_t DIR_TLS = 9; -const std::uint16_t DIR_LOAD_CONFIG = 10; -const std::uint16_t DIR_BOUND_IMPORT = 11; -const std::uint16_t DIR_IAT = 12; -const std::uint16_t DIR_DELAY_IMPORT = 13; -const std::uint16_t DIR_COM_DESCRIPTOR = 14; +constexpr std::uint16_t MZ_MAGIC = 0x5A4D; +constexpr std::uint32_t NT_MAGIC = 0x00004550; +constexpr std::uint16_t NUM_DIR_ENTRIES = 16; +constexpr std::uint16_t NT_OPTIONAL_32_MAGIC = 0x10B; +constexpr std::uint16_t NT_OPTIONAL_64_MAGIC = 0x20B; +constexpr std::uint16_t NT_SHORT_NAME_LEN = 8; +constexpr std::uint16_t SYMTAB_RECORD_LEN = 18; +constexpr std::uint16_t DIR_EXPORT = 0; +constexpr std::uint16_t DIR_IMPORT = 1; +constexpr std::uint16_t DIR_RESOURCE = 2; +constexpr std::uint16_t DIR_EXCEPTION = 3; +constexpr std::uint16_t DIR_SECURITY = 4; +constexpr std::uint16_t DIR_BASERELOC = 5; +constexpr std::uint16_t DIR_DEBUG = 6; +constexpr std::uint16_t DIR_ARCHITECTURE = 7; +constexpr std::uint16_t DIR_GLOBALPTR = 8; +constexpr std::uint16_t DIR_TLS = 9; +constexpr std::uint16_t DIR_LOAD_CONFIG = 10; +constexpr std::uint16_t DIR_BOUND_IMPORT = 11; +constexpr std::uint16_t DIR_IAT = 12; +constexpr std::uint16_t DIR_DELAY_IMPORT = 13; +constexpr std::uint16_t DIR_COM_DESCRIPTOR = 14; // Machine Types -const std::uint16_t IMAGE_FILE_MACHINE_UNKNOWN = 0x0; -const std::uint16_t IMAGE_FILE_MACHINE_AM33 = 0x1d3; // Matsushita AM33 -const std::uint16_t IMAGE_FILE_MACHINE_AMD64 = 0x8664; // x64 -const std::uint16_t IMAGE_FILE_MACHINE_ARM = 0x1c0; // ARM little endian -const std::uint16_t IMAGE_FILE_MACHINE_ARM64 = 0xaa64; // ARM64 little endian -const std::uint16_t IMAGE_FILE_MACHINE_ARMNT = 0x1c4; // ARM Thumb-2 little endian -const std::uint16_t IMAGE_FILE_MACHINE_EBC = 0xebc; // EFI byte code -const std::uint16_t IMAGE_FILE_MACHINE_I386 = 0x14c; // Intel 386 or later processors and compatible processors -const std::uint16_t IMAGE_FILE_MACHINE_IA64 = 0x200; // Intel Itanium processor family -const std::uint16_t IMAGE_FILE_MACHINE_M32R = 0x9041; // Mitsubishi M32R little endian -const std::uint16_t IMAGE_FILE_MACHINE_MIPS16 = 0x266; // MIPS16 -const std::uint16_t IMAGE_FILE_MACHINE_MIPSFPU = 0x366; // MIPS with FPU -const std::uint16_t IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466; // MIPS16 with FPU -const std::uint16_t IMAGE_FILE_MACHINE_POWERPC = 0x1f0; // Power PC little endian -const std::uint16_t IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1; // Power PC with floating point support -const std::uint16_t IMAGE_FILE_MACHINE_R4000 = 0x166; // MIPS little endian -const std::uint16_t IMAGE_FILE_MACHINE_RISCV32 = 0x5032; // RISC-V 32-bit address space -const std::uint16_t IMAGE_FILE_MACHINE_RISCV64 = 0x5064; // RISC-V 64-bit address space -const std::uint16_t IMAGE_FILE_MACHINE_RISCV128 = 0x5128; // RISC-V 128-bit address space -const std::uint16_t IMAGE_FILE_MACHINE_SH3 = 0x1a2; // Hitachi SH3 -const std::uint16_t IMAGE_FILE_MACHINE_SH3DSP = 0x1a3; // Hitachi SH3 DSP -const std::uint16_t IMAGE_FILE_MACHINE_SH4 = 0x1a6; // Hitachi SH4 -const std::uint16_t IMAGE_FILE_MACHINE_SH5 = 0x1a8; // Hitachi SH5 -const std::uint16_t IMAGE_FILE_MACHINE_THUMB = 0x1c2; // Thumb -const std::uint16_t IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169; // MIPS little-endian WCE v2 +constexpr std::uint16_t IMAGE_FILE_MACHINE_UNKNOWN = 0x0; +constexpr std::uint16_t IMAGE_FILE_MACHINE_AM33 = 0x1d3; // Matsushita AM33 +constexpr std::uint16_t IMAGE_FILE_MACHINE_AMD64 = 0x8664; // x64 +constexpr std::uint16_t IMAGE_FILE_MACHINE_ARM = 0x1c0; // ARM little endian +constexpr std::uint16_t IMAGE_FILE_MACHINE_ARM64 = 0xaa64; // ARM64 little endian +constexpr std::uint16_t IMAGE_FILE_MACHINE_ARMNT = 0x1c4; // ARM Thumb-2 little endian +constexpr std::uint16_t IMAGE_FILE_MACHINE_EBC = 0xebc; // EFI byte code +constexpr std::uint16_t IMAGE_FILE_MACHINE_I386 = 0x14c; // Intel 386 or later processors and compatible processors +constexpr std::uint16_t IMAGE_FILE_MACHINE_IA64 = 0x200; // Intel Itanium processor family +constexpr std::uint16_t IMAGE_FILE_MACHINE_M32R = 0x9041; // Mitsubishi M32R little endian +constexpr std::uint16_t IMAGE_FILE_MACHINE_MIPS16 = 0x266; // MIPS16 +constexpr std::uint16_t IMAGE_FILE_MACHINE_MIPSFPU = 0x366; // MIPS with FPU +constexpr std::uint16_t IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466; // MIPS16 with FPU +constexpr std::uint16_t IMAGE_FILE_MACHINE_POWERPC = 0x1f0; // Power PC little endian +constexpr std::uint16_t IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1; // Power PC with floating point support +constexpr std::uint16_t IMAGE_FILE_MACHINE_R4000 = 0x166; // MIPS little endian +constexpr std::uint16_t IMAGE_FILE_MACHINE_RISCV32 = 0x5032; // RISC-V 32-bit address space +constexpr std::uint16_t IMAGE_FILE_MACHINE_RISCV64 = 0x5064; // RISC-V 64-bit address space +constexpr std::uint16_t IMAGE_FILE_MACHINE_RISCV128 = 0x5128; // RISC-V 128-bit address space +constexpr std::uint16_t IMAGE_FILE_MACHINE_SH3 = 0x1a2; // Hitachi SH3 +constexpr std::uint16_t IMAGE_FILE_MACHINE_SH3DSP = 0x1a3; // Hitachi SH3 DSP +constexpr std::uint16_t IMAGE_FILE_MACHINE_SH4 = 0x1a6; // Hitachi SH4 +constexpr std::uint16_t IMAGE_FILE_MACHINE_SH5 = 0x1a8; // Hitachi SH5 +constexpr std::uint16_t IMAGE_FILE_MACHINE_THUMB = 0x1c2; // Thumb +constexpr std::uint16_t IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169; // MIPS little-endian WCE v2 -const std::uint16_t IMAGE_FILE_RELOCS_STRIPPED = 0x0001; -const std::uint16_t IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002; -const std::uint16_t IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004; -const std::uint16_t IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008; -const std::uint16_t IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010; -const std::uint16_t IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020; -const std::uint16_t IMAGE_FILE_BYTES_REVERSED_LO = 0x0080; -const std::uint16_t IMAGE_FILE_32BIT_MACHINE = 0x0100; -const std::uint16_t IMAGE_FILE_DEBUG_STRIPPED = 0x0200; -const std::uint16_t IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400; -const std::uint16_t IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800; -const std::uint16_t IMAGE_FILE_SYSTEM = 0x1000; -const std::uint16_t IMAGE_FILE_DLL = 0x2000; -const std::uint16_t IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000; -const std::uint16_t IMAGE_FILE_BYTES_REVERSED_HI = 0x8000; +constexpr std::uint16_t IMAGE_FILE_RELOCS_STRIPPED = 0x0001; +constexpr std::uint16_t IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002; +constexpr std::uint16_t IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004; +constexpr std::uint16_t IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008; +constexpr std::uint16_t IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010; +constexpr std::uint16_t IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020; +constexpr std::uint16_t IMAGE_FILE_BYTES_REVERSED_LO = 0x0080; +constexpr std::uint16_t IMAGE_FILE_32BIT_MACHINE = 0x0100; +constexpr std::uint16_t IMAGE_FILE_DEBUG_STRIPPED = 0x0200; +constexpr std::uint16_t IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400; +constexpr std::uint16_t IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800; +constexpr std::uint16_t IMAGE_FILE_SYSTEM = 0x1000; +constexpr std::uint16_t IMAGE_FILE_DLL = 0x2000; +constexpr std::uint16_t IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000; +constexpr std::uint16_t IMAGE_FILE_BYTES_REVERSED_HI = 0x8000; -const std::uint32_t IMAGE_SCN_TYPE_NO_PAD = 0x00000008; -const std::uint32_t IMAGE_SCN_CNT_CODE = 0x00000020; -const std::uint32_t IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040; -const std::uint32_t IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080; -const std::uint32_t IMAGE_SCN_LNK_OTHER = 0x00000100; -const std::uint32_t IMAGE_SCN_LNK_INFO = 0x00000200; -const std::uint32_t IMAGE_SCN_LNK_REMOVE = 0x00000800; -const std::uint32_t IMAGE_SCN_LNK_COMDAT = 0x00001000; -const std::uint32_t IMAGE_SCN_NO_DEFER_SPEC_EXC = 0x00004000; -const std::uint32_t IMAGE_SCN_GPREL = 0x00008000; -const std::uint32_t IMAGE_SCN_MEM_FARDATA = 0x00008000; -const std::uint32_t IMAGE_SCN_MEM_PURGEABLE = 0x00020000; -const std::uint32_t IMAGE_SCN_MEM_16BIT = 0x00020000; -const std::uint32_t IMAGE_SCN_MEM_LOCKED = 0x00040000; -const std::uint32_t IMAGE_SCN_MEM_PRELOAD = 0x00080000; -const std::uint32_t IMAGE_SCN_ALIGN_1BYTES = 0x00100000; -const std::uint32_t IMAGE_SCN_ALIGN_2BYTES = 0x00200000; -const std::uint32_t IMAGE_SCN_ALIGN_4BYTES = 0x00300000; -const std::uint32_t IMAGE_SCN_ALIGN_8BYTES = 0x00400000; -const std::uint32_t IMAGE_SCN_ALIGN_16BYTES = 0x00500000; -const std::uint32_t IMAGE_SCN_ALIGN_32BYTES = 0x00600000; -const std::uint32_t IMAGE_SCN_ALIGN_64BYTES = 0x00700000; -const std::uint32_t IMAGE_SCN_ALIGN_128BYTES = 0x00800000; -const std::uint32_t IMAGE_SCN_ALIGN_256BYTES = 0x00900000; -const std::uint32_t IMAGE_SCN_ALIGN_512BYTES = 0x00A00000; -const std::uint32_t IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000; -const std::uint32_t IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000; -const std::uint32_t IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000; -const std::uint32_t IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000; -const std::uint32_t IMAGE_SCN_ALIGN_MASK = 0x00F00000; -const std::uint32_t IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000; -const std::uint32_t IMAGE_SCN_MEM_DISCARDABLE = 0x02000000; -const std::uint32_t IMAGE_SCN_MEM_NOT_CACHED = 0x04000000; -const std::uint32_t IMAGE_SCN_MEM_NOT_PAGED = 0x08000000; -const std::uint32_t IMAGE_SCN_MEM_SHARED = 0x10000000; -const std::uint32_t IMAGE_SCN_MEM_EXECUTE = 0x20000000; -const std::uint32_t IMAGE_SCN_MEM_READ = 0x40000000; -const std::uint32_t IMAGE_SCN_MEM_WRITE = 0x80000000; +constexpr std::uint32_t IMAGE_SCN_TYPE_NO_PAD = 0x00000008; +constexpr std::uint32_t IMAGE_SCN_CNT_CODE = 0x00000020; +constexpr std::uint32_t IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040; +constexpr std::uint32_t IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080; +constexpr std::uint32_t IMAGE_SCN_LNK_OTHER = 0x00000100; +constexpr std::uint32_t IMAGE_SCN_LNK_INFO = 0x00000200; +constexpr std::uint32_t IMAGE_SCN_LNK_REMOVE = 0x00000800; +constexpr std::uint32_t IMAGE_SCN_LNK_COMDAT = 0x00001000; +constexpr std::uint32_t IMAGE_SCN_NO_DEFER_SPEC_EXC = 0x00004000; +constexpr std::uint32_t IMAGE_SCN_GPREL = 0x00008000; +constexpr std::uint32_t IMAGE_SCN_MEM_FARDATA = 0x00008000; +constexpr std::uint32_t IMAGE_SCN_MEM_PURGEABLE = 0x00020000; +constexpr std::uint32_t IMAGE_SCN_MEM_16BIT = 0x00020000; +constexpr std::uint32_t IMAGE_SCN_MEM_LOCKED = 0x00040000; +constexpr std::uint32_t IMAGE_SCN_MEM_PRELOAD = 0x00080000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_1BYTES = 0x00100000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_2BYTES = 0x00200000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_4BYTES = 0x00300000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_8BYTES = 0x00400000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_16BYTES = 0x00500000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_32BYTES = 0x00600000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_64BYTES = 0x00700000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_128BYTES = 0x00800000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_256BYTES = 0x00900000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_512BYTES = 0x00A00000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000; +constexpr std::uint32_t IMAGE_SCN_ALIGN_MASK = 0x00F00000; +constexpr std::uint32_t IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000; +constexpr std::uint32_t IMAGE_SCN_MEM_DISCARDABLE = 0x02000000; +constexpr std::uint32_t IMAGE_SCN_MEM_NOT_CACHED = 0x04000000; +constexpr std::uint32_t IMAGE_SCN_MEM_NOT_PAGED = 0x08000000; +constexpr std::uint32_t IMAGE_SCN_MEM_SHARED = 0x10000000; +constexpr std::uint32_t IMAGE_SCN_MEM_EXECUTE = 0x20000000; +constexpr std::uint32_t IMAGE_SCN_MEM_READ = 0x40000000; +constexpr std::uint32_t IMAGE_SCN_MEM_WRITE = 0x80000000; // Symbol section number values -const std::int16_t IMAGE_SYM_UNDEFINED = 0; -const std::int16_t IMAGE_SYM_ABSOLUTE = -1; -const std::int16_t IMAGE_SYM_DEBUG = -2; +constexpr std::int16_t IMAGE_SYM_UNDEFINED = 0; +constexpr std::int16_t IMAGE_SYM_ABSOLUTE = -1; +constexpr std::int16_t IMAGE_SYM_DEBUG = -2; // Symbol table types -const std::uint16_t IMAGE_SYM_TYPE_NULL = 0; -const std::uint16_t IMAGE_SYM_TYPE_VOID = 1; -const std::uint16_t IMAGE_SYM_TYPE_CHAR = 2; -const std::uint16_t IMAGE_SYM_TYPE_SHORT = 3; -const std::uint16_t IMAGE_SYM_TYPE_INT = 4; -const std::uint16_t IMAGE_SYM_TYPE_LONG = 5; -const std::uint16_t IMAGE_SYM_TYPE_FLOAT = 6; -const std::uint16_t IMAGE_SYM_TYPE_DOUBLE = 7; -const std::uint16_t IMAGE_SYM_TYPE_STRUCT = 8; -const std::uint16_t IMAGE_SYM_TYPE_UNION = 9; -const std::uint16_t IMAGE_SYM_TYPE_ENUM = 10; -const std::uint16_t IMAGE_SYM_TYPE_MOE = 11; -const std::uint16_t IMAGE_SYM_TYPE_BYTE = 12; -const std::uint16_t IMAGE_SYM_TYPE_WORD = 13; -const std::uint16_t IMAGE_SYM_TYPE_UINT = 14; -const std::uint16_t IMAGE_SYM_TYPE_DWORD = 15; -const std::uint16_t IMAGE_SYM_DTYPE_NULL = 0; -const std::uint16_t IMAGE_SYM_DTYPE_POINTER = 1; -const std::uint16_t IMAGE_SYM_DTYPE_FUNCTION = 2; -const std::uint16_t IMAGE_SYM_DTYPE_ARRAY = 3; +constexpr std::uint16_t IMAGE_SYM_TYPE_NULL = 0; +constexpr std::uint16_t IMAGE_SYM_TYPE_VOID = 1; +constexpr std::uint16_t IMAGE_SYM_TYPE_CHAR = 2; +constexpr std::uint16_t IMAGE_SYM_TYPE_SHORT = 3; +constexpr std::uint16_t IMAGE_SYM_TYPE_INT = 4; +constexpr std::uint16_t IMAGE_SYM_TYPE_LONG = 5; +constexpr std::uint16_t IMAGE_SYM_TYPE_FLOAT = 6; +constexpr std::uint16_t IMAGE_SYM_TYPE_DOUBLE = 7; +constexpr std::uint16_t IMAGE_SYM_TYPE_STRUCT = 8; +constexpr std::uint16_t IMAGE_SYM_TYPE_UNION = 9; +constexpr std::uint16_t IMAGE_SYM_TYPE_ENUM = 10; +constexpr std::uint16_t IMAGE_SYM_TYPE_MOE = 11; +constexpr std::uint16_t IMAGE_SYM_TYPE_BYTE = 12; +constexpr std::uint16_t IMAGE_SYM_TYPE_WORD = 13; +constexpr std::uint16_t IMAGE_SYM_TYPE_UINT = 14; +constexpr std::uint16_t IMAGE_SYM_TYPE_DWORD = 15; +constexpr std::uint16_t IMAGE_SYM_DTYPE_NULL = 0; +constexpr std::uint16_t IMAGE_SYM_DTYPE_POINTER = 1; +constexpr std::uint16_t IMAGE_SYM_DTYPE_FUNCTION = 2; +constexpr std::uint16_t IMAGE_SYM_DTYPE_ARRAY = 3; // Symbol table storage classes -const std::uint8_t IMAGE_SYM_CLASS_END_OF_FUNCTION = -1; -const std::uint8_t IMAGE_SYM_CLASS_NULL = 0; -const std::uint8_t IMAGE_SYM_CLASS_AUTOMATIC = 1; -const std::uint8_t IMAGE_SYM_CLASS_EXTERNAL = 2; -const std::uint8_t IMAGE_SYM_CLASS_STATIC = 3; -const std::uint8_t IMAGE_SYM_CLASS_REGISTER = 4; -const std::uint8_t IMAGE_SYM_CLASS_EXTERNAL_DEF = 5; -const std::uint8_t IMAGE_SYM_CLASS_LABEL = 6; -const std::uint8_t IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7; -const std::uint8_t IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8; -const std::uint8_t IMAGE_SYM_CLASS_ARGUMENT = 9; -const std::uint8_t IMAGE_SYM_CLASS_STRUCT_TAG = 10; -const std::uint8_t IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11; -const std::uint8_t IMAGE_SYM_CLASS_UNION_TAG = 12; -const std::uint8_t IMAGE_SYM_CLASS_TYPE_DEFINITION = 13; -const std::uint8_t IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14; -const std::uint8_t IMAGE_SYM_CLASS_ENUM_TAG = 15; -const std::uint8_t IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16; -const std::uint8_t IMAGE_SYM_CLASS_REGISTER_PARAM = 17; -const std::uint8_t IMAGE_SYM_CLASS_BIT_FIELD = 18; -const std::uint8_t IMAGE_SYM_CLASS_BLOCK = 100; -const std::uint8_t IMAGE_SYM_CLASS_FUNCTION = 101; -const std::uint8_t IMAGE_SYM_CLASS_END_OF_STRUCT = 102; -const std::uint8_t IMAGE_SYM_CLASS_FILE = 103; -const std::uint8_t IMAGE_SYM_CLASS_SECTION = 104; -const std::uint8_t IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105; -const std::uint8_t IMAGE_SYM_CLASS_CLR_TOKEN = 107; +constexpr std::uint8_t IMAGE_SYM_CLASS_END_OF_FUNCTION = -1; +constexpr std::uint8_t IMAGE_SYM_CLASS_NULL = 0; +constexpr std::uint8_t IMAGE_SYM_CLASS_AUTOMATIC = 1; +constexpr std::uint8_t IMAGE_SYM_CLASS_EXTERNAL = 2; +constexpr std::uint8_t IMAGE_SYM_CLASS_STATIC = 3; +constexpr std::uint8_t IMAGE_SYM_CLASS_REGISTER = 4; +constexpr std::uint8_t IMAGE_SYM_CLASS_EXTERNAL_DEF = 5; +constexpr std::uint8_t IMAGE_SYM_CLASS_LABEL = 6; +constexpr std::uint8_t IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7; +constexpr std::uint8_t IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8; +constexpr std::uint8_t IMAGE_SYM_CLASS_ARGUMENT = 9; +constexpr std::uint8_t IMAGE_SYM_CLASS_STRUCT_TAG = 10; +constexpr std::uint8_t IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11; +constexpr std::uint8_t IMAGE_SYM_CLASS_UNION_TAG = 12; +constexpr std::uint8_t IMAGE_SYM_CLASS_TYPE_DEFINITION = 13; +constexpr std::uint8_t IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14; +constexpr std::uint8_t IMAGE_SYM_CLASS_ENUM_TAG = 15; +constexpr std::uint8_t IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16; +constexpr std::uint8_t IMAGE_SYM_CLASS_REGISTER_PARAM = 17; +constexpr std::uint8_t IMAGE_SYM_CLASS_BIT_FIELD = 18; +constexpr std::uint8_t IMAGE_SYM_CLASS_BLOCK = 100; +constexpr std::uint8_t IMAGE_SYM_CLASS_FUNCTION = 101; +constexpr std::uint8_t IMAGE_SYM_CLASS_END_OF_STRUCT = 102; +constexpr std::uint8_t IMAGE_SYM_CLASS_FILE = 103; +constexpr std::uint8_t IMAGE_SYM_CLASS_SECTION = 104; +constexpr std::uint8_t IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105; +constexpr std::uint8_t IMAGE_SYM_CLASS_CLR_TOKEN = 107; struct dos_header { std::uint16_t e_magic;