2

I'm trying to read a value from a pointer address + offset and not getting the correct result.

I have the following (relevant pieces) of code:

uintptr_t moduleBase = GetModuleBaseAddress(procId, L"ProgramImReading.exe");
uintptr_t pObjectManager = moduleBase + 0x237CB28;
std::vector<unsigned int> countOffset = { 0x20 };

uintptr_t totalObjects = FindDMAAddy(hProcess, pObjectManager, countOffset);
std::cout << "Current objects = " << totalObjects << std::endl;

FindDMAAddy:

    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;
}

For some reason this will not work. I can confirm the addresses are correct by opening cheat engine and entering GameAdress + Pointer, then setting the offset + 20 and getting the correct value.

When i run the code above I get a long random value "2596411228208"

I can also find the current dynamic address the pointer is pointing to and read directly from that address, but when I try to read from the pointer + offset It does not work right.

zero298
  • 25,467
  • 10
  • 75
  • 100
Tman
  • 389
  • 1
  • 14
  • What kind of object do you hope to find at the address? An `int`, a `double`, a `...`? – R Sahu Jan 08 '20 at 21:51
  • @RSahu int, generally between the values of 30-200 – Tman Jan 08 '20 at 21:53
  • Are you looking for a `20` or a `0x20` byte offset? You may have gotten them mixed up. The question says `20` but the code says `0x20`. – François Andrieux Jan 08 '20 at 21:55
  • @FrançoisAndrieux 0x20 offset, thanks for catching that I should have been more clear in the title. – Tman Jan 08 '20 at 21:56
  • @Tman `addr += offsets[i];` -- What are you expecting this to do? Advance `addr` by only `offsets[i]` bytes? If so, it will not do that. – PaulMcKenzie Jan 08 '20 at 21:57
  • Please isolate the actually problematic part into a [mcve]. Also, where exactly do you get that value you quote? – Ulrich Eckhardt Jan 08 '20 at 22:01
  • @UlrichEckhardt i scanned the memory until I found the pointer and found the offset in reclass, here is an example of the address + offset working properly in cheat engine: https://prnt.sc/ql15ws – Tman Jan 08 '20 at 22:04
  • 2
    2596411228208 in decimal is 0x25C862B4030, which is the number in your screenshot. Is this not what you want? – molbdnilo Jan 08 '20 at 22:04
  • @molbdnilo Correct, and this code I am using has worked on other programs in the past, but it is not working now for some reason. It should be simple: get the base .exe address + pointer, add the offset 0x20, but for some reason it does not work - or i should say, it does not return the expected 4 byte value – Tman Jan 08 '20 at 22:07
  • @molbdnilo That is indeed what I want, but I cannot hard code that number, the code needs to do that dynamically, because that 25C862B4030 is the result of a pointer, which will change next time I restart the program, so the code needs to do it on the fly. – Tman Jan 08 '20 at 22:10
  • 1
    The "long random number" is the number you're looking for, but written in base 10 rather than 16. – molbdnilo Jan 08 '20 at 22:11
  • 1
    Yup, one more ReadProcessMemory() call, now for an *int*. – Hans Passant Jan 08 '20 at 22:15
  • Got it, thanks guys, majorly spaced out and forgot I need to actually READ from that location /facepalm Really appreciate the help! https://prnt.sc/ql1api – Tman Jan 08 '20 at 22:19
  • 1
    I have rolled back your edit because it removes almost all of the important bits of your question. – zero298 Jan 08 '20 at 22:36
  • A link to some external code dump is not a replacement for putting a [mcve] inline in your question. Glad you found your mistake. I still wonder if you'd have found it yourself if you had followed proper procedure. – Ulrich Eckhardt Jan 09 '20 at 13:20
  • Your code is incomplete; in particular, it seems to be missing a `main()` function and at least one `#include`. Please [edit] your code so it's a [mcve] of your problem (including any necessary inputs, but preferably not needing any), then we can try to reproduce and solve it. You should also read [ask]. – Toby Speight Jan 09 '20 at 17:16

3 Answers3

3

I'm a bit confused with your code, but I think you are talking about this:

When you have a pointer to an int, that is 4 bytes length, and you increase the pointer by 1, you are actually adding 4 to the pointer, because you need to go 4 bytes forward to get the next int. Like this:

uint32_t* pointer = 124;
++pointer; //128

or with a short, that is 2 bytes long:

uint16_t* pointer = 124;
++pointer; //126

For add bytes to an uint32_t pointer, you have to convert to an uint8_t pointer first and cast back to uint32_t pointer.

uint32_t* pointer = 124;
uint32_t offset = 0x20;

pointer = (uint32_t*)((uint8_t*)pointer + offset);
Moonslate
  • 51
  • 5
0

Since you expect to find an int at the given address, you need to use:

for (unsigned int i = 0; i < offsets.size(); ++i)
{
    int var;
    ReadProcessMemory(hProc, (BYTE*)addr, &var, sizeof(var), 0);
    addr += offsets[i];
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

FindDMAAddy returns the final address of the pointer chain. Your code expects it to contain the value in that address, which it does not. You need to use ReadProcessMemory to read it.

The correct code is:

uintptr_t moduleBase = GetModuleBaseAddress(procId, L"ProgramImReading.exe");
uintptr_t pObjectManager = moduleBase + 0x237CB28;
std::vector<unsigned int> countOffset = { 0x20 };

uintptr_t addr = FindDMAAddy(hProcess, pObjectManager, countOffset);

int totalObjects = 0;

ReadProcessMemory(hProc, (BYTE*)addr, &totalObjects, sizeof(totalObjects), 0);

std::cout << "Current objects = " << totalObjects << std::endl;
GuidedHacking
  • 3,628
  • 1
  • 9
  • 59