I'm using WinAPI's ReadProcessMemory()
to read some "hidden" information from a game.
I've used Cheat Engine to find out the static pointers, but I don't know how to read from them.
Cheat Engine gives me a pointer to something like this: "mygame.exe"+1C50
I'm really new to WinAPI, how do I convert "mygame.exe"+1C50
to an address that I can read with ReadProcessMemory()
?
EDIT: I tried simplifying the problem, but I guess I should've just given the full code in the first place. So I'm working with static addresses and multi level pointers here, but I'm still stuck with getting the base address or w/e.
Here's the full code and a picture of my cheat engine address:
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
using namespace std;
HANDLE GetProcessHandle(const char *procName);
int main()
{
const char *procName = "prism3d.exe";
HANDLE hProc = GetProcessHandle(procName);
if (hProc) {
/* This works if I use the dynamic address (f.e. 0x02C2C4DC),
but it changes every time I restart the game.
I need to use the static address (prism3d.exe+A1C) to get
the dynamic address for my "nuke".
*/
float nuke;
ReadProcessMemory(hProc, (void*)0x02C2C4DC, &nuke, 4, 0);
cout << nuke;
}
CloseHandle(hProc);
return 0;
}
HANDLE GetProcessHandle(const char *procName)
{
HANDLE hProc = NULL;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(hSnapshot, &pe32)) {
do {
if (!strcmp(pe32.szExeFile, procName)) {
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
break;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return hProc;
}
Edit 2:
Here's how I tried reading the value of my nuke, but it gives me random numbers, different every time I restart the game (sometimes it's 0
, sometimes 324324324
, etc...):
if (hProc) [
DWORD baseAddr = (DWORD)GetModuleHandle(procName) + 0xA1C50; // also tried this with GetModuleHandle(NULL)
DWORD mainAddr;
ReadProcessMemory(hProc, (void*)(baseAddr + 0x111C), &mainAddr, 4, 0);
// Nuke
float nuke;
DWORD nukeAddr;
ReadProcessMemory(hProc, (void*)(mainAddr + 0x48), &nukeAddr, 4, 0);
ReadProcessMemory(hProc, (void*)nukeAddr, &nuke, 4, 0);
cout << nuke;
}
The base offset is generally the start of the module in memory, you can get this with GetModuleHandle
(the address this returns is the start of the PE in memory). I say generally because some conventions define the base relative to the start of the code section, which you then need to read from the PE.
you can do something such as the following:
UINT_PTR addr = (UINT_PTR)GetModuleHandle("game.dll") + 0x1C50;
ReadProcessMemory(hProc,(void*)addr,pBuffer,nSize,&BytesRead);
The above only works if you are running in the address space of the process you are targeting (via dll injection), to do this via a remote process (as your example shows) you need to enumerate to process modules to get a valid handle to the module you are interested in.
MSDN has an example of that here, refactoring it a bit, you can create a function that checks against the name and return the HMODULE
if it matches, casting this will give you the module base address.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With