From d84259fdccbb50325421ac3a45ab497815873d81 Mon Sep 17 00:00:00 2001 From: Orange Date: Tue, 7 Oct 2025 11:19:43 +0300 Subject: [PATCH] Adds PE file header definitions Defines `DosHeader` and `FileHeader` structures to represent PE file header information. Includes definitions for `MachineId` enum and `FileCharacteristics` union. These definitions are prerequisite for PE file parsing and analysis. --- include/omath/system/pe/dos_header.hpp | 32 ++++++++++ include/omath/system/pe/file_header.hpp | 77 ++++++++++++++++++++++++ source/utility/pe_pattern_scan.cpp | 2 +- tests/general/unit_test_pattern_scan.cpp | 7 ++- 4 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 include/omath/system/pe/dos_header.hpp create mode 100644 include/omath/system/pe/file_header.hpp diff --git a/include/omath/system/pe/dos_header.hpp b/include/omath/system/pe/dos_header.hpp new file mode 100644 index 0000000..b4f370d --- /dev/null +++ b/include/omath/system/pe/dos_header.hpp @@ -0,0 +1,32 @@ +// +// Created by Vlad on 10/7/2025. +// + +#pragma once +#include + +namespace omath::system::pe +{ + struct DosHeader + { + std::uint16_t e_magic; + std::uint16_t e_cblp; + std::uint16_t e_cp; + std::uint16_t e_crlc; + std::uint16_t e_cparhdr; + std::uint16_t e_minalloc; + std::uint16_t e_maxalloc; + std::uint16_t e_ss; + std::uint16_t e_sp; + std::uint16_t e_csum; + std::uint16_t e_ip; + std::uint16_t e_cs; + std::uint16_t e_lfarlc; + std::uint16_t e_ovno; + std::uint16_t e_res[4]; + std::uint16_t e_oemid; + std::uint16_t e_oeminfo; + std::uint16_t e_res2[10]; + std::uint32_t e_lfanew; + }; +} \ No newline at end of file diff --git a/include/omath/system/pe/file_header.hpp b/include/omath/system/pe/file_header.hpp new file mode 100644 index 0000000..a07f965 --- /dev/null +++ b/include/omath/system/pe/file_header.hpp @@ -0,0 +1,77 @@ +// +// Created by Vlad on 10/7/2025. +// + +#pragma once +#include + +enum class MachineId : std::uint16_t +{ + UNKNOWN = 0x0000, + TARGET_HOST = 0x0001, // Useful for indicating we want to interact with the host and not a WoW guest. + I386 = 0x014C, // Intel 386. + R3000 = 0x0162, // MIPS little-endian, 0x160 big-endian + R4000 = 0x0166, // MIPS little-endian + R10000 = 0x0168, // MIPS little-endian + WCEMIPSV2 = 0x0169, // MIPS little-endian WCE v2 + ALPHA = 0x0184, // Alpha_AXP + SH3 = 0x01A2, // SH3 little-endian + SH3DSP = 0x01A3, + SH3E = 0x01A4, // SH3E little-endian + SH4 = 0x01A6, // SH4 little-endian + SH5 = 0x01A8, // SH5 + ARM = 0x01C0, // ARM Little-Endian + THUMB = 0x01C2, // ARM Thumb/Thumb-2 Little-Endian + ARMNT = 0x01C4, // ARM Thumb-2 Little-Endian + AM33 = 0x01D3, + POWERPC = 0x01F0, // IBM PowerPC Little-Endian + POWERPCP = 0x01F1, + IA64 = 0x0200, // Intel 64 + MIPS16 = 0x0266, // MIPS + ALPHA64 = 0x0284, // ALPHA64 + MIPSFPU = 0x0366, // MIPS + MIPSFPU16 = 0x0466, // MIPS + AXP64 = 0x0284, + TRICORE = 0x0520, // Infineon + CEF = 0x0CEF, + EBC = 0x0EBC, // EFI Byte Code + AMD64 = 0x8664, // AMD64 (K8) + M32R = 0x9041, // M32R little-endian + ARM64 = 0xAA64, // ARM64 Little-Endian + CEE = 0xC0EE, +}; + +union FileCharacteristics +{ + std::uint16_t flags; + struct + { + std::uint16_t relocs_stripped : 1; // Relocation info stripped from file. + std::uint16_t executable : 1; // File is executable (i.e. no unresolved external references). + std::uint16_t lines_stripped : 1; // Line nunbers stripped from file. + std::uint16_t local_symbols_stripped : 1; // Local symbols stripped from file. + std::uint16_t aggressive_ws_trim : 1; // Aggressively trim working set + std::uint16_t large_address_aware : 1; // App can handle >2gb addresses + std::uint16_t _pad0 : 1; + std::uint16_t bytes_reversed_lo : 1; // Bytes of machine word are reversed. + std::uint16_t machine_32 : 1; // 32 bit word machine. + std::uint16_t debug_stripped : 1; // Debugging info stripped from file in .DBG file + std::uint16_t runnable_from_swap : 1; // If Image is on removable media, copy and run from the swap file. + std::uint16_t net_run_from_swap : 1; // If Image is on Net, copy and run from the swap file. + std::uint16_t system_file : 1; // System File. + std::uint16_t dll_file : 1; // File is a DLL. + std::uint16_t up_system_only : 1; // File should only be run on a UP machine + std::uint16_t bytes_reversed_hi : 1; // Bytes of machine word are reversed. + }; +}; + +struct FileHeader +{ + MachineId machine; + uint16_t num_sections; + uint32_t timedate_stamp; + uint32_t ptr_symbols; + uint32_t num_symbols; + uint16_t size_optional_header; + FileCharacteristics characteristics; +}; \ No newline at end of file diff --git a/source/utility/pe_pattern_scan.cpp b/source/utility/pe_pattern_scan.cpp index 48ac6ef..f9d62e9 100644 --- a/source/utility/pe_pattern_scan.cpp +++ b/source/utility/pe_pattern_scan.cpp @@ -62,7 +62,7 @@ namespace omath PePatternScanner::extract_section_from_pe_file(const std::filesystem::path& path_to_file, const std::string_view& section_name) { - std::ifstream file(path_to_file, std::ios::binary); + std::fstream file(path_to_file, std::ios::binary | std::ios::in); if (!file.is_open()) [[unlikely]] return std::nullopt; diff --git a/tests/general/unit_test_pattern_scan.cpp b/tests/general/unit_test_pattern_scan.cpp index d0da462..248ab88 100644 --- a/tests/general/unit_test_pattern_scan.cpp +++ b/tests/general/unit_test_pattern_scan.cpp @@ -1,11 +1,11 @@ // // Created by Vlad on 10/4/2025. // +#include "omath/utility/pe_pattern_scan.hpp" #include "gtest/gtest.h" #include #include - TEST(unit_test_pattern_scan, read_test) { const auto result = omath::PatternScanner::parse_pattern("FF ? ?? E9"); @@ -49,6 +49,9 @@ TEST(unit_test_pattern_scan, corner_case_3) TEST(unit_test_pattern_scan, corner_case_4) { const auto result = omath::PatternScanner::parse_pattern("X ? ?? E9 "); - + const auto result2 = omath::PePatternScanner::scan_for_pattern_in_file( + std::filesystem::path{ + "C:\\Users\\Vlad\\CLionProjects\\l4bhop\\cmake-build\\build\\windows-release\\l4bhop.dll"}, + "4C 8B D1 B8 ? ? ? ? F6 04 25 ? ? ? ? ? 75 ? 0F 05 C3"); EXPECT_FALSE(result.has_value()); } \ No newline at end of file