Walkirio
Walkirio

Reputation: 11

C++ Process Reading pointers

i'm trying to read the memory of a game called: "Prison Architect", but i always have this value: "Money :-858993460" I lost 2 days without have found any solutions. I hope you can help me.


Pointer Info:

  1. BaseAddress: "prison architect.exe"+00075140
  2. Pointer1: 300

  3. Pointer2: 88

  4. Pointer3: 26c

  5. Pointer4: 70
  6. Pointer5: 328

int FindPointer(int offset, HANDLE pHandle, int baseaddr, int offsets[])
{
    int Address = baseaddr;
    int total = offset;
    for (int i = 0; i < total; i++) //Loop trough the offsets
    {
        ReadProcessMemory(pHandle, (LPCVOID)Address, &Address, 4, NULL);
        Address += offsets[i];
    }
    return Address;
}

int main()
{

    int value = 0; // This will store our value. In my case, its an integer, which is the timer
    DWORD pid; //This will store our Process ID, used to read/write into the memory
    HWND hwnd; //Finally a handle to our window

    hwnd = FindWindow(NULL, L"Prison Architect"); //Finds the Window
    if (!hwnd) //If none, display an error
    {
        cout << "Window not found!\n";
        cin.get();
    }

    GetWindowThreadProcessId(hwnd, &pid); //Get the process id and place it in pid
    HANDLE phandle = OpenProcess(PROCESS_VM_READ, 0, pid); //Get permission to read
    if (!phandle) //Once again, if it fails, tell us
    {
        cout << "Could not get handle!\n";
        cin.get();
    }

    int baseAddress = 0x00197BE8;
    int offsets[] = { 0x300, 0x88, 0x26c, 0x70, 0x328 };

    while (1) {

        int moneyRead = FindPointer(5, phandle, baseAddress, offsets); //number of offsets, HANDLE, base address, offsets
        //reading
        int money;
        ReadProcessMemory(phandle, (LPVOID)moneyRead, &money, sizeof(money), 0);
        cout << "\nMoney :" << money;

        Sleep(3000);
    }
    return 0;
}

Upvotes: 0

Views: 1366

Answers (1)

GuidedHacking
GuidedHacking

Reputation: 3923

int baseAddress = 0x00197BE8;

You're using a hard coded address, which is bad practice because it may only work for this one instance of running the game process. When you re-open the game it probably will change.

The pointer must begin with an address that has a relative offset from a module. You then add the relative offset to the address of the module which you have calculated at run time. This will make it so your final address that is calculated always works correctly, regardless of ASLR.

You can use this function to find the base address of a module

uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
    uintptr_t modBaseAddr = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32First(hSnap, &modEntry))
        {
            do
            {
                if (!_wcsicmp(modEntry.szModule, modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return modBaseAddr;
}

Add the relative offset to the return value and use this as the base address of the pointer you pass into your FindPointer() function.

Upvotes: 1

Related Questions