0

First of all, what I am trying to do is changing a value in the memory of a game. In order to write to that variable I need to add the following pointer and offsets because then I always get to an address that works:

baseAddr + offset1 + offset2 + offset3 = myDesiredAddr

Now, this is what I have tried to do...

ReadProcessMemory(
hProc, (LPVOID)(BaseAddr + offset1), &myDesiredAddr, sizeof(myDesiredAddr), 0
);
ReadProcessMemory(
hProc, (LPVOID)(myDesiredAddr + offset2), &myDesiredAddr, sizeof(myDesiredAddr), 0
);
ReadProcessMemory(
hProc, (LPVOID)(myDesiredAddr + offset3), &myDesiredAddr, sizeof(myDesiredAddr), 0
);

I've tired to WriteProcessMemory on the final address that I got but it does not read and write successfully. Any advice will be helpful.

Jose Luis
  • 3,307
  • 3
  • 36
  • 53
Andreas DM
  • 10,685
  • 6
  • 35
  • 62
  • `ReadProcessMemory` provides both a return value and a way to get how much data is read, both of which you ignore. Add some error checking. – Retired Ninja Oct 26 '14 at 05:44
  • No please, I do check if it succeeds. This is only quick example. – Andreas DM Oct 26 '14 at 05:54
  • 1
    It's hard to give a read answer if you don't post the real code. If you're getting an error, what is it? Extremely important information to have. – Retired Ninja Oct 26 '14 at 05:55
  • I want to know if im walking in right direction when adding the offsets, or if its wrong thing to do... – Andreas DM Oct 26 '14 at 06:54
  • I guess that the final address (`myDesiredAddr + offset3`) is not a valid address within `hProc`. It looks to me that you're trying to follow pointers of/to objects of that process to a final memory location. I doubt if this will work since the memory of the other process may change while you're reading thus rendering your final address invalid. – Lukas Thomsen Oct 26 '14 at 08:10
  • You're right @LukasThomsen that's what I'm trying to do. Ok thanks, your comment is useful. – Andreas DM Oct 26 '14 at 15:20

2 Answers2

3

You could do something like this:

unsigned long offset1 =  /* your value              */
unsigned long offset2 =  /* your value              */
unsigned long offset3 =  /* your value              */
unsigned long BaseAddr = /* your value              */
unsigned long Pointer;   /* to hold the final value */
unsigned long temp;      /* hold the temp values    */
unsigned value =         /* value to write          */

The above shows your declarations. I presume you check if the read and write functions return successfully, otherwise I would suggest you do so.

ReadProcessMemory(
hProc, reinterpret_cast<LPVOID>(BaseAddr), &temp, sizeof(temp), 0);
Pointer = temp + offset1;

ReadProcessMemory(
hProc, reinterpret_cast<LPVOID>(Pointer), &temp, sizeof(temp), 0);
Pointer = temp + offset2;

ReadProcessMemory(
hProc, reinterpret_cast<LPVOID>(Pointer), &temp, sizeof(temp), 0);
Pointer = temp + offset3;

/* Now Pointer stores the final address and *
 * you can write to it                      */
WriteProcessMemory(
hProc, reinterpret_cast<unsigned*>(Pointer), &value, sizeof(value), 0);

By adding the memory addresses and offsets and storing the value in Pointer, you can continue to read from Pointer and store the temporary addresses in a temp variable until you get to the final address that you want.

I suggest you do this in a loop for efficiency and neater code.

0

You write a function which walks the multilevel pointer, each step it de-references the pointer and adds the relative offset.

For this example I will use a simple assault cube cheat I've made

FindDMAAddy function (Find Dynamic Memory Allocation Address):

uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < offsets.size(); ++i)
    {
        ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}

The main code:

    uintptr_t moduleBase = GetModuleBaseAddress(procId, L"ac_client.exe");

    //Get Handle to Process
    HANDLE hProcess = 0;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);

    //Resolve base address of the pointer chain
    uintptr_t dynamicPtrBaseAddr = moduleBase + 0x10f4f4;

    std::cout << "DynamicPtrBaseAddr = " << "0x" << std::hex << dynamicPtrBaseAddr << std::endl;

    //Resolve our ammo pointer chain
    std::vector<unsigned int> ammoOffsets = { 0x374, 0x14, 0x0 };
    uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, ammoOffsets);

    std::cout << "ammoAddr = " << "0x" << std::hex << ammoAddr << std::endl;

You can find a more complete version of my answer here

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59