From 5646654317f689a53dc9ec2dee6dd78347630c39 Mon Sep 17 00:00:00 2001 From: Orange Date: Mon, 13 Oct 2025 14:17:30 +0300 Subject: [PATCH] Removes Windows-specific API dependencies for pattern scanning Replaces calls to Windows API functions (GetModuleHandleA) with a void pointer parameter. Simplifies pattern scanning for loaded modules by removing Windows-specific code and replacing it with a generic approach. --- include/omath/utility/pe_pattern_scan.hpp | 2 +- source/utility/pe_pattern_scan.cpp | 63 +++++++++++++++-------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/include/omath/utility/pe_pattern_scan.hpp b/include/omath/utility/pe_pattern_scan.hpp index a5de420..2f5477f 100644 --- a/include/omath/utility/pe_pattern_scan.hpp +++ b/include/omath/utility/pe_pattern_scan.hpp @@ -19,7 +19,7 @@ namespace omath { public: [[nodiscard]] - static std::optional scan_for_pattern_in_loaded_module(const std::string_view& module_name, + static std::optional scan_for_pattern_in_loaded_module(const void* module_base_address, const std::string_view& pattern); [[nodiscard]] diff --git a/source/utility/pe_pattern_scan.cpp b/source/utility/pe_pattern_scan.cpp index 90c47e5..e477d15 100644 --- a/source/utility/pe_pattern_scan.cpp +++ b/source/utility/pe_pattern_scan.cpp @@ -7,9 +7,6 @@ #include #include #include -#ifdef _WIN32 -#include -#endif // Internal PE shit defines // Big thx for linuxpe sources as ref @@ -206,6 +203,26 @@ namespace return x64_headers; } + [[nodiscard]] + std::optional get_nt_header_from_loaded_module(const void* module_base_address) + { + const auto module_byte_ptr = static_cast(module_base_address); + ImageNtHeaders x86_headers{}; + const auto dos_header = static_cast(module_base_address); + + x86_headers = *reinterpret_cast*>(module_byte_ptr + + dos_header->e_lfanew); + + if (x86_headers.optional_header.magic == opt_hdr32_magic) + return x86_headers; + + if (x86_headers.optional_header.magic != opt_hdr64_magic) + return std::nullopt; + + return *reinterpret_cast*>(module_byte_ptr + + dos_header->e_lfanew); + } + [[nodiscard]] constexpr bool invalid_dos_header_file(const DosHeader& dos_header) { @@ -286,35 +303,37 @@ namespace namespace omath { - std::optional - PePatternScanner::scan_for_pattern_in_loaded_module([[maybe_unused]] const std::string_view& module_name, - [[maybe_unused]] const std::string_view& pattern) + std::optional PePatternScanner::scan_for_pattern_in_loaded_module(const void* module_base_address, + const std::string_view& pattern) { -#ifdef _WIN32 - const auto base_address = reinterpret_cast(GetModuleHandleA(module_name.data())); + const auto base_address = reinterpret_cast(module_base_address); if (!base_address) return std::nullopt; - const auto dos_headers = reinterpret_cast(base_address); - const auto image_nt_headers = reinterpret_cast(base_address + dos_headers->e_lfanew); + auto nt_header_variant = get_nt_header_from_loaded_module(module_base_address); - // Define .code segment as scan area - const auto start = image_nt_headers->OptionalHeader.BaseOfCode; - const auto scan_size = image_nt_headers->OptionalHeader.SizeOfCode; + if (!nt_header_variant) + return std::nullopt; - const auto scan_range = std::span{reinterpret_cast(base_address) + start, scan_size}; + return std::visit( + [base_address, &pattern](const auto& nt_header) -> std::optional + { + // Define .code segment as scan area + const auto start = nt_header.optional_header.base_of_code; + const auto scan_size = nt_header.optional_header.size_code; - // ReSharper disable once CppTooWideScopeInitStatement - const auto result = PatternScanner::scan_for_pattern(scan_range, pattern); + const auto scan_range = std::span{reinterpret_cast(base_address) + start, scan_size}; - if (result != scan_range.cend()) - return reinterpret_cast(&*result); + // ReSharper disable once CppTooWideScopeInitStatement + const auto result = PatternScanner::scan_for_pattern(scan_range, pattern); - return std::nullopt; -#else - throw std::runtime_error("Pattern scan for loaded modules is only for windows platform"); -#endif + if (result != scan_range.cend()) + return reinterpret_cast(&*result); + + return std::nullopt; + }, + nt_header_variant.value()); } std::optional PePatternScanner::scan_for_pattern_in_file(const std::filesystem::path& path_to_file,