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.
This commit is contained in:
2025-10-13 14:17:30 +03:00
parent ee54e3de34
commit 5646654317
2 changed files with 42 additions and 23 deletions

View File

@@ -19,7 +19,7 @@ namespace omath
{ {
public: public:
[[nodiscard]] [[nodiscard]]
static std::optional<std::uintptr_t> scan_for_pattern_in_loaded_module(const std::string_view& module_name, static std::optional<std::uintptr_t> scan_for_pattern_in_loaded_module(const void* module_base_address,
const std::string_view& pattern); const std::string_view& pattern);
[[nodiscard]] [[nodiscard]]

View File

@@ -7,9 +7,6 @@
#include <span> #include <span>
#include <stdexcept> #include <stdexcept>
#include <variant> #include <variant>
#ifdef _WIN32
#include <Windows.h>
#endif
// Internal PE shit defines // Internal PE shit defines
// Big thx for linuxpe sources as ref // Big thx for linuxpe sources as ref
@@ -206,6 +203,26 @@ namespace
return x64_headers; return x64_headers;
} }
[[nodiscard]]
std::optional<NtHeaderVariant> get_nt_header_from_loaded_module(const void* module_base_address)
{
const auto module_byte_ptr = static_cast<const std::byte*>(module_base_address);
ImageNtHeaders<NtArchitecture::x32_bit> x86_headers{};
const auto dos_header = static_cast<const DosHeader*>(module_base_address);
x86_headers = *reinterpret_cast<const ImageNtHeaders<NtArchitecture::x32_bit>*>(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<const ImageNtHeaders<NtArchitecture::x64_bit>*>(module_byte_ptr
+ dos_header->e_lfanew);
}
[[nodiscard]] [[nodiscard]]
constexpr bool invalid_dos_header_file(const DosHeader& dos_header) constexpr bool invalid_dos_header_file(const DosHeader& dos_header)
{ {
@@ -286,22 +303,25 @@ namespace
namespace omath namespace omath
{ {
std::optional<std::uintptr_t> std::optional<std::uintptr_t> PePatternScanner::scan_for_pattern_in_loaded_module(const void* module_base_address,
PePatternScanner::scan_for_pattern_in_loaded_module([[maybe_unused]] const std::string_view& module_name, const std::string_view& pattern)
[[maybe_unused]] const std::string_view& pattern)
{ {
#ifdef _WIN32 const auto base_address = reinterpret_cast<std::uintptr_t>(module_base_address);
const auto base_address = reinterpret_cast<std::uintptr_t>(GetModuleHandleA(module_name.data()));
if (!base_address) if (!base_address)
return std::nullopt; return std::nullopt;
const auto dos_headers = reinterpret_cast<PIMAGE_DOS_HEADER>(base_address); auto nt_header_variant = get_nt_header_from_loaded_module(module_base_address);
const auto image_nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS>(base_address + dos_headers->e_lfanew);
if (!nt_header_variant)
return std::nullopt;
return std::visit(
[base_address, &pattern](const auto& nt_header) -> std::optional<std::uintptr_t>
{
// Define .code segment as scan area // Define .code segment as scan area
const auto start = image_nt_headers->OptionalHeader.BaseOfCode; const auto start = nt_header.optional_header.base_of_code;
const auto scan_size = image_nt_headers->OptionalHeader.SizeOfCode; const auto scan_size = nt_header.optional_header.size_code;
const auto scan_range = std::span{reinterpret_cast<std::byte*>(base_address) + start, scan_size}; const auto scan_range = std::span{reinterpret_cast<std::byte*>(base_address) + start, scan_size};
@@ -312,9 +332,8 @@ namespace omath
return reinterpret_cast<std::uintptr_t>(&*result); return reinterpret_cast<std::uintptr_t>(&*result);
return std::nullopt; return std::nullopt;
#else },
throw std::runtime_error("Pattern scan for loaded modules is only for windows platform"); nt_header_variant.value());
#endif
} }
std::optional<PeSectionScanResult> std::optional<PeSectionScanResult>
PePatternScanner::scan_for_pattern_in_file(const std::filesystem::path& path_to_file, PePatternScanner::scan_for_pattern_in_file(const std::filesystem::path& path_to_file,