From f3fe0e3cee8ecf53e15a805d5891e2a13a4bce10 Mon Sep 17 00:00:00 2001 From: Orange Date: Tue, 7 Oct 2025 06:14:42 +0300 Subject: [PATCH] added pe pattern scan --- include/omath/utility/pattern_scan.hpp | 2 +- include/omath/utility/pe_pattern_scan.hpp | 22 ++++++++++++ source/utility/pe_pattern_scan.cpp | 44 +++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 include/omath/utility/pe_pattern_scan.hpp create mode 100644 source/utility/pe_pattern_scan.cpp diff --git a/include/omath/utility/pattern_scan.hpp b/include/omath/utility/pattern_scan.hpp index d8486f0..35d9314 100644 --- a/include/omath/utility/pattern_scan.hpp +++ b/include/omath/utility/pattern_scan.hpp @@ -26,7 +26,7 @@ namespace omath { INVALID_PATTERN_STRING }; - class PatternScanner + class PatternScanner final { friend unit_test_pattern_scan_read_test_Test; friend unit_test_pattern_scan_corner_case_1_Test; diff --git a/include/omath/utility/pe_pattern_scan.hpp b/include/omath/utility/pe_pattern_scan.hpp new file mode 100644 index 0000000..8acdbae --- /dev/null +++ b/include/omath/utility/pe_pattern_scan.hpp @@ -0,0 +1,22 @@ +// +// Created by Vlad on 10/7/2025. +// + +#pragma once +#include +#include +#include +#include +namespace omath +{ + class PePatternScanner final + { + public: + [[nodiscard]] + static std::optional scan_for_pattern_in_loaded_module(const std::string_view& module_name, + const std::string_view& pattern); + + [[nodiscard]] + static std::optional scan_for_pattern_in_file(const std::filesystem::path& path_to_file); + }; +} // namespace omath \ No newline at end of file diff --git a/source/utility/pe_pattern_scan.cpp b/source/utility/pe_pattern_scan.cpp new file mode 100644 index 0000000..54530b1 --- /dev/null +++ b/source/utility/pe_pattern_scan.cpp @@ -0,0 +1,44 @@ +// +// Created by Vlad on 10/7/2025. +// +#include "omath/utility/pe_pattern_scan.hpp" +#include "omath/utility/pattern_scan.hpp" +#include +#include +#ifdef _WIN32 +#include +#endif + +namespace omath +{ + + std::optional + PePatternScanner::scan_for_pattern_in_loaded_module(const std::string_view& module_name, + const std::string_view& pattern) + { +#ifdef _WIN32 + const auto base_address = reinterpret_cast(GetModuleHandleA(module_name.data())); + + 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); + + // Define .code segment as scan area + const auto start = image_nt_headers->OptionalHeader.BaseOfCode; + const auto scan_size = image_nt_headers->OptionalHeader.SizeOfCode; + + const auto scan_range = std::span{reinterpret_cast(base_address) + start, scan_size}; + + const auto result = PatternScanner::scan_for_pattern(scan_range, pattern); + + if (result != scan_range.cend()) + return reinterpret_cast(&*result); + + return std::nullopt; +#else + throw std::runtime_error("Pattern scan for loaded modules is only for windows platform"); +#endif + } +} // namespace omath \ No newline at end of file