How ScriptPointer and ScriptPatch Enable Runtime Script Modification in YimMenuV2
YimMenuV2 exposes two complementary Lua objects—ScriptPointer for dynamic address resolution and ScriptPatch for live byte manipulation—that together enable runtime script modification without restarting GTA V.
YimMenuV2 provides developers with powerful tools to inspect and alter GTA V's native script behavior while the game executes. Through the ScriptPointer and ScriptPatch classes exposed to the Lua environment, the menu enables runtime script modification by allowing scripts to locate memory addresses via pattern matching and apply hot-patches to alter game logic on the fly.
Understanding the Core Components
ScriptPointer: Dynamic Memory Address Resolution
ScriptPointer serves as the address resolution layer for runtime script modification. According to the source code in YimMenu/YimMenuV2, this class encapsulates a resolved memory pointer and provides arithmetic operations to navigate script structures.
The implementation resides in src/game/scripting/libraries/ScriptPointer.cpp, where ScriptPointerBinding::New constructs pointers from name-pattern pairs or explicit addresses. The underlying C++ class—defined in src/game/gta/ScriptPointer.hpp—stores the resolved address and exposes methods including Add, Sub, Rip, and Scan.
When registered with Lua, ScriptPointer creates a metatable exposing methods such as:
addandsub– Offset arithmetic for pointer adjustmentrip– Resolution of relative addresses (RIP-relative addressing)scan– Lookup of script programs viaScripts::FindScriptProgramusing hash identifiersget_addressandget_name– Introspection utilities
The Scan method specifically enables cross-script references by locating a script program through its hash and returning a new pointer to that script's code block, facilitating dynamic script-to-script interaction.
ScriptPatch: Byte-Level Code Modification
While ScriptPointer locates targets, ScriptPatch executes the actual runtime script modification through byte-level patching. Implemented in src/game/scripting/libraries/ScriptPatch.cpp, this class manages writable overlays that replace original game bytes with custom instructions.
The ScriptPatch constructor accepts a name, pattern, and replacement byte buffer, using the same signature-matching logic as ScriptPointer to resolve target addresses. The binding registers a "ScriptPatch" metatable with Lua, providing three core operations:
apply– Writes replacement bytes to the resolved address usingcore/memory/BytePatches.cpputilitiesremove– Restores original bytes from internal backuptoggle– Switches between patched and original statesis_applied– Query method for patch state verification
This architecture decouples address resolution from modification, allowing patches to be maintained separately from the pointers that locate them.
How ScriptPointer Locates Script Targets
The address resolution pipeline begins with pattern matching against GTA V's script bytecode. In src/game/scripting/libraries/ScriptPointer.cpp, the binding layer parses constructor arguments including:
- A human-readable name for debugging
- A
SimplePatternbyte sequence with wildcards - Optional offset parameters for pointer adjustment
Once constructed, the ScriptPointer object can traverse script memory using arithmetic methods. For example, calling Sub adjusts the pointer backward by specified offsets, while Rip handles x64 RIP-relative addressing calculations common in native game code.
The Scan functionality—leveraging Scripts::FindScriptProgram from src/game/gta/Scripts.hpp—enables scripts to locate other active script programs by hash, returning a new ScriptPointer instance referencing that script's code block. This allows Lua scripts to reference and potentially modify external script resources dynamically.
How ScriptPatch Applies Live Modifications
After resolution, ScriptPatch handles the actual memory manipulation. The class encapsulates both the target address (resolved during construction) and a buffer of replacement bytes. When apply is invoked, the patch writes to game memory using low-level utilities in src/core/memory/BytePatches.cpp.
Key characteristics of the patching system include:
- Atomic application – Patches are applied as contiguous byte sequences
- Backup preservation – Original bytes are stored internally to support
removeoperations - State tracking – The
is_appliedmethod prevents redundant writes or premature removals
This mechanism enables hot-patching of native functions or script blocks, allowing immediate behavioral changes without process restarts or file modifications.
Practical Implementation Workflow
Combining these components enables sophisticated runtime script modification workflows:
- Locate – Create a
ScriptPointerusing signature patterns to find the target native function or script block - Adjust – Use arithmetic methods (
add,sub) orripto navigate to the exact injection point - Reference – Optionally
scanto locate related script programs by hash - Patch – Instantiate a
ScriptPatchat the resolved address with replacement bytes - Modify – Call
applyto write changes,removeto restore, ortoggleto switch states
The Lua binding allows dynamic interaction, enabling conditional patching based on game state queries.
Code Examples
Creating a pointer and scanning for a script program:
local ptr = ScriptPointer("myScript", "48 89 ?? ?? ?? 48 8B ??", 0)
local scriptPtr = ptr:scan("SCRIPT_HASH") -- resolves the script block
print("Address:", scriptPtr:get_address())
Applying a byte patch to disable a function:
-- Replace function prologue with NOPs (0x90)
local patch = ScriptPatch("nopFunc", "40 53 48 83 EC 20", "\x90\x90\x90\x90\x90")
patch:apply() -- writes the NOP sled to memory
-- Later restoration...
patch:remove() -- restores original 5 bytes
Summary
- ScriptPointer (
src/game/scripting/libraries/ScriptPointer.cpp) provides dynamic address resolution via pattern matching, arithmetic operations, and cross-script scanning throughScripts::FindScriptProgram - ScriptPatch (
src/game/scripting/libraries/ScriptPatch.cpp) enables live byte modification withapply,remove, andtogglemethods backed bycore/memory/BytePatches.cpp - Together, these classes allow Lua scripts to locate arbitrary game addresses and modify them at runtime without restarting GTA V
- The architecture separates concerns:
ScriptPointerhandles "where," whileScriptPatchhandles "what to change"
Frequently Asked Questions
How does ScriptPointer handle pattern matching for address resolution?
ScriptPointer uses the SimplePattern class to match byte sequences against GTA V's script memory. The constructor in ScriptPointerBinding::New accepts a pattern string with wildcard characters (typically ?? for unknown bytes) and an optional offset. When matched, the base address is calculated and stored in the underlying C++ ScriptPointer class, allowing subsequent arithmetic operations to navigate the resolved memory region.
Can ScriptPatch modifications be detected by GTA V's anti-cheat systems?
ScriptPatch writes directly to process memory using the byte-patch utilities in src/core/memory/BytePatches.cpp. While the patches modify executable script regions, YimMenuV2 implements these changes at the memory level below standard script verification layers. However, the persistence and detectability depend on the specific bytes modified and Rockstar's current anti-cheat heuristics, which are subject to change with game updates.
What is the difference between the rip and scan methods in ScriptPointer?
The rip method performs RIP-relative address calculation—common in x64 architecture where addresses are encoded as offsets from the instruction pointer—effectively dereferencing relative pointers within the current script context. Conversely, scan searches the global script table via Scripts::FindScriptProgram to locate entirely different script programs by their hash, returning a pointer to that external script's code block rather than adjusting the current pointer.
How do I safely remove a ScriptPatch to restore original game behavior?
Call the remove method on your ScriptPatch instance. The class maintains an internal backup of the original bytes captured during construction in src/game/scripting/libraries/ScriptPatch.cpp. When remove is invoked, it writes these backed-up bytes back to the target address using the same memory utilities in src/core/memory/BytePatches.cpp, effectively restoring the original instructions without requiring a game restart.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →