1

I am writing a cheat for a game that I play sometimes, there is no anticheat. I have the value and pointers and offsets in Cheat Engine.

I have been using stuff from different places, mostly copy paste and put together (this is my first cheat, lagswitching doesn't count).

When I run it, it gives the Module base address + the pointer which was 0x7ff732b3bc80, then I already know the offsets. But the value it reads is 0 from the address 0x7ff732b3bc80 + the offsets 0xC60, 0x68, 0x58, 0x8, 0x0, 0x88, 0x14. I put these into Cheat Engine and receive the results of the value I am looking for, which is the Y coordinate. I will show a picture of that below. This seems to be from the error 299 that it is not showing up.

Please help, this is not an online game I promise ;). I need to learn somehow.

#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#endif
#endif

#include <windows.h>
#include <memory.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;

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)
    {
        MODULEENTRY32W modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32FirstW(hSnap, &modEntry))
        {
            do
            {
                if (!_wcsicmp(modEntry.szModule, modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32NextW(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return modBaseAddr;
}

DWORD GetProcId()
{
    PROCESSENTRY32   pe32;
    HANDLE         hSnapshot = NULL;
    DWORD pid = 0;

    pe32.dwSize = sizeof( PROCESSENTRY32 );
    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if( Process32First( hSnapshot, &pe32 ) )
    {
        do{
            if( strcmp( pe32.szExeFile, "*****.exe" ) == 0 )
            {
                pid = pe32.th32ProcessID;
                break;
            }
        }while( Process32Next( hSnapshot, &pe32 ) );
    }

    if( hSnapshot != INVALID_HANDLE_VALUE )
        CloseHandle( hSnapshot );
    return pid;
}

uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, 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[1];
    }
    return addr;
}

int main()
{
    DWORD ProcId = GetProcId();
    cout<<ProcId << endl;
    float CoordY = 0;
    uintptr_t ModuleBase = GetModuleBaseAddress(ProcId, L"****[enter image description here][1].exe");
    uintptr_t PointerAddr = ModuleBase + 0x0195BC80;
    cout << "DynamicPointerAddress: " << "0x" << hex << PointerAddr << endl;
    HANDLE hProcess = 0;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcId);
    vector<unsigned int> Offsets = {0xC60, 0x68, 0x58, 0x8, 0x0, 0x88, 0x14};
    uintptr_t CoordAddress = FindDMAAddy(hProcess, PointerAddr, Offsets);
    ReadProcessMemory(hProcess, (BYTE*)CoordAddress, &CoordY, sizeof(float), nullptr);
    cout<<CoordY;
    Sleep(10000);
}

And this is what Cheat Engine says:

Cheat engine pointer

*Edit 1: Value of the hProcess opening is 0xc0.

**Edit 2: Value of ReadProccessMemory() is 0. **Edit 3: Thanks to someone in the comment's I have narrowd the error to Error 299 on ReadProcessMemory. If anyone has any way I could fix this please share. I have tried several online methods. And the program I am reading from is 64 bit.

I am running as admin.

IInspectable
  • 46,945
  • 8
  • 85
  • 181
Programmer
  • 11
  • 2
  • 2
    [`ReadProcessMemory`](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-readprocessmemory) has a return value. The documentation also supplies instructions on what to do when the call fails. – IInspectable Oct 04 '22 at 20:00
  • 12b is the error i got. Here is the list of things that I tested/ 31500 DynamicPointerAddress: 0x7ff732b3bc80 Process Handler Result: 0xa8 ValueAddress: 7ff732b3bf58 ReadMemory result: 0 Error: 12b Value: 0 – Programmer Oct 04 '22 at 20:17
  • 0x12b (299) is [`ERROR_PARTIAL_COPY`](https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-). – IInspectable Oct 04 '22 at 20:23
  • Just checked the open process result for getlasterror and I have 0 – Programmer Oct 04 '22 at 20:23
  • Any idea on how I would fix that? What error I made? – Programmer Oct 04 '22 at 20:25
  • This code is not doing any error handling in `FindDMAAddy()` or `main()`. Does `OpenProcess()` succeed or fail? Does `ReadProcessMemory()`? ALWAYS return value and check error codes. When you say "ReadProccessMemory() is 0", do you mean it is **returning** 0 (ie FALSE), or it is setting the **output variable** to 0? – Remy Lebeau Oct 04 '22 at 21:14
  • Cleared up. It's the ReadProcessMemory. Do you have any Idea how to fix the error 299? And it is returning false. And the output variable was always 0. – Programmer Oct 04 '22 at 21:22
  • Where does `0x0195BC80` come from in `ModuleBase + 0x0195BC80`? Also, per https://stackoverflow.com/questions/4457171/why-does-readprocessmemory-have-lpnumberofbytesread/4457745#4457745: "*`ReadProcessMemory` would return FALSE and `GetLastError` would return `ERROR_PARTIAL_COPY` **when the copy hits a page fault**.*" Which basically means that you are reading from an invalid memory address in the target process. – Remy Lebeau Oct 04 '22 at 21:27
  • Ah, so it could be I am going to the wrong location? Do you know perhaps where I am going that is wrong? I think it might be in the FindDMAAddy() function because the result of that (7ff732b3bf58) Is different than what cheat engine says (2b401ad0de4) – Programmer Oct 04 '22 at 21:28
  • 1
    Well, why don't you start by running your code in a debugger (or at least put some logging in your code) and make sure that every pointer value that `FindDMAAddy()` receives from `ReadProcessMemory()` matches what you see in Cheat Engine on each loop iteration. Does reading from `0x7ff732b3bc80` give you `0x2B400040B00`? Does reading from `0x2B400040B00+0C60` give you `0x2B400041738`? And so on. Where is `0x7ff732b3bf58` coming from? – Remy Lebeau Oct 04 '22 at 21:30
  • Ok, I checked FindDMAAddy() Every time. It went in this order 7ff73d50c8e0 7ff73d50c948 7ff73d50c9a0 7ff73d50c9a8 7ff73d50c9a8 7ff73d50ca30 7ff73d50ca44 So it seems to be adding the offsets Just checked the error every single time on FindDMAAddy(), and it is returning error 299 every single time. Whats wrong with that one? A wrong module base address? – Programmer Oct 04 '22 at 21:35
  • OMIGOSH I GOT IT! – Programmer Oct 04 '22 at 21:41
  • 2
    If you wish to share your answer, there's a dedicated editor and *Post Your Answer* button for that. Please do take the [tour]. – IInspectable Oct 05 '22 at 12:01
  • "*It went in this order 7ff73d50c8e0 7ff73d50c948 7ff73d50c9a0 7ff73d50c9a8 7ff73d50c9a8 7ff73d50ca30 7ff73d50ca44*" - makes sense, since you weren't checking `ReadProcessMemory()` for failure, so it was leaving `addr` unmodified, and so you were simply adding your offsets to the original base address, not following the pointer chain at all. – Remy Lebeau Oct 05 '22 at 16:33

0 Answers0