Question

I read some data from a process (address: 0x58F03C) by using the WINAPI function ReadProcessMemory:

DWORD proc_id;
GetWindowThreadProcessId(hwnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);
int value=0;

while (1)
{
    ReadProcessMemory(hProcess, (LPVOID)0x58F03C, &value, sizeof(value), 0);
    cout << "val: " << value << endl;
}

Since the address changes every time I restart the process I wondered if there is a way to always get the same address? There must be one because I see a lot of "Trainer-Programs" which are able to do that. How do they obtain the right address value to read from / write to?

Currently I obtain it by scanning for a value with the CheatEngine and perform a next scan for changed value.

Thanks.

Was it helpful?

Solution

You are encountering dynamic memory allocation. In the CheatEngine world, these are called 'pointers'.

Consider some data (for example a uint32_t/DWORD) inside memory which was malloc'd. If you find the address of the data, there is no guarantee that the next time you launch the process, the address will be the same. This is because the memory returned by malloc could be based at a different point in memory.

The trick used to defeat dynamic memory allocation is to find a static heap address which can lead you to the address of the value you are interested in. The CheatEngine tutorial shows you how this is done. The same applies for multi-level pointers. At a higher level, this corresponds to dynamically allocated memory which holds a pointer to some other dynamically allocated memory, and so on.

The method used in CheatEngine to get pointers works approximately like this:

  • Set an access hardware breakpoint at the address of the data value you are interested in
  • When code accesses it, the hardware breakpoint will show you what the code looks like

The code will typically look something like this:

mov eax, 0x1234ABCD 
dec dword ptr ds:[eax+0x85]

This might correspond to some code which decrements your HP when hit by an enemy. 0x1234ABCD is the pointer in this case and 0x85 the offset. In C code, this might have happened:

struct some_struct* blah = malloc(...);
...
blah->HP--;

0x1234ABCD would be the address of blah. The HP value lives somewhere inside the block pointed to by blah. The offset into the memory block is 0x85. Then if you were writing a trainer, you would read the DWORD (QWORD if 64 bit) at 0x1234ABCD and add 0x85 to the value. This would give you the address of the HP value.

OTHER TIPS

This will work if the address is in the executable's portion of the data section where preallocated variables live (not suitable for heap and stack)...

Take a look at the "Enumerating All Modules For a Process" example on MSDN.

It uses EnumProcessModules() to get module handles. Those are image base addresses.

You can obtain the image base address for the executable and adjust your address by it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top