Solved [C++][Basic Trainer] WriteProcessMemory Question

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

arlight1

Newbie
Full Member
Sep 25, 2015
15
108
0
Hello guys!

I've been following Fleep's tutorial from a couple years back on creating a game trainer with C++. Originally I tried with C# but had some issues.
The game, in particular, that I've been creating memory changes for is Mortal Kombat 10.

Now, I just want to say I do have some C++ experience and was able to get the trainer working on a basic level (CE tutorial w/ pointers and write value), but the problem is MK10 is a 64-bit process.
I took the explanation and code Fleep provided with his tutorial and tried to re-create it to fit a 64-bit game.
I've rewritten it for my own debugging purpose and it mostly seems to work, but the value I tell it to write doesn't seem to stick in game. Actually, it appears to write twice into a single DWORD_PTR container.

I'll post my code thus far, but please focus on "WriteProcessMemory" that I call within the while loop of the main function. It says it is successful in its writing of memory. Also, I am fairly certain my pointer and offsets are correct as I have double-checked with CE and my own hand calculation (Game.exe module is found + offset + 5 separate offsets). I've done much googling and research to get to this point.

In any case here is my code, any suggestions/tips would be appreciated! I have posted an image of the console results window below it.

C++:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <ctime>
#include "TlHelp32.h"
#include "tchar.h"

DWORD_PTR FindDmaAddy(int PointerLevel, HANDLE hProcHandle, DWORD Offsets[], DWORD_PTR BaseAddress);
DWORD_PTR WriteToMemory(HANDLE hProcHandle);
DWORD_PTR getModuleBaseAddr(DWORD_PTR procId, TCHAR * lpszModuleName);

std::string GameName = "MK10";
LPCSTR LGameWindow = "MK10";
std::string GameStatus;

bool IsGameAvail;
bool UpdateOnNextRun;

//TutStep1Vars
bool P1HPStatus;
DWORD P1HPValue = 0x3F800000;
DWORD_PTR P1HPBaseAddress = getModuleBaseAddr(15344, "MK10.exe") + 0x0304C488;
DWORD P1HPOffsets[] = { 0x28, 0x590, 0x588, 0xA0, 0x420 };

VOID DisplayError(CHAR* pMessage)
{
	DWORD dwNum;
	CHAR szSysMsg[256] = { 0 };
	CHAR* p;

	dwNum = GetLastError();
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL, dwNum,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		szSysMsg, 256, NULL);
	// Trim the end of the line and terminate it with a null
	p = szSysMsg;
	while ((*p > 31) || (*p == 9))
		++p;
	do { *p-- = 0; } while ((p >= szSysMsg) &&
		((*p == '.') || (*p < 33)));
	printf("\n%s error %d (%s)", pMessage, dwNum, szSysMsg);
}

BOOL EnableTokenPrivilege(LPTSTR pPrivilege)
{
	HANDLE hToken;
	TOKEN_PRIVILEGES token_privileges;
	DWORD dwSize;
	ZeroMemory(&token_privileges, sizeof(token_privileges));
	token_privileges.PrivilegeCount = 1;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
	{
		DisplayError("OpenProcessToken failed");
		return FALSE;
	}
	if (!LookupPrivilegeValue(NULL, pPrivilege, &token_privileges.Privileges[0].Luid))
	{
		DisplayError("LookupPrivilegeValue failed");
		CloseHandle(hToken);
		return FALSE;
	}
	token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	if (!AdjustTokenPrivileges(hToken, FALSE, &token_privileges, 0, NULL, &dwSize))
	{
		DisplayError("AdjustTokenPrivileges failed");
		CloseHandle(hToken);
		return FALSE;
	}
	CloseHandle(hToken);
	return TRUE;
}

#define array_size(array) (sizeof((array))/sizeof((array[0])))

int main()
{
	HWND hGameWindow = NULL;
	HANDLE hProcHandle = NULL;
	char choice;
	DWORD_PTR pointer = P1HPBaseAddress;
	DWORD_PTR pointer1;
	DWORD_PTR pointer2;
	DWORD_PTR pointer3;
	DWORD_PTR pointer4;
	DWORD_PTR pointer5;
	DWORD_PTR pTemp = 0;
	DWORD_PTR baseaddy;
	DWORD_PTR firstaddy;
	DWORD_PTR secondaddy;
	DWORD_PTR thirdaddy;
	DWORD_PTR fourthaddy;
	DWORD_PTR fifthaddy;
	DWORD_PTR writeCheck;
	DWORD_PTR confirmWrite;
	DWORD dwProcID = NULL;
	DWORD_PTR AddressToWrite;

	if (!EnableTokenPrivilege(SE_DEBUG_NAME))
	{
		std::cout << "Enable Privilege Failed" << std::endl;
	}

	else
	{
		while (!GetAsyncKeyState(VK_INSERT))
		{
			hGameWindow = FindWindow(NULL, LGameWindow);
			if (hGameWindow)
			{
				GetWindowThreadProcessId(hGameWindow, &dwProcID);
				if (dwProcID != 0)
				{
					hProcHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcID);
					if (hProcHandle == INVALID_HANDLE_VALUE || hProcHandle == NULL)
					{
						GameStatus = "Failed to open process for valid handle";
					}
					else
					{
						GameStatus = "Game is ready To hack";
					}
				}
				else
				{
					GameStatus = "Failed to get process ID";
				}
			}

			else
			{
				GameStatus = "GAME NOT FOUND!";
			}


			std::cout << GameStatus << std::endl << std::endl;
			std::cout << "Info: " << std::endl;
			//Base Address
			std::cout << "Base Address (Module from PID): 0x" << std::hex << pointer << std::endl;
			baseaddy = ReadProcessMemory(hProcHandle, (LPCVOID)pointer, &pTemp, sizeof(pTemp), NULL);
			std::cout << "Base PTR Read Successful: " << std::hex << baseaddy << ", Error #: " << GetLastError() << std::endl << std::endl;
			//First Address
			pointer1 = pTemp + P1HPOffsets[0];
			std::cout << "Pointer Value: 0x" << std::hex << pTemp << std::endl;
			std::cout << "First Pointer Loc: 0x" << std::hex << pointer1 << std::endl;
			firstaddy = ReadProcessMemory(hProcHandle, (LPCVOID)pointer1, &pTemp, sizeof(pTemp), NULL);
			std::cout << "First PTR Read Successful: " << std::hex << firstaddy << std::endl << std::endl;
			//Second Address
			pointer2 = pTemp + P1HPOffsets[1];
			std::cout << "Pointer Value: 0x" << std::hex << pTemp << std::endl;
			std::cout << "Second Pointer Loc: 0x" << std::hex << pointer2 << std::endl;
			secondaddy = ReadProcessMemory(hProcHandle, (LPCVOID)pointer2, &pTemp, sizeof(pTemp), NULL);
			std::cout << "Second PTR Read Successful: " << std::hex << secondaddy << std::endl << std::endl;
			//Third Address
			pointer3 = pTemp + P1HPOffsets[2];
			std::cout << "Pointer Value: 0x" << std::hex << pTemp << std::endl;
			std::cout << "Third Pointer Loc: 0x" << std::hex << pointer3 << std::endl;
			thirdaddy = ReadProcessMemory(hProcHandle, (LPCVOID)pointer3, &pTemp, sizeof(pTemp), NULL);
			std::cout << "Third PTR Read Successful: " << std::hex << thirdaddy << std::endl << std::endl;
			//Fourth Address
			pointer4 = pTemp + P1HPOffsets[3];
			std::cout << "Pointer Value: 0x" << std::hex << pTemp << std::endl;
			std::cout << "Fourth Pointer Loc: 0x" << std::hex << pointer4 << std::endl;
			fourthaddy = ReadProcessMemory(hProcHandle, (LPCVOID)pointer4, &pTemp, sizeof(pTemp), NULL);
			std::cout << "Fourth PTR Read Successful: " << std::hex << fourthaddy << std::endl << std::endl;
			//Fifth Address
			pointer5 = pTemp + P1HPOffsets[4];
			std::cout << "Pointer Value: 0x" << std::hex << pTemp << std::endl;
			std::cout << "Fifth Pointer Loc: 0x" << std::hex << pointer5 << std::endl;
			fifthaddy = ReadProcessMemory(hProcHandle, (LPCVOID)pointer5, &pTemp, sizeof(pTemp), NULL);
			std::cout << "Fifth PTR Read Successful: " << std::hex << fifthaddy << std::endl << std::endl;

			AddressToWrite = FindDmaAddy(array_size(P1HPOffsets), hProcHandle, P1HPOffsets, P1HPBaseAddress);
			std::cout << "WriteTo Pointer Loc(Fcn Calculated): 0x" << std::hex << AddressToWrite << std::endl;
			std::cout << "Offset Size " << array_size(P1HPOffsets) << std::endl;
			std::cout << "Value to write: 0x" << std::hex << P1HPValue << std::endl;
			writeCheck = WriteProcessMemory(hProcHandle, (BYTE*)AddressToWrite, &P1HPValue, sizeof(P1HPValue), NULL);
			std::cout << "Successfully written to memory: " << std::hex << writeCheck << ", Error #: " << GetLastError() << std::endl << std::endl;

			confirmWrite = ReadProcessMemory(hProcHandle, (LPCVOID)AddressToWrite, &pTemp, sizeof(pTemp), NULL);
			std::cout << "Value Written: 0x" << std::hex << pTemp << std::endl;
			std::cin >> choice;
		}

	}

	CloseHandle(hProcHandle);
	CloseHandle(hGameWindow);
	return ERROR_SUCCESS;
}



DWORD_PTR FindDmaAddy(int PointerLevel, HANDLE hProcHandle, DWORD Offsets[], DWORD_PTR BaseAddress)
{
	DWORD_PTR pointer = BaseAddress;
	DWORD_PTR pTemp;

	DWORD_PTR pointerAddr;
	for (int c = 0; c < PointerLevel; c++)
	{
		if (c == 0)
		{
			ReadProcessMemory(hProcHandle, (LPCVOID)pointer, &pTemp, sizeof(pTemp), NULL);
		}

		pointerAddr = pTemp + Offsets[c];
		ReadProcessMemory(hProcHandle, (LPCVOID)pointerAddr, &pTemp, sizeof(pTemp), NULL);
	}
	return pointerAddr;
}

DWORD_PTR WriteToMemory(HANDLE hProcHandle)
{
	DWORD_PTR AddressToWrite;
	AddressToWrite = FindDmaAddy(3, hProcHandle, P1HPOffsets, P1HPBaseAddress);
	WriteProcessMemory(hProcHandle, (BYTE*)AddressToWrite, &P1HPValue, sizeof(P1HPValue), NULL);

	return AddressToWrite;
}

DWORD_PTR getModuleBaseAddr(DWORD_PTR procId, TCHAR * lpszModuleName)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId);
	DWORD_PTR moduleBaseAddr = 0;

	if (hSnapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 mentry32 = { 0 };
		mentry32.dwSize = sizeof(MODULEENTRY32);

		if (Module32First(hSnapshot, &mentry32))
		{
			do
			{
				if (_tcscmp(mentry32.szModule, lpszModuleName) == 0)
				{
					moduleBaseAddr = (DWORD_PTR)mentry32.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &mentry32));
		}
	}
	else
	{
		std::cout << "Error on finding module base address: " << GetLastError() << "\n";
	}

	return moduleBaseAddr;
}

 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,745
40,528
316
Nope, it writes correctly.
To WriteProcessMemory (WPM) you pass an unsigned 4-byte (DWORD) value 0x3F800000. It definitly writes 4-bytes and not more.
What causes the "double" output (0x3F8000003F800000) is the fact that you are reading 8-bytes because in the call where you check the written value with RPM you pass a DWORD_PTR (which is 8-bytes big in when you compile your program as x64) as buffer.
So RPM reads 8-bytes from memory and coincidentally the additional 4-bytes are 0x3F800000, too what makes it look like you wrote the value twice.

The check should look like this:
C++:
DWORD checkBuffer;
confirmWrite = ReadProcessMemory(hProcHandle, (LPCVOID)AddressToWrite, &checkBuffer, sizeof(checkBuffer), NULL);
std::cout << "Value Written: 0x" << std::hex << checkBuffer << std::endl;
 
Last edited by a moderator:

arlight1

Newbie
Full Member
Sep 25, 2015
15
108
0
Вroihon;36817 said:
Nope, it writes correctly.
To WriteProcessMemory (WPM) you pass an unsigned 4-byte (DWORD) value 0x3F800000. It definitly writes 4-bytes and not more.
What causes the "double" output (0x3F8000003F800000) is the fact that you are reading 8-bytes because in the call where you check the written value with RPM you pass a DWORD_PTR (which is 8-bytes big in when you compile your program as x64) as buffer.
So RPM reads 8-bytes from memory and coincidentally the additional 4-bytes are 0x3F800000, too what makes it look like you wrote the value twice.

The check should look like this:
C++:
DWORD checkBuffer;
confirmWrite = ReadProcessMemory(hProcHandle, (LPCVOID)AddressToWrite, &checkBuffer, sizeof(checkBuffer), NULL);
std::cout << "Value Written: 0x" << std::hex << checkBuffer << std::endl;
Thank you! Your suggestion worked perfectly, as the proper value is now displayed! But, this is just a user diagnostic. A way for me to see if the proper value was written. So why didn't the value overwrite work before then? Just after using your checkBuffer read did it begin working in-game and changing the value correctly? Perhaps a game restart?

In any case, I have it loop to constantly overwrite to my desired value and it "freezes" my health in-game.

Thanks again for the assistance. Love this forum! :D
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods