Guide:Finding pointers and offsets
|Game(s)||Sly Cooper and the Thievius Raccoonus|
Sly 2: Band of Thieves
Sly 3: Honor Among Thieves
|Time to complete||10-20 mins|
This tutorial will teach you how to find pointers to structs and use offsets to access values stored within those structs. Basically every value the game uses is stored in a struct somewhere in memory, so if you can find a global pointer to a struct, and then figure out the offset to access a value in that struct, you can access that value in any map without having to scan for it. The steps below should work for all three games, though keep in mind that Sly 1 structs are organized slightly differently than Sly 2 and Sly 3 structs.
How to find the pointer/offset to a value in any struct[edit | edit source]
- Find the address of the value within the struct you want to find the pointer for.
- In this tutorial we will use Sly's X-position while in the Paris map in Sly 2. By doing changed value scans in Cheat Engine, we know the address of Sly's X position is is 0xFB3710.
- We don't need to the 0x20 at the front of the address because the 0x20000000 is the emulator base address, and pointers are automatically read relative to the base address.
- Set a read breakpoint on that address in the PCSX2 debugger.
- In PCSX2, click Debug > Open Debug Window.
- Once it opens, click Set Breakpoint.
- In the Address box, type in the address (for this example I use 0xFB3710 which is Sly's X position)
- Check the box for Read, but not Write or Execute.
- Click OK.
- Do something to make the game read the value.
- For this example, all you have to do is play as Sly, since the game constantly reads Sly's position while he's active.
- When your breakpoint hits the game will freeze and the debugger will show you which instruction it broke on.
- In the Debugger, look at the assembly code instruction that reads the value, and see what address is in the register it used.
- For example, the instruction will probably be something like
sw s0, 0x30(s1). The register in parenthesis (in this case, s1) will contain the base address of the struct, and the number before the parenthesis (in this case, 0x30) is the offset.
- So, if the s0 register contains the value FB36E0, then the base address of the struct is 0xFB36E0, and Sly's X-Position is at offset 0x30 from that address.
- For example, the instruction will probably be something like
- Do a 4-byte scan in Cheat Engine to find an address which stores a pointer to that base address.
- Take the value from the register in Step 4, and do a 4-byte / Exact Value scan in Cheat Engine for that value (remember to check the box that says Hex).
- All the resulting addresses are pointers to that struct
- If you have too many results, load another map, and repeat the process until you narrow it down (however, this will only work if one of the pointers you found is a global value).
A struct can store pointers to other structs[edit | edit source]
If you followed the above steps to find the pointer to the struct that stores Sly's X position, you might think you've found the pointer to the Sly Entity struct. However, since this is Sly 2, what you have actually found is the pointer to Sly's Transform Component struct.
Each entity in the game has a Transform Component, which is referenced by a pointer inside it's Entity struct. This means the pointer you found will not work to find Sly's X position on every map. But, if you find the global pointer to the Sly Entity struct that works on every map, you can always find the Transform Component by using its offset from that pointer, then offset again by 0x30 from that pointer to find the X position.
To find the actual Sly Entity Struct pointer[edit | edit source]
Option A[edit | edit source]
Repeat steps 2-5, but in Step 2, use the address of one of the pointers you got in Step 5. You should probably use the address that is closest to the base address of the Transform Component. That way, you will find the base address of the Sly Entity, and the offset of the pointer Transform struct inside the Sly Entity struct.
Option B[edit | edit source]
Use the tutorial below to find the base address of the Sly entity struct using the FK$X string. Then use Cheat Engine's memory viewer to find the pointer to the Transform Component in memory nearby. Now use a calculator to subtract the address of the Transform Component pointer from the Sly Entity base address, and that will be the offset of the Transform Component for every entity in the game.
Once you know the offset of the Transform Component from the entity struct, and the offset of the X coordinate from the transform component, you can find the coordinates for every entity in the game without having to repeat the steps above every single time.
How to find the base address for a known entities (Sly 2 and Sly 3)[edit | edit source]
This will work for Sly 2 and Sly 3 entities like Sly, Bentley, Neyla, guards, antennas, cars, trees, bombs, bullets, music box, etc. since Sly 2 and 3 have a method for easily finding pointers to these structs.
- Find the FK$X struct for the entity you want
- In CE, do a String Search for FK$Xentity_name, where entity_name is the name of the entity. In this case we will do FK$Xz_antenna in Sly 2 Ep 1, Paris.
- If you do not know the entity name, you can guess, try to search for just part of it (eg. just antenna), or search for just FK$X and look through all of them until you find it.
- Once you found the FK$X string, open that in the Memory Viewer, and scroll up to see the entire FK$X struct.
- Right click in the memory viewer, and change the display mode to 4-byte Hex.
- It should look like this:
- Use the entity list pointer to find the array of pointers to each instance of that entity in the world
- Ignoring the zeroes at the start of the line, the second value in the FK$X struct is a pointer to the entity pool for that entity
- The third value value in the FK$X struct is how many of that entity the game instantiated when the level was loaded
- Copy the value of the pool pointer, press Ctrl+G, paste it, and press OK to go to that address in the memory viewer.
- I am using the emuprm script so these screenshots do not include the 0x20000000 base address. If you don't have the script, you will have to add 0x20000000.
- You are now looking at the proxy pool for that entity, which is an array of pointers to instances of that entity in the current map.
- These are pointers to Entity structs. Each 4-byte value is a pointer to an instance of that entity.
- There will be a number of pointers equal to the pool size you saw in the FK$X struct. For the antennas, there are 4.
- You can use the Dissect Data Structures tool in Cheat Engine to easily view/edit the values stored on the struct.
Once you know the base address for an entity, you can add the offset for a known element to get that element for that entity. For example, if you followed the steps in the first tutorial to find the offset for the Transform Component for an entity, you can add that offset to the base address for any entity to get the pointer to its Transform Component. Then you can add the offsets 0x30, 0x34, and 0x38 to that pointer to get the entity's X, Y, and Z coordinates.