Pointers
Make sure to understand value types or read this first: Value types
Pointers are integers who's size is the base word size of the process and store an address in that process. That is in a 16 bit process a pointer is a WORD (16 bit), in a 32 bit process a pointer is a DWORD (32 bit), and in a 64 but process a pointer is a QWORD (64 bit).
- 16 bit
- WORD : int16/short
- 32 bit
- WORD : int32/int
- 64 bit
- WORD : int64/long
In programs and programming simply using integers, floating point values, and strings really isn't feasible with complex objects. So the concept of an object in memory was seen as a must. This is where pointers come in. They simply point to an object in memory, hence the name.
Technically strings are pointers to character arrays, that end with a null byte (0x0). In the ANSI C there is no string type just character arrays.
Objects in memory
Now let's say we have some code that declares a player object and its setup like this:
- Player : object
- Name : string
- Health : integer
- Coins : integer
- Coordinates : object
- X : float
- Z : float
- Y : float
- Inventory : array - Array of item objects, having the item and item count.
So in a 32 bit process in memory the player object could get assembled some thing like this:
- Process.exe+123ABC : pointer : DWORD - Player base.
- [Process.exe+123ABC]+10 : pointer : DWORD - Pointer to where the Name string is stored in memory.
- [[Process.exe+123ABC]+10]+4 : string : 256 bytes - The Name value, as a null (0x0) ended string.
- [Process.exe+123ABC]+14 : integer : DWORD - Health value.
- [Process.exe+123ABC]+18 : integer : DWORD - Coins value.
- [Process.exe+123ABC]+1C : pointer : DWORD - Pointer to where the Coordinates object is stored in memory.
- [[Process.exe+123ABC]+20]+10 : float : DWORD - X coordinate.
- [[Process.exe+123ABC]+20]+14 : float : DWORD - Z coordinate.
- [[Process.exe+123ABC]+20]+18 : float : DWORD - Y coordinate.
- [Process.exe+123ABC]+24 : pointer : DWORD - Pointer to where the Inventory array starts in memory.
- [[Process.exe+123ABC]+24]+XX*4 : pointer : DWORD - Pointer to where the inventory array item number XX is stored in memory.
- [[[Process.exe+123ABC]+24]+XX*4]+4 : integer : DWORD - The inventory item Count value.
- [[[Process.exe+123ABC]+24]+XX*4]+8 : pointer : DWORD - Pointer to where item object is stored in memory.
- [[Process.exe+123ABC]+24]+XX*4 : pointer : DWORD - Pointer to where the inventory array item number XX is stored in memory.
- [Process.exe+123ABC]+10 : pointer : DWORD - Pointer to where the Name string is stored in memory.
And in a 64 bit process in memory the player object could get assembled some thing like this:
- Process.exe+123ABC : pointer : QWORD - Player base.
- [Process.exe+123ABC]+10 : pointer : QWORD - Pointer to where the Name string is stored in memory.
- [[Process.exe+123ABC]+10]+8 : string : 256 bytes - The Name value, as a null (0x0) ended string.
- [Process.exe+123ABC]+18 : integer : DWORD - Health value.
- [Process.exe+123ABC]+1C : integer : DWORD - Coins value.
- [Process.exe+123ABC]+20 : pointer : QWORD - Pointer to where the Coordinates object is stored in memory.
- [[Process.exe+123ABC]+20]+10 : float : DWORD - X coordinate.
- [[Process.exe+123ABC]+20]+14 : float : DWORD - Z coordinate.
- [[Process.exe+123ABC]+20]+18 : float : DWORD - Y coordinate.
- [Process.exe+123ABC]+28 : pointer : QWORD - Pointer to where the Inventory array starts in memory.
- [[Process.exe+123ABC]+28]+XX*8 : pointer : QWORD - Pointer to where the inventory array item number XX is stored in memory.
- [[[Process.exe+123ABC]+28]+XX*8]+4 : integer : DWORD - The inventory item Count value.
- [[[Process.exe+123ABC]+28]+XX*8]+8 : pointer : DWORD - Pointer to where item object is stored in memory.
- [[Process.exe+123ABC]+28]+XX*8 : pointer : QWORD - Pointer to where the inventory array item number XX is stored in memory.
- [Process.exe+123ABC]+10 : pointer : QWORD - Pointer to where the Name string is stored in memory.
But if we had an Actor object that held all the values, and then a Player object that inherits from Actor, a Player object could get assembled some thing like this:
- Process.exe+123ABC : pointer : DWORD - Player base.
- [Process.exe+123ABC]+4 : pointer : DWORD - Actor base.
- [[Process.exe+123ABC]+4]+10 : pointer : DWORD - Pointer to where the Name string is stored in memory.
- [[[Process.exe+123ABC]+4]+10]+4 : string : 256 bytes - The Name value, as a null (0x0) ended string.
- [[Process.exe+123ABC]+4]+14 : integer : DWORD - Health value.
- [[Process.exe+123ABC]+4]+18 : integer : DWORD - Coins value.
- ...
- [[Process.exe+123ABC]+4]+10 : pointer : DWORD - Pointer to where the Name string is stored in memory.
- [Process.exe+123ABC]+4 : pointer : DWORD - Actor base.
And the more complex the object structure the more complex the pointer structure.
Example of multi-level pointers
Check out step 8 of the Cheat Engine Tutorial for an example of multi-level pointers.