GameFindPattern Method (String, IntPtr)

RAGE Plugin Hook Documentation

[This is preliminary documentation and is subject to change.]

Finds the specified pattern of bytes in the game's memory.

Namespace:  Rage
Assembly:  RagePluginHook (in RagePluginHook.dll) Version: 0.0.0.0 (0.56.1131.11510)
Syntax

public static IntPtr FindPattern(
	string pattern,
	IntPtr startAddress
)

Parameters

pattern
Type: SystemString
The pattern to find. Wildcard ?? is supported.
startAddress
Type: SystemIntPtr
The address to start searching at. If Zero, search is started at the base address.

Return Value

Type: IntPtr
An IntPtr representing the memory location the pattern was found at, or Zero if the pattern wasn't found.
Remarks

The pattern should be in the following format:

XX XX XX XX XX XX XX XX XX XX

Where each XX is a hexadecimal value representing the byte, or ?? to indicate a wildcard.

eg. "77 37 E8 ?? ?? ?? ?? 84 C0"

All white space is ignored.

Even though the search algorithm is fast, you shouldn't be calling this every frame.

Ideally, you want to find all the patterns you need when your plugin initializes.

Examples

When a new game patch is released, the memory layout of the game process changes. This means that variables, code, etc. is no longer at the same offsets as in a previous patch. To overcome this problem, byte pattern scanning can be used to find the correct addresses.
The following example shows a method that uses FindPattern to locate a piece of code that accesses the GameTime variable (The variable accessed by GET_GAME_TIMER), and then gets the address of the variable.
C#
private static IntPtr gameTimeAddress;
private unsafe static uint GetGameTime()
{
    if (gameTimeAddress == IntPtr.Zero)
    {
        string pattern =
        "8B 05 ?? ?? ?? ??" +   // mov     eax, [????????]
        "05 D0 07 00 00" +      // add     eax, 7D0h
        "39 05 ?? ?? ?? ??" +   // cmp     [GameTime], eax
        "77 37" +               // ja      short ????????
        "E8 ?? ?? ?? ??";      // call    ????????
        IntPtr address = Game.FindPattern(pattern, IntPtr.Zero);
        if (address == IntPtr.Zero)
        {
            // Pattern not found.
            return 0u;
        }

        address += 11; // Brings the address to the cmp instruction (39 05 ?? ?? ?? ??).

        // The CMP instruction uses an offset to the variable, not an absolute address.
        // The offset is from the address of the next instruction.
        // The offset is the last 4 bytes of the instruction.
        long offset = (long)*(int*)(address + 2); // Read the offset (cmp instruction address + 2).
        gameTimeAddress = (IntPtr)(address.ToInt64() + 6 + offset); // Address of GameTime = address of cmp instruction + size of cmp instruction (to get to next instruction) + offset.
    }

    return *(uint*)gameTimeAddress;
}
See Also

Reference