mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 07:03:25 +00:00
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:
@@ -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]]
|
||||||
|
|||||||
@@ -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,35 +303,37 @@ 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);
|
|
||||||
|
|
||||||
// Define .code segment as scan area
|
if (!nt_header_variant)
|
||||||
const auto start = image_nt_headers->OptionalHeader.BaseOfCode;
|
return std::nullopt;
|
||||||
const auto scan_size = image_nt_headers->OptionalHeader.SizeOfCode;
|
|
||||||
|
|
||||||
const auto scan_range = std::span{reinterpret_cast<std::byte*>(base_address) + start, scan_size};
|
return std::visit(
|
||||||
|
[base_address, &pattern](const auto& nt_header) -> std::optional<std::uintptr_t>
|
||||||
|
{
|
||||||
|
// 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 scan_range = std::span{reinterpret_cast<std::byte*>(base_address) + start, scan_size};
|
||||||
const auto result = PatternScanner::scan_for_pattern(scan_range, pattern);
|
|
||||||
|
|
||||||
if (result != scan_range.cend())
|
// ReSharper disable once CppTooWideScopeInitStatement
|
||||||
return reinterpret_cast<std::uintptr_t>(&*result);
|
const auto result = PatternScanner::scan_for_pattern(scan_range, pattern);
|
||||||
|
|
||||||
return std::nullopt;
|
if (result != scan_range.cend())
|
||||||
#else
|
return reinterpret_cast<std::uintptr_t>(&*result);
|
||||||
throw std::runtime_error("Pattern scan for loaded modules is only for windows platform");
|
|
||||||
#endif
|
return std::nullopt;
|
||||||
|
},
|
||||||
|
nt_header_variant.value());
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user