Skip to content

Commit 568883f

Browse files
authored
Merge pull request #87 from orange-cpp/feature/no_win_api
Removes Windows-specific API dependencies for pattern scanning
2 parents 97003b9 + 5646654 commit 568883f

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

include/omath/utility/pe_pattern_scan.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace omath
1919
{
2020
public:
2121
[[nodiscard]]
22-
static std::optional<std::uintptr_t> scan_for_pattern_in_loaded_module(const std::string_view& module_name,
22+
static std::optional<std::uintptr_t> scan_for_pattern_in_loaded_module(const void* module_base_address,
2323
const std::string_view& pattern);
2424

2525
[[nodiscard]]

source/utility/pe_pattern_scan.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#include <span>
88
#include <stdexcept>
99
#include <variant>
10-
#ifdef _WIN32
11-
#include <Windows.h>
12-
#endif
1310

1411
// Internal PE shit defines
1512
// Big thx for linuxpe sources as ref
@@ -206,6 +203,26 @@ namespace
206203
return x64_headers;
207204
}
208205

206+
[[nodiscard]]
207+
std::optional<NtHeaderVariant> get_nt_header_from_loaded_module(const void* module_base_address)
208+
{
209+
const auto module_byte_ptr = static_cast<const std::byte*>(module_base_address);
210+
ImageNtHeaders<NtArchitecture::x32_bit> x86_headers{};
211+
const auto dos_header = static_cast<const DosHeader*>(module_base_address);
212+
213+
x86_headers = *reinterpret_cast<const ImageNtHeaders<NtArchitecture::x32_bit>*>(module_byte_ptr
214+
+ dos_header->e_lfanew);
215+
216+
if (x86_headers.optional_header.magic == opt_hdr32_magic)
217+
return x86_headers;
218+
219+
if (x86_headers.optional_header.magic != opt_hdr64_magic)
220+
return std::nullopt;
221+
222+
return *reinterpret_cast<const ImageNtHeaders<NtArchitecture::x64_bit>*>(module_byte_ptr
223+
+ dos_header->e_lfanew);
224+
}
225+
209226
[[nodiscard]]
210227
constexpr bool invalid_dos_header_file(const DosHeader& dos_header)
211228
{
@@ -286,35 +303,37 @@ namespace
286303
namespace omath
287304
{
288305

289-
std::optional<std::uintptr_t>
290-
PePatternScanner::scan_for_pattern_in_loaded_module([[maybe_unused]] const std::string_view& module_name,
291-
[[maybe_unused]] const std::string_view& pattern)
306+
std::optional<std::uintptr_t> PePatternScanner::scan_for_pattern_in_loaded_module(const void* module_base_address,
307+
const std::string_view& pattern)
292308
{
293-
#ifdef _WIN32
294-
const auto base_address = reinterpret_cast<std::uintptr_t>(GetModuleHandleA(module_name.data()));
309+
const auto base_address = reinterpret_cast<std::uintptr_t>(module_base_address);
295310

296311
if (!base_address)
297312
return std::nullopt;
298313

299-
const auto dos_headers = reinterpret_cast<PIMAGE_DOS_HEADER>(base_address);
300-
const auto image_nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS>(base_address + dos_headers->e_lfanew);
314+
auto nt_header_variant = get_nt_header_from_loaded_module(module_base_address);
301315

302-
// Define .code segment as scan area
303-
const auto start = image_nt_headers->OptionalHeader.BaseOfCode;
304-
const auto scan_size = image_nt_headers->OptionalHeader.SizeOfCode;
316+
if (!nt_header_variant)
317+
return std::nullopt;
305318

306-
const auto scan_range = std::span{reinterpret_cast<std::byte*>(base_address) + start, scan_size};
319+
return std::visit(
320+
[base_address, &pattern](const auto& nt_header) -> std::optional<std::uintptr_t>
321+
{
322+
// Define .code segment as scan area
323+
const auto start = nt_header.optional_header.base_of_code;
324+
const auto scan_size = nt_header.optional_header.size_code;
325+
326+
const auto scan_range = std::span{reinterpret_cast<std::byte*>(base_address) + start, scan_size};
307327

308-
// ReSharper disable once CppTooWideScopeInitStatement
309-
const auto result = PatternScanner::scan_for_pattern(scan_range, pattern);
328+
// ReSharper disable once CppTooWideScopeInitStatement
329+
const auto result = PatternScanner::scan_for_pattern(scan_range, pattern);
310330

311-
if (result != scan_range.cend())
312-
return reinterpret_cast<std::uintptr_t>(&*result);
331+
if (result != scan_range.cend())
332+
return reinterpret_cast<std::uintptr_t>(&*result);
313333

314-
return std::nullopt;
315-
#else
316-
throw std::runtime_error("Pattern scan for loaded modules is only for windows platform");
317-
#endif
334+
return std::nullopt;
335+
},
336+
nt_header_variant.value());
318337
}
319338
std::optional<PeSectionScanResult>
320339
PePatternScanner::scan_for_pattern_in_file(const std::filesystem::path& path_to_file,

0 commit comments

Comments
 (0)