Replacements - TekkaGB/Inaba-Exe-Patcher GitHub Wiki

Similar to regular .patch files, replacements allow you to replace things in the exe such as text, however replacements have an easier to use syntax and support advanced features such as signature scanning.

Example

If you just want to look at a heavily commented example check out Replacement Example.expatch.

Specification

Below is a specification for the format used by expatch replacements, any heading suffixed with an * is mandatory for the replacements to work, everything else is optional.

Declaring A Replacement*

To start a function hook put a [replacement] tag in your expatch, optionally you can also name your replacements (this is recommended as the names are used in logging) by putting it inside of the tag such as [replacement My Replacement]. Everything below this replacement tag up until another replacement or patch tag will be considered part of the same replacement.

Locating The Stuff*

There are two ways that replacements can find what you want to replace, either using a simple search or signature scanning.

Simple Search

A simple search takes a value such as a string and searches for the first exact occurrence of it which is then replaced. To use a search add search = "The thing to search for" to your expatch. Here if you are searching for a string you'll need to surround it with " however, you can also search for any other Value Type (strings will be the most useful).

Signature Scan

Signature scanning works the same way that it does for Function Hooks where a certain code signature is used to find the address to replace at. To use it add pattern = 68 ?? 6C 6C 6F, note that spacing between characters is not required (but it looks nice), and wildcards are done using ?? as described in the cheat sheet.

This is useful if you're changing something that may slightly change between versions of the game or if you're doing very small code changes (such as removing a single instruction). For most code changes, however, it is recommended that you use Function Hooks as they are more suited to it. For information about creating patterns please check Reloaded's signature scanning cheat sheet.

Replacing The Stuff*

To define what you want to set the found memory to you use replacement = "The new stuff". Here if you are setting it to a string you'll need to surround it with " however, you can also set it to any other Value Type (strings will be the most useful).

Pad Null

When replacing strings by default if the replacement is shorter than the original any extra characters are set to null characters (c style string terminators) however, sometimes this is not desirable. You can disable this by using padNull = false (you could also explicitly enable it although it is always on by default).

For example, if you search for "The" and replace it with "An" having this off will result in "Ane" in memory, with it on it will be "An".

Offsets

You may want to replace something slightly away from a location, as such you can set an offset which will offset the location of your replacement from the address found by the search. To do so add offset = x where x is an integer (positive or negative).

For example, if you've defined a pattern that finds the address 1340 but the stuff you actually want to replace is at 1337 you could have offset = -3 inside of your replacement.

Indices

If there are duplicates of what you are replacing and you either can't get a unique pattern for the one you want to replace or you want to replace multiple you can use indices. By adding index = x, y, z you can replace specific occurrences of your pattern or search. If you just want to replace every occurrence of it you can instead use index = all. If you do not define an index only the first occurrence will ever be replaced.

For example, if you are trying to replace a string but there are 5 occurrences of it and you only want to change the 1st and 4th you could add index = 1, 4 to your replacement.

Constants

Constants are named values that you can use in expatches for things like adding basic "configuration" to your mods or just to remove magic numbers. Unlike variables these are not assigned space in memory, instead, they simply act as values that are found and replaced throughout your expatch file. They are also global and can be used before or after they're defined.

To define a constant use const constantName = value. Here value does not have to be a valid value type, it is simply any text (there is no parsing done directly on it). To use a constant you simply put {constantName} anywhere in your file and it will be replaced with your value of constantName when the patch is applied.

Scanning For Constants

When defining a constant you can set the value as scan(pattern) and a signature scan will be performed, the address found will then be used as the constant's value.

For example, you could define the constant const timePtr = scan(E8 ?? ?? ?? ?? A1 ?? ?? ?? ?? 8D 55 ?? 8B 0D ?? ?? ?? ??) and then use that value as a replacement value if you wanted to replace an existing pointer with one that points to another existing variable or function.