Accessing Memory - Jamiras/RATools GitHub Wiki
The following built-in functions are provided for accessing memory:
byte(address)- the 8-bit value at the specified addressword(address)- the 16-bit value at the specified addresstbyte(address)- the 24-bit value at the specified addressdword(address)- the 32-bit value at the specified addressbit0(address)- the least significant bit of the specified addressbit1(address)- the second least significant bit of the specified addressbit2(address)- the third least significant bit of the specified addressbit3(address)- the fourth least significant bit of the specified addressbit4(address)- the fifth least significant bit of the specified addressbit5(address)- the sixth least significant bit of the specified addressbit6(address)- the seventh least significant bit of the specified addressbit7(address)- the most significant bit of the specified addressbit(index, address)- theindexth bit of the specified address (indexmust be between 0 and 31)low4(address)- the four least significant bits of the specified addresshigh4(address)- the four most significant bits of the specified addressbitcount(address)- the number of non-zero bits at the specified addressword_be(address)- the 16-bit big-endian value at the specified addresstbyte_be(address)- the 24-bit big-endian value at the specified addressdword_be(address)- the 32-bit big-endian value at the specified addressfloat(address)- the 32-bit IEEE-754 floating point value at the specified addressfloat_be(address)- the 32-bit IEEE-754 big-endian floating point value at the specified addressmbf32(address)- the 32-bit Microsoft Binary Format floating point value at the specified addressmbf32_le(address)- the 32-bit Microsoft Binary Format floating point value (in little-endian form) at the specified addressdouble32(address)- the 32 most significant bits of a 64-bit double at the specified addressdouble32_be(address)- the 32 most significant bits of a 64-bit double (in big-endian form). Note: specified address should be offset for the most significant bits.
Additionally, you can wrap any of the above functions with these functions to modify the behavior:
prev(accessor(address))- the value of the specified address from the previous frameprior(accessor(address))- the last differing value of the specified addressbcd(accessor(address))- converts a BCD-encoded value to decimal for leaderboard and rich presence values.
Examples
| Example | Description |
|---|---|
word(0x1234) == 1000 |
Would be true if the two-bytes at $1234 were E8 03 (0x03E8 = 1000) |
byte(0x4567) > prev(byte(0x4567)) |
Would be true if the byte at $4567 is a larger value than it was in the previous frame |
String matching
Additionally, you can match memory to strings assuming they're encoded using ASCII (7-bit latin characters) or Unicode (16-bit international alphabets).
ascii_string_equals(address, string, length=0x7FFFFFFF, transform=a=>a)unicode_string_equals(address, string, length=0x7FFFFFFF, transform=a=>a)
These matches length characters starting at address. If length is unspecified, the length of the string is used.
transform allows the caller to wrap the generated logic in prev or prior (i.e. transform = a => prev(a)). The expression passed to the transform function may be multiple bytes (i.e. dword(address)) as the comparison is broken into chunks.
Examples
| Example | Returns | Notes |
|---|---|---|
ascii_string_equals(0x1234, "Hi") |
word(0x1234) == 0x6948 | Implicit length of string (2) used |
ascii_string_equals(0x1234, "World", 6) |
dword(0x1234) == 0x6c726f57 && word(0x1238) == 0x0064 | Explicit length includes null terminator |
ascii_string_equals(0x1234, "World", 6, transform= a=>prev(a)) |
prev(dword(0x1234)) == 0x6c726f57 && prev(word(0x1238)) == 0x0064 | transform wraps each chunk |
ascii_string_equals(0x1234, "World", 3) |
tbyte(0x1234) == 0x726f57 | Explicit length only checks part of the string |
unicode_string_equals(0x1234, "Hi") |
dword(0x1234) == 0x00690048 | Unicode characters are 16-bits each |