Search code examples
c++memoryallocation

C++ is there a way to find a memory adress from another application from its value?


How can I find a memory address that I can afterwards change/read by just using that memory address' value using C++? For example like how you can find the memory adress of something by just searching up a value in Cheat Engine.

I searched it on Google for about an hour now but I still couldn't find anything that would be useful for me.

I'm using Windows.

Sorry if I have any spelling mistakes or grammar issues, my main language isn't English.


Solution

  • For example like how you can find the memory adress of something by just searching up a value in Cheat Engine.

    So what you want is to know the memory address at which something can be found in a process. For example, let's say that notepad.exe has the bytes 68 65 6c 6c 6f somewhere in memory and we want to figure out where.

    Basically we want to scan the memory of a process for a given pattern while that process is running.

    There are a few strategies:

    1. we inject a DLL inside notepad.exe and do the scanning from that DLL;
    2. we scan the memory remotely, from another process

    There are various pros and cons for each approach. Your question is focused on the second. I'm going to give a high level view of how one might approach this problem.

    First, each process has its own address space. What this means is that address A in notepad.exe and address A in paint.exe will point to different things, or may not even be valid in both processes. See this page for more details.

    There's also ASLR, which randomizes memory addresses, but that's not such a big problem in this case.

    We need a way to work around this and know which memory ranges are valid in the target process. We can do it with VirtualQueryEx. We can start from 0 and go up to the last valid user mode memory address (0x7FFFFFFF for 32-bit processes, 0x7FFFFFFFFFFF for 64-bit processes). If we have a valid range, we read it with ReadProcessMemory. If it is not valid, we check the next page. If we managed to read it, we can now search for our pattern.

    We can skip the VirtualQueryEx call and blindly try ReadProcessMemory for every possible page, but, especially for 64-bit processes, this can take quite some time. The information returned by VirtualQueryEx can be used to filter out some ranges, based on what we're looking for.

    Note that in order to do this we need to be able to open a handle to the target process with OpenProcess with the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights.

    There are a few problems we may encounter: there's a time frame between our query and our read in which the memory layout of the target process can change. We must be prepared for this. Generally speaking, the read will fail and we can just ignore it. Or the target process may be actively trying to stop us: maybe we can't open a handle to it with the required rights, maybe there's some anti-cheating techniques in place, etc. There's no way of knowing until we try.