# How ScriptPointer and ScriptPatch Enable Runtime Script Modification in YimMenuV2

> Learn how YimMenuV2 uses ScriptPointer and ScriptPatch for runtime script modification in GTA V. Dynamically resolve addresses and patch bytes live without restarts.

- Repository: [YimMenu/YimMenuV2](https://github.com/YimMenu/YimMenuV2)
- Tags: deep-dive
- Published: 2026-07-16

---

**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`](https://github.com/YimMenu/YimMenuV2/blob/main/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`](https://github.com/YimMenu/YimMenuV2/blob/main/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:

- **`add`** and **`sub`** – Offset arithmetic for pointer adjustment
- **`rip`** – Resolution of relative addresses (RIP-relative addressing)
- **`scan`** – Lookup of script programs via `Scripts::FindScriptProgram` using hash identifiers
- **`get_address`** and **`get_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`](https://github.com/YimMenu/YimMenuV2/blob/main/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 using [`core/memory/BytePatches.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/core/memory/BytePatches.cpp) utilities
- **`remove`** – Restores original bytes from internal backup
- **`toggle`** – Switches between patched and original states
- **`is_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`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/ScriptPointer.cpp), the binding layer parses constructor arguments including:

1. A human-readable name for debugging
2. A `SimplePattern` byte sequence with wildcards
3. 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`](https://github.com/YimMenu/YimMenuV2/blob/main/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`](https://github.com/YimMenu/YimMenuV2/blob/main/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 `remove` operations
- **State tracking** – The `is_applied` method 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:

1. **Locate** – Create a `ScriptPointer` using signature patterns to find the target native function or script block
2. **Adjust** – Use arithmetic methods (`add`, `sub`) or `rip` to navigate to the exact injection point
3. **Reference** – Optionally `scan` to locate related script programs by hash
4. **Patch** – Instantiate a `ScriptPatch` at the resolved address with replacement bytes
5. **Modify** – Call `apply` to write changes, `remove` to restore, or `toggle` to 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:

```lua
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:

```lua
-- 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`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/ScriptPointer.cpp)) provides dynamic address resolution via pattern matching, arithmetic operations, and cross-script scanning through `Scripts::FindScriptProgram`
- **ScriptPatch** ([`src/game/scripting/libraries/ScriptPatch.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/ScriptPatch.cpp)) enables live byte modification with `apply`, `remove`, and `toggle` methods backed by [`core/memory/BytePatches.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/core/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: `ScriptPointer` handles "where," while `ScriptPatch` handles "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`](https://github.com/YimMenu/YimMenuV2/blob/main/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`](https://github.com/YimMenu/YimMenuV2/blob/main/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`](https://github.com/YimMenu/YimMenuV2/blob/main/src/core/memory/BytePatches.cpp), effectively restoring the original instructions without requiring a game restart.