I am trying to get the ReadProcessMemory function to work, but it doesnt seem to return anything useful. In the code below, I initiated output to 0 and the value of output does not change from my ReadProcessMemory function like expected. Am I missing anything? I am thinking that I need to include Kernel32.lib. somehow, but I have no idea really. Can someone point me in the right direction?
Well, first of all you have to thoroughly understand your target game. You have to spend a lot of time using such tools as Cheat Engine, OllyDbg etc. to investigate the game. These tools will help you find specific memory locations of interest such as memory locations to increase health, wealth etc. When you finally have a thorough understanding of the internal workings of the game, you can start writing code. With that said, here a basic example using pinball.
The first thing I did before writing the code was to fire up Cheat Engine and attach it to a running instance of pinball. I then played one ball to generate a score. Let's assume my score for one ball was 17450. I entered this score, 17450 in the "value" box and clicked on the first scan button. I found two memory addresses of interest listed in the listbox. These are the two memory addresses that I used in the code below. You'll have to run CE and attach to pinball to get your memory addresses since they may not necessarily be the same addresses I used.
Code:
#include <windows.h>
#include <stdio.h>
HANDLE hProcess = (HANDLE) INVALID_HANDLE_VALUE;
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;
}
BOOL CloseProcess(VOID)
{
if (CloseHandle(hProcess))
return TRUE;
else
{
DisplayError("Close handle failed");
return FALSE;
}
}
BOOL OpenProcess(LPTSTR pProcessWindowTitle)
{
HWND hTargetWindow = (HWND) -1;
DWORD dwProcessID = 0;
hTargetWindow = FindWindow(NULL, pProcessWindowTitle); // see if it exist
if (hTargetWindow)
{
GetWindowThreadProcessId(hTargetWindow, &dwProcessID); //get a PROCESS number
if (dwProcessID)
{
hProcess = OpenProcess(PROCESS_ALL_ACCESS ,TRUE, dwProcessID);
if (hProcess == NULL)
{
DisplayError("Invalid Process handle");
return FALSE;
}
else return TRUE;
}
else
{
DisplayError("Invalid ProcessId");
return FALSE;
}
}
DisplayError("Cannot find target window");
return FALSE;
}
BOOL ReadProcess(LPCVOID lpBaseAddress, DWORD dwSize)
{
BOOL bSuccess = FALSE, bProcessSuspended = FALSE;
DWORD dwTemp = 0, dwBytesRead = 0;
if (hProcess)
{
if (SuspendThread(hProcess) != (DWORD) -1)
bProcessSuspended = TRUE;
if (ReadProcessMemory(hProcess, lpBaseAddress, &dwTemp, dwSize,
&dwBytesRead) && dwBytesRead == dwSize)
{
bSuccess = TRUE;
printf("Value read = %d\n",dwTemp);
}
else
{
bSuccess = FALSE;
DisplayError("ReadProcess failed");
}
if (bProcessSuspended)
ResumeThread(hProcess);
}
else DisplayError("hProcess invalid");
return bSuccess;
}
INT main(VOID)
{
// The following two addresses were identified by
// attaching Cheat Engine (CE) to Pinball.exe
DWORD dwAddress1 = 0x00AB4414;
DWORD dwAddress2 = 0x00BAFCF2;
if ( !EnableTokenPrivilege (SE_DEBUG_NAME) )
DisplayError("EnableTokenPrivilege failed");
else if(OpenProcess("3d Pinball for Windows - Space Cadet"))
{
ReadProcess((LPCVOID)dwAddress1, sizeof(DWORD));
ReadProcess((LPCVOID)dwAddress2, sizeof(DWORD));
CloseProcess();
}
else DisplayError("OpenProcess failed");
return 0;
}