QuestionHelpBlocking with Offset to access Memory

Posts 1–2 of 2 · Page 1 of 1
Blocking with Offset to access Memory
Hello everyone,
I'm a new guy into the domain of games hacking but I'm very exciting to do some basics hacks in the first time. But, of course, I'm struggling with probably a small issue. I would like to ask your help
So here I'm, to practice I try to hack The Witcher 3 which is for me a game with a ton of possibilities.
I already find my base address for the health and I try to access this address into C++ but I have some problems to do it.

1) Here is my base address with his offsets where the value is a float.



2) Here is my function to get the value of the address.


DWORD GetProcessThreadID(HANDLE Process)
{
THREADENTRY32 entry;
entry.dwSize = sizeof(THREADENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

if (Thread32First(snapshot, &entry) == TRUE)
{
DWORD PID = GetProcessId(Process);
while (Thread32Next(snapshot, &entry) == TRUE)
{
if (entry.th32OwnerProcessID == PID)
{
CloseHandle(snapshot);
return entry.th32ThreadID;
}
}
}
CloseHandle(snapshot);
return NULL;
}


DWORD LoopToAddress(int pointerLevel, HANDLE handle, DWORD Offset[], DWORD BaseAddress)
{
DWORD pointer = BaseAddress;
DWORD nextP;
DWORD endAddress;
for (int i = 0; i < pointerLevel; i++)
{
if (i == 0)
{
ReadProcessMemory(handle, (LPCVOID)pointer, &nextP, sizeof(nextP), NULL);
}
endAddress = nextP + Offset[i];
ReadProcessMemory(handle, (LPCVOID)endAddress, &nextP, sizeof(nextP), NULL);
}
return endAddress;


if (GetAsyncKeyState(VK_F1))
{
float valueToTest;
DWORD OffSet[] = { 0xCC4,0x810,0x48 };
DWORD ProcessId = GetProcessThreadID(hProcHandle);
valueToTest = LoopToAddress(3, hProcHandle, OffSet, (ProcessId + 0x02BA2890));
cout << "My value is : " << valueToTest << endl;
}

}


I Assume something goes wrong with my function to loop to the address but what ? and also I search for a float and I'm using a DWORD but I don't know if it's matter or not ?

Anyone who get time to answer to this, the help will be very appreciate !
Hey,
glad to see you're getting into hacking.
Firstly, I can't resist to comment on your LoopToAddress function, it's poorly written. Having an if statement like that in a for loop is usually an indicator of bad design, but I'll leave that up to you.

Here's the real problem:
Not only is your GetProcessThreadID function completely wrong, but it's also not the right thing to do. In case you wonder,
Code:
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
You pass in 0 for the process id, that's completely wrong and will surely fail, you're supposed to pass in the process id of the remote process.

Anyways, what you actually need to figure out is the base address of the main module. The code to do that is quite similar to your GetProcessThreadID function, also using TlHelp32:

Code:
HMODULE RemoteGetModuleHandle(HANDLE processHandle, const char* moduleName)
{
	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetProcessId(processHandle));
	if (snapshot == INVALID_HANDLE_VALUE)
		return NULL;

	MODULEENTRY32 entry;
	entry.dwSize = sizeof(MODULEENTRY32);
	if (!Module32First(snapshot, &entry))
		return NULL;

	do {
		if (!strcmpi(moduleName, entry.szModule))
			return entry.hModule;
		entry.dwSize = sizeof(MODULEENTRY32);
	} while (Module32Next(snapshot, &entry));

	return NULL;
}
Now do this instead:
Code:
HMODULE hModule = RemoteGetModuleHandle(hProcHandle, "witcher3.exe");
valueToTest = LoopToAddress(3, hProcHandle, OffSet, (DWORD)hModule + 0x02BA2890);
Also it doesn't matter that you use DWORD instead of float, they're the same size. It will only start to matter when you print it out. You can't simply cast it at this point, you would have to do something like this:
Code:
DWORD value = LoopToAddress(3, hProcHandle, OffSet, (ProcessId + 0x02BA2890));
valueToTest = *(float*)&value;
But again, that could be avoided if you would re-write LoopToAddress...

If you still need help ask me.

-- Xen0

EDIT: I just realized that witcher3 is 64 bit, so instead of using DWORD's for pointers you actually have to use QWORDs. I'll leave making those changes up to you. This will actually force you to re-write your LoopToAddress function because now in the last iteration you would read 8 bytes instead of only 4.
Posts 1–2 of 2 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us