How YimMenuV2's Pattern Scanning System Locates Functions in GTA5_Enhanced.exe

YimMenuV2 uses a modular pattern scanner with IDA-style signatures, asynchronous parallel scanning, and persistent caching to locate functions and data structures in GTASEnhanced.exe at runtime.

YimMenuV2 implements a sophisticated memory pattern scanning system to dynamically resolve function addresses inside GTASEnhanced.exe without relying on static offsets. This architecture enables the menu to survive game updates by searching for unique byte sequences rather than hardcoded addresses. The scanner operates through a pipeline of module abstraction, signature parsing, and cached memory traversal.

Core Architecture of the Pattern Scanner

The pattern scanning system in YimMenuV2 is built on three foundational components that work together to map the game's memory space.

Module Abstraction

Every scan targets a specific Module object that wraps a loaded PE image. The Module class defined in src/core/memory/Module.hpp (lines 21-95) exposes critical memory boundaries through methods like Base(), Size(), and End(). When scanning GTASEnhanced.exe, the scanner typically receives the main executable module retrieved via ModuleMgr.GetModule("GTASEnhanced.exe"), establishing the searchable address range from the module's base address to its end address.

Pattern Definition and Parsing

Patterns use IDA-style signatures such as "48 89 ?? ?? 8B ??" where hexadecimal bytes represent exact matches and ?? acts as wildcards. The SimplePattern class in src/core/memory/Pattern.cpp (lines 35-59) parses these strings into a byte vector where concrete values occupy specific positions and wildcards become std::nullopt. This representation allows the scanner to perform flexible matching against the raw memory of GTASEnhanced.exe while maintaining the exact byte relationships found in the game's compiled code.

The Scanning Process

The PatternScanner class orchestrates the search operation through a multi-stage pipeline that prioritizes performance and reliability.

Asynchronous Orchestration

The scanner maintains an internal list of (IPattern*, PatternFunc) pairs representing signatures and their associated callback functions. According to the implementation in src/core/memory/PatternScanner.cpp (lines 17-46), the Scan() method iterates over these pairs and launches each search as a separate std::async task, enabling parallel execution across multiple CPU cores. However, if the process is detected as manual-mapped, the scanner automatically falls back to sequential execution to prevent race conditions in modified memory environments.

Cache-First Resolution

Before performing expensive memory traversals, the scanner consults PatternCache to check for previously resolved offsets. As implemented in src/core/memory/PatternScanner.cpp (lines 54-62), the cache hashes the pattern signature combined with the module size to generate a unique key. If a cached offset exists, the scanner immediately invokes the callback with the stored address, eliminating redundant scanning. Upon successful discovery of a new pattern, the system writes the offset back to the cache (lines 86-90) for subsequent runs, significantly improving initialization times after the first execution.

Byte-by-Byte Matching

When the cache misses, ScanInternal performs a linear scan through the module's memory range from Base() to End(). The algorithm verifies that sufficient bytes remain within the module boundaries, then compares each signature byte against memory, treating std::nullopt entries as wildcards that match any value. Upon finding a complete match in src/core/memory/PatternScanner.cpp (lines 65-92), the scanner logs the resolved address, executes the stored callback function with the matched pointer, updates the persistent cache, and terminates the search for that specific pattern.

Integration with GTA5_Enhanced.exe

The pattern scanner serves as the backbone for YimMenuV2's runtime function resolution throughout the codebase.

In src/game/pointers/Pointers.cpp (lines 5-30), the scanner resolves critical GTA 5 native functions required for the menu's core functionality. The system also exposes these capabilities to Lua scripting through src/core/scripting/libraries/Memory.cpp (lines 3-70), allowing custom scripts to perform their own signature scans.

// Locating NETWORK_GET_NETWORK_ID_FROM_PLAYER in GTASEnhanced.exe
auto gta5 = ModuleMgr.GetModule("GTASEnhanced.exe");
PatternScanner scanner(gta5);

scanner.AddPattern(
    new SimplePattern("48 89 ?? ?? 8B ?? ?? ?? ?? ?? 48 8B ??"),
    [](std::uintptr_t addr) {
        g_NetworkGetNetworkIdFromPlayer = reinterpret_cast<decltype(g_NetworkGetNetworkIdFromPlayer)>(addr);
        LOG(INFO) << "Resolved NETWORK_GET_NETWORK_ID_FROM_PLAYER at " << HEX(addr);
    }
);

scanner.Scan();  // Executes async scan (sequential if manual-mapped)
-- Lua exposure via Memory library
function memory.scanPattern(sig, callback)
    local scanner = PatternScanner(gta5)  -- gta5 = GTASEnhanced.exe module
    scanner:AddPattern(SimplePattern(sig), function(addr)
        callback(addr)
    end)
    scanner:Scan()
end

Summary

  • YimMenuV2 locates functions in GTASEnhanced.exe using a PatternScanner that operates on Module objects representing loaded PE images.
  • Signatures follow IDA-style syntax with wildcards, parsed by SimplePattern in src/core/memory/Pattern.cpp into searchable byte vectors.
  • The scanner uses asynchronous parallel execution via std::async for performance, falling back to sequential mode for manual-mapped processes.
  • A persistent cache stores resolved offsets hashed against module sizes, eliminating redundant scans across application restarts.
  • The system is integrated throughout the codebase, from native function resolution in Pointers.cpp to Lua scripting interfaces in Memory.cpp.

Frequently Asked Questions

What signature format does YimMenuV2 use for pattern scanning?

YimMenuV2 uses IDA-style signatures consisting of hexadecimal byte pairs separated by spaces, where ?? represents wildcard bytes that match any value. The SimplePattern class in src/core/memory/Pattern.cpp (lines 35-59) parses these strings into byte vectors where wildcards become std::nullopt, allowing flexible matching against GTASEnhanced.exe memory.

How does the scanner handle multiple patterns efficiently?

The PatternScanner class launches each pattern search as an independent std::async task, enabling parallel execution across CPU cores as seen in src/core/memory/PatternScanner.cpp (lines 17-46). This asynchronous approach significantly reduces initialization time when resolving numerous functions in GTASEnhanced.exe, except when running in manual-mapped mode where sequential execution prevents memory corruption.

Does YimMenuV2 cache pattern scan results between sessions?

Yes. The scanner implements a persistent cache that stores resolved offsets hashed with the module size, as implemented in src/core/memory/PatternScanner.cpp (lines 54-62 and 86-90). On subsequent runs, the scanner checks this cache before performing memory traversals, immediately returning cached addresses for known patterns to minimize startup latency.

Which source files contain the core pattern scanning implementation?

The primary implementation resides in src/core/memory/PatternScanner.cpp for the scanning engine and cache integration, src/core/memory/Pattern.cpp for signature parsing, and src/core/memory/Module.hpp for PE module abstraction. Usage examples appear in src/game/pointers/Pointers.cpp for GTA 5 native resolution and src/core/scripting/libraries/Memory.cpp for Lua exposure.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →