I'm having some trouble with trying to calculate an memory address with a offset.
NOTE: I can do 32 bit, but I need to use 64-bit addresses.
The example I have is this address: 0x000002586F08CE30 with offset 0x88. When I get this add it has the address of : 0x2586F08CEB8 when it should be : 0x25825C4C880
I have tried this:
void aVoid()
{
DWORD64* add = (DWORD64*)0x000002586F08CE30;
cout << add << endl;
DWORD64* off = (DWORD64*)0x88;
cout << off << endl;
DWORD64* BaseTimeAddress = (DWORD64*)((char*)add (DWORD64)off);
cout << BaseTimeAddress << endl; // Gets 000002586F08CEB8
}
Where I got 0x25825C4C880 at : (https://i.stack.imgur.com/5K4eP.png)
FULL CODE
#include <iostream>
#include <windows.h>
#include <string>
#include <vector>
#include <tchar.h>
#include <stdlib.h>
#include <tlhelp32.h>
`
using namespace std;
DWORD GetModuleBaseAddress(TCHAR* lpszModuleName, DWORD pID) {
DWORD dwModuleBaseAddress = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID); // make snapshot of all modules within process
MODULEENTRY32 ModuleEntry32 = { 0 };
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32)) //store first Module in ModuleEntry32
{
do {
if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) // if Found Module matches Module we look for -> done!
{
dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32)); // go through Module entries in Snapshot and store in ModuleEntry32
}
CloseHandle(hSnapshot);
return dwModuleBaseAddress;
}
DWORD GetPointerAddress(HWND hwnd, DWORD gameBaseAddr, DWORD address, vector<DWORD> offsets)
{
DWORD pID = NULL; // Game process ID
GetWindowThreadProcessId(hwnd, &pID);
HANDLE phandle = NULL;
phandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (phandle == INVALID_HANDLE_VALUE || phandle == NULL);
DWORD offset_null = NULL;
ReadProcessMemory(phandle, (LPVOID*)(gameBaseAddr address), &offset_null, sizeof(offset_null), 0);
DWORD pointeraddress = offset_null; // the address we need
for (int i = 0; i < offsets.size() - 1; i ) // we dont want to change the last offset value so we do -1
{
ReadProcessMemory(phandle, (LPVOID*)(pointeraddress offsets.at(i)), &pointeraddress, sizeof(pointeraddress), 0);
//cout << "ADD: " << &pointeraddress << endl;
}
return pointeraddress = offsets.at(offsets.size() - 1); // adding the last offset
}
#include <Psapi.h>
DWORD_PTR GetProcessBaseAddress(DWORD processID)
{
DWORD_PTR baseAddress = 0;
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
HMODULE* moduleArray;
LPBYTE moduleArrayBytes;
DWORD bytesRequired;
if (processHandle)
{
if (EnumProcessModules(processHandle, NULL, 0, &bytesRequired))
{
if (bytesRequired)
{
moduleArrayBytes = (LPBYTE)LocalAlloc(LPTR, bytesRequired);
if (moduleArrayBytes)
{
unsigned int moduleCount;
moduleCount = bytesRequired / sizeof(HMODULE);
moduleArray = (HMODULE*)moduleArrayBytes;
if (EnumProcessModules(processHandle, moduleArray, bytesRequired, &bytesRequired))
{
baseAddress = (DWORD_PTR)moduleArray[0];
}
LocalFree(moduleArrayBytes);
}
}
}
CloseHandle(processHandle);
}
return baseAddress;
}
int main() {
//HWND hWnd = FindWindowA(NULL, "Halo Wars: Definitive Edition");
//char gameModule1[] = "xgameFinal.exe";
DWORD64 address = 0x00000258722B0AB0;
float nVal = 2000;
HWND hWnd = FindWindowA(0, "Halo Wars: Definitive Edition");
if (hWnd == 0) {
cerr << "Could not find window." << endl;
}
else {
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (!hProc) {
cerr << "Cannot open process." << endl;
}
else {
DWORD64* add = (DWORD64*)0x000002586F08CE30;
cout << add << endl;
DWORD64* off = (DWORD64*)0x88;
cout << off << endl;
DWORD64* BaseTimeAddress = (DWORD64*)((char*)add (DWORD64)off);
cout << BaseTimeAddress << endl;
DWORD64* com = (DWORD64*)add;
cout << com << endl;
//cout << &add << endl;
DWORD_PTR baseAddr2 = GetProcessBaseAddress(PID);
cout << "base" << &baseAddr2 << endl;
cout << "base"<<baseAddr2 << endl;
cout << "base" <<hex<< baseAddr2 << endl;
DWORD64 offset_null = NULL;
DWORD64 add2 = ReadProcessMemory(hWnd, (LPVOID*)(baseAddr2 0x014FA250), &offset_null, sizeof(offset_null), 0);
cout << &add2 << endl;
cout << &offset_null << endl;
ReadProcessMemory(hWnd, (LPVOID*)(baseAddr2 0x014FA250 0x88 0x8 0x110), &offset_null, sizeof(offset_null), 0);
cout << &offset_null << endl;
cout << "END";
char gameModule1[] = "xgameFinal.exe";
DWORD_PTR baseAddr1 = GetProcessBaseAddress(PID);
cout << hex << baseAddr1 << endl;
cout << &baseAddr1 << endl;
DWORD64 baseAddr = GetModuleBaseAddress(_T(gameModule1), PID);
/*
char gameModule1[] = "ac_client.exe";
DWORD baseAddr = GetModuleBaseAddress(_T(gameModule1), procID);
DWORD pointsAddr = 0x0018AC00;
vector<DWORD> pointsOffesets = { 0x11C };
//cout << std::hex << pointsAddr << endl;
DWORD pointsPtrAddr = GetPointerAddress(hWnd, baseAddr, pointsAddr, pointsOffesets);
//010FF974
//cout << pointsPtrAddr << endl << &pointsPtrAddr << endl;
int val = 1;
ReadProcessMemory(handle, (LPVOID*)(pointsPtrAddr), &val, sizeof(val), 0);
cout << "Value: " << val << endl;
cout << "Pointer Address: " << std::hex << pointsPtrAddr << endl;
cout << "WORKS";
//"xgameFinal.exe" 016208B0
*/
/* DWORD64* BaseAddress = (DWORD64*)GetModuleHandle(NULL);
DWORD64* address = (DWORD64*)((char*)BaseAddress 0x014FA250);
address = (DWORD64*)((char*)*address 0x88 0x8 0x110);
float currentTime = *(float*)address;
cout << currentTime;
cout << "END";
*/
ReadProcessMemory(hProc, (LPVOID)address, &nVal, (DWORD64)sizeof(nVal), NULL);
cout << nVal;
CloseHandle(hProc);
cin.get();
}
}
return 0;
}
`
CodePudding user response:
DWORD64* BaseTimeAddress = (DWORD64*)((char*)add (DWORD64)off);
By doing (char*)add
, you make the
operator add an offset in char. Chars are 1-byte. As such,
0x000002586F08CE30 0x88 = 0x2586F08CEB8
is correct. The other address you specify is wildly off. Where did you get it from?
In the image you link, there is a type field. You probably need to change your line to typecast to this type:
DWORD64* BaseTimeAddress = (DWORD64*)((float*)add (DWORD64)off);
This means: Offset add
, by off
number of float
s. This type of low-level modifications of pointers, though, can easily lead to undefined behaviour in C , unless you are very careful. You need to understand reinterpret_cast
s and their limitations.
CodePudding user response:
I figured it out! I do want to give a shoutout to @Jeffrey and @RaymondChen for their posts that helped me think better about this problem.
So real quick I'll post the code below and after that explain it more:
void code()
{
/*1*/ DWORD64* test6 = (DWORD64*)0x2586F08CE30; cout << test6 << endl;
/*2*/ DWORD64* test7 = (DWORD64*)0x88; cout << test7 << endl;
/*3*/ DWORD64* test8;
/*4*/ DWORD64* test9;
/*5*/ ReadProcessMemory(hProc, (LPVOID*)((DWORD64)test6 (DWORD64)test7), &test8, sizeof(test8), 0);
/*6*/ ReadProcessMemory(hProc, (LPVOID*)((DWORD64)test8 (DWORD64)0x8), &test9, sizeof(test9), 0);
/*7*/ DWORD64* test2 = (DWORD64*)0x110;
/*8*/ //cout << test2 << endl;
/*9*/ DWORD64* test3 = (DWORD64*)((char*)test9 (DWORD64)test2);
/*10*/ //cout << test3 << endl;
/*11*/ float currentTime = 0;
/*12*/ ReadProcessMemory(hProc, (LPVOID*)test3, ¤tTime, sizeof(currentTime), 0);
/*13*/ //cout << test3 << endl;
/*14*/ cout << currentTime << endl;
}
Here is the image from cheat engine that has all the data: https://i.stack.imgur.com/5K4eP.png
So I started with 0x2586F08CE30 which I get from cheat engine right now, but "xgameFinal.exe" 014FA250 = 0x2586F08CE30
So next I need to take that address and combine it with offset 0x88, at line 5 I do that.
Next is to take that address from test8 and combine offset 0x8. (@ line 6)
Next is the last offset (0x110), this is where @RaymondChen comment helped me out.
The screen shot says [2586F08CE30 88] but you calculated 2586F08CE30 88. – Raymond Chen
So at line 9 is where I get the final address and then also the value.