From ba13f13c1195e41dcda8e1aec2043405b3521292 Mon Sep 17 00:00:00 2001 From: Emmanuel AYME Date: Fri, 27 Feb 2026 22:39:52 +0100 Subject: [PATCH] Moved preprocessor log to hpp file. Add AOB scan by region and base address --- libs/Memory/Memory.cpp | 83 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/libs/Memory/Memory.cpp b/libs/Memory/Memory.cpp index 4984984..948bdd3 100644 --- a/libs/Memory/Memory.cpp +++ b/libs/Memory/Memory.cpp @@ -10,18 +10,6 @@ #include #include -// Rich verbose for internal release only -#ifdef MY_VERBOSE_LOGS -#define LOG_SIGNATURE_FOUND(name, addr) \ - logger->info( \ - "{} signature found at address: 0x{:X}.", \ - name, addr \ - ) -#else -#define LOG_SIGNATURE_FOUND(name, addr) \ - logger->info("{} signature found", name) -#endif - static std::shared_ptr _log; std::unordered_map Memory::patches; @@ -125,9 +113,7 @@ std::string Memory::ByteToHexEscaped(const BYTE byte) { return oss.str(); } -uint8_t* Memory::AOBScan( - const std::string& module_name, - const std::string& signature, +uint8_t* Memory::AOBScan(const std::string& module_name, const std::string& signature, DWORD protect_flags = PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY, std::shared_ptr log) { @@ -221,6 +207,73 @@ uint8_t* Memory::AOBScan( return nullptr; } +uint8_t* Memory::AOBScanInternal(uint8_t* base, const char* label, size_t size, const std::string& signature, DWORD protect_flags, std::shared_ptr logger) { + if (!base || size == 0) return nullptr; + + // Convert AOB string into vector bytes + std::vector pattern_bytes; + std::istringstream stream(signature); + std::string byte_str; + + while (stream >> byte_str) { + if (byte_str == "??" || byte_str == "?") + pattern_bytes.push_back(-1); + else + pattern_bytes.push_back(static_cast(std::strtol(byte_str.c_str(), nullptr, 16))); + } + + if (pattern_bytes.empty()) return nullptr; + + if (logger) logger->info("Scanning JIT method region: 0x{:X} - 0x{:X}", reinterpret_cast(base), reinterpret_cast(base + size)); + + MEMORY_BASIC_INFORMATION mbi{}; + + for (uint8_t* current = base; current < base + size;) { + + if (!VirtualQuery(current, &mbi, sizeof(mbi))) + break; + + bool isCommitted = (mbi.State & MEM_COMMIT) != 0; + bool hasAccess = (mbi.Protect & protect_flags) != 0; + bool isNoAccess = (mbi.Protect & PAGE_NOACCESS) != 0; + bool isGuard = (mbi.Protect & PAGE_GUARD) != 0; + + if (isCommitted && hasAccess && !isNoAccess && !isGuard) { + + uint8_t* regionBase = reinterpret_cast(mbi.BaseAddress); + size_t regionSize = mbi.RegionSize; + + // Clamp region inside requested range + uint8_t* regionEnd = regionBase + regionSize; + uint8_t* scanStart = max(regionBase, base); + uint8_t* scanEnd = min(regionEnd, base + size); + + size_t scanSize = scanEnd - scanStart; + + for (size_t i = 0; i <= scanSize - pattern_bytes.size(); ++i) { + bool match = true; + + for (size_t j = 0; j < pattern_bytes.size(); ++j) { + if (pattern_bytes[j] != -1 && + scanStart[i + j] != static_cast(pattern_bytes[j])) { + match = false; + break; + } + } + + if (match) { + LOG_SIGNATURE_FOUND(label, reinterpret_cast(scanStart + i)); + return scanStart + i; + } + } + } + + current = reinterpret_cast(mbi.BaseAddress) + mbi.RegionSize; + } + + return nullptr; +} + void Memory::AOBScanBatch(const std::vector& entries, std::shared_ptr logger) { for (auto scanEntry = entries.begin(); scanEntry != entries.end(); ++scanEntry) { if (*scanEntry->address) continue;