|
7 | 7 | #include <span> |
8 | 8 | #include <stdexcept> |
9 | 9 | #include <variant> |
10 | | -#ifdef _WIN32 |
11 | | -#include <Windows.h> |
12 | | -#endif |
13 | 10 |
|
14 | 11 | // Internal PE shit defines |
15 | 12 | // Big thx for linuxpe sources as ref |
@@ -206,6 +203,26 @@ namespace |
206 | 203 | return x64_headers; |
207 | 204 | } |
208 | 205 |
|
| 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 | + |
209 | 226 | [[nodiscard]] |
210 | 227 | constexpr bool invalid_dos_header_file(const DosHeader& dos_header) |
211 | 228 | { |
@@ -286,35 +303,37 @@ namespace |
286 | 303 | namespace omath |
287 | 304 | { |
288 | 305 |
|
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) |
292 | 308 | { |
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); |
295 | 310 |
|
296 | 311 | if (!base_address) |
297 | 312 | return std::nullopt; |
298 | 313 |
|
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); |
301 | 315 |
|
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; |
305 | 318 |
|
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}; |
307 | 327 |
|
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); |
310 | 330 |
|
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); |
313 | 333 |
|
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()); |
318 | 337 | } |
319 | 338 | std::optional<PeSectionScanResult> |
320 | 339 | PePatternScanner::scan_for_pattern_in_file(const std::filesystem::path& path_to_file, |
|
0 commit comments