I am trying to fiddle around with CounterStrike in order to learn something about memory editing in C++. I used an offset dumper in order to obtain the static pointers and offsets that will lead to the temporary adresses of the dw_LocalPlayer, m_fFlags and dw_ForceJump. I am not using any memory editing classes like VAMemory.dll, just ReadProcessMemory. I found out that when the player is in the air, the value of m_fFlags is "256". When he is on the ground it is "257". However, I am not able to read these to values once I obtained a temporary adress. Here is the code:
// ConsoleApplication1.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <cstdint>
#define dwLocalPlayer 0xAB06EC
#define dwForceJump 0x4D6A684
#define fFlags 0x100
int main()
{
HWND hwnd = FindWindowA(NULL, "Counter-Strike: Global Offensive");
if (hwnd == NULL)
{
std::cout << "Error!" << std::endl;
exit(-1);
system("PAUSE");
}
else
{
DWORD pid = GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
DWORD tempadress;
ReadProcessMemory(pHandle, (PBYTE*)dwLocalPlayer, &tempadress, sizeof(tempadress), NULL);
DWORD fl_Onground = tempadress + fFlags;
std::cout << fl_Onground << "\n" << &fl_Onground << std::endl;
system("PAUSE");
}
return 0;
}
I would really appreciate some help and suggestions to the code since Im stuck on this since a few days. I am only trying to gain knowledge on C++ here, I do not want to code any cheats or whatnot...
You are not using the offsets correctly. The offsets that are supplied by the dumper need to be added to other addresses, such as the base address of the module.
dwLocalPlayer is not a pointer to the local player, it's an offset. You have to add it to the address of client_panorama.dll.
Secondly:
DWORD fl_Onground = tempadress + fFlags;
This gives you the address of fl_Onground but you never read it's value, your subsequent std::cout will print the address not the value.
Fixed code here:
#include <iostream>
#include <Windows.h>
#include <cstdint>
#include <TlHelp32.h>
#define dwLocalPlayer 0xD30B94
#define dwForceJump 0x51EE680
#define m_fFlags 0x104
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_wcsicmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
int main()
{
HWND hwnd = FindWindowA(NULL, "Counter-Strike: Global Offensive");
if (hwnd == NULL)
{
std::cout << "Error!\n" << std::endl;
exit(-1);
system("PAUSE");
}
else
{
DWORD pid = GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
uintptr_t dllBaseAddress = 0;
dllBaseAddress = GetModuleBaseAddress(pid, L"client_panorama.dll");
DWORD tempadress;
ReadProcessMemory(pHandle, (BYTE*)(dllBaseAddress + dwLocalPlayer), &tempadress, sizeof(tempadress), NULL);
BYTE fl_Onground = 0;
ReadProcessMemory(pHandle, (BYTE*)(tempadress + m_fFlags), &fl_Onground, sizeof(fl_Onground), NULL);
std::cout << fl_Onground << "\n" << &fl_Onground << std::endl;
getchar();
}
return 0;
}
Related
I am writing a cheat for a game that I play sometimes, there is no anticheat. I have the value and pointers and offsets in Cheat Engine.
I have been using stuff from different places, mostly copy paste and put together (this is my first cheat, lagswitching doesn't count).
When I run it, it gives the Module base address + the pointer which was 0x7ff732b3bc80, then I already know the offsets. But the value it reads is 0 from the address 0x7ff732b3bc80 + the offsets 0xC60, 0x68, 0x58, 0x8, 0x0, 0x88, 0x14. I put these into Cheat Engine and receive the results of the value I am looking for, which is the Y coordinate. I will show a picture of that below.
This seems to be from the error 299 that it is not showing up.
Please help, this is not an online game I promise ;). I need to learn somehow.
#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#endif
#endif
#include <windows.h>
#include <memory.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32W modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32FirstW(hSnap, &modEntry))
{
do
{
if (!_wcsicmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32NextW(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
DWORD GetProcId()
{
PROCESSENTRY32 pe32;
HANDLE hSnapshot = NULL;
DWORD pid = 0;
pe32.dwSize = sizeof( PROCESSENTRY32 );
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( Process32First( hSnapshot, &pe32 ) )
{
do{
if( strcmp( pe32.szExeFile, "*****.exe" ) == 0 )
{
pid = pe32.th32ProcessID;
break;
}
}while( Process32Next( hSnapshot, &pe32 ) );
}
if( hSnapshot != INVALID_HANDLE_VALUE )
CloseHandle( hSnapshot );
return pid;
}
uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, vector<unsigned int> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size(); ++i)
{
ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
addr += offsets[1];
}
return addr;
}
int main()
{
DWORD ProcId = GetProcId();
cout<<ProcId << endl;
float CoordY = 0;
uintptr_t ModuleBase = GetModuleBaseAddress(ProcId, L"****[enter image description here][1].exe");
uintptr_t PointerAddr = ModuleBase + 0x0195BC80;
cout << "DynamicPointerAddress: " << "0x" << hex << PointerAddr << endl;
HANDLE hProcess = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcId);
vector<unsigned int> Offsets = {0xC60, 0x68, 0x58, 0x8, 0x0, 0x88, 0x14};
uintptr_t CoordAddress = FindDMAAddy(hProcess, PointerAddr, Offsets);
ReadProcessMemory(hProcess, (BYTE*)CoordAddress, &CoordY, sizeof(float), nullptr);
cout<<CoordY;
Sleep(10000);
}
And this is what Cheat Engine says:
*Edit 1: Value of the hProcess opening is 0xc0.
**Edit 2: Value of ReadProccessMemory() is 0.
**Edit 3: Thanks to someone in the comment's I have narrowd the error to Error 299 on ReadProcessMemory. If anyone has any way I could fix this please share. I have tried several online methods. And the program I am reading from is 64 bit.
I am running as admin.
I would like to find the value in 0x109B74 + 0xF8. Where did I get it wrong and how should I correct it? Please help me.
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main()
{
HWND hwnd = FindWindowA("AssaultCube", NULL);
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
void* Pointeraddress;
void* ptr;
while (1)
{
ReadProcessMemory(handle, (LPVOID)0x109B74, &Pointeraddress, 4, 0);
ReadProcessMemory(handle, (LPVOID)Pointeraddress, &ptr, 4, 0);
cout << ptr << endl;
}
}
0x109B74 is a relative offset, not an absolute address. It needs to be added to the base address of the module at runtime.
There are other issues with your code, but the best solution is to replace it all with this:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
uintptr_t GetModuleBaseAddress(DWORD procId, const char* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_stricmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
int main()
{
//Get ProcId of the target process
DWORD procId = GetProcId("ac_client.exe");
//Getmodulebaseaddress
uintptr_t moduleBase = GetModuleBaseAddress(procId, "ac_client.exe");
//Get Handle to Process
HANDLE hProcess = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);
uintptr_t pointer = moduleBase + 0x109B74;
uintptr_t objectBaseAddr = 0;
while (1)
{
ReadProcessMemory(hProcess, (LPVOID)pointer, &objectBaseAddr, sizeof(pointer), 0);
uintptr_t healthAddr = objectBaseAddr + 0xF8;
int healthValue = 0;
ReadProcessMemory(hProcess, (LPVOID)healthAddr, &healthValue, sizeof(healthValue), 0);
std::cout << "Health : " << healthValue << std::endl;
}
return 0;
}
Be sure to follow my tutorials to avoid making mistakes or learning the improper way to do things.
I'm writing a program in Code::Blocks that would simply print application's process ID and base address. The PID is found correctly but I'm having difficulties with base address also I'm using GNU GCC Compiler (x64). My guess is that the error lies in HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId); because it returns INVALID_HANDLE_VALUE. But still I can't resolve this problem. The IDE doesn't show any error or warnings. GetLastError() returns 5 (Access Denied)
Console output:
Process ID = 2656
INVALID_HANDLE_VALUE returned
BaseAddr = 0
And this is full code:
#include <iostream>
#include <Windows.h>
#include <tlhelp32.h>
#include <string.h>
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (lstrcmpi(procEntry.szExeFile, procName) == 0) {
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
uintptr_t GetModuleBaseAddress(DWORD procId, const char* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_stricmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
} else {
std::cout << "INVALID_HANDLE_VALUE returned" << std::endl;
}
CloseHandle(hSnap);
return modBaseAddr;
}
int main()
{
DWORD procId = GetProcId("Game.exe");
std::cout << "Process ID = " << procId << std::endl;
uintptr_t baseAddr = GetModuleBaseAddress(procId, "Game.exe");
std::cout << "BaseAddr = " << baseAddr << std::endl;
std::getchar();
return 0;
}
Well after putting it to Code Blocks, i just changed the _stricmp in the GetModuleBaseAddress function to strcmp also this line
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
to this
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId);
Try this code:
#include <windows.h>
#include <tlhelp32.h>
#include <string>
#include <iostream>
using namespace std;
HANDLE _process = NULL;
DWORD pid = 0;
DWORD baseAddr = 0;
bool getID(string process)
{
HANDLE hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 entry;
entry.dwSize = sizeof(entry);
do
{
if(!strcmp(entry.szExeFile,process.c_str()))
{
pid = entry.th32ProcessID;
CloseHandle(hHandle);
_process = OpenProcess(PROCESS_ALL_ACCESS,false,pid);
return true;
}
} while(Process32Next(hHandle,&entry));
return false;
}
bool getModuleBaseAddress(string module)
{
HANDLE hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pid);
MODULEENTRY32 mentry;
mentry.dwSize = sizeof(mentry);
do
{
if(!strcmp(mentry.szModule,module.c_str()))
{
CloseHandle(hHandle);
baseAddr = (DWORD)mentry.modBaseAddr;
return true;
}
} while(Module32Next(hHandle,&mentry));
return false;
}
int main()
{
while(!getID("popo.exe")) {Sleep(10);}
while(!getModuleBaseAddress("popo.exe")) {Sleep(10);}
cout << "PID: " << pid << endl << "Base Address: " << baseAddr;
return 0;
}
I'm trying to write a code in C++ which would display a process ID and base address of some application, PID seems to look correct but base address is 0, which is incorrect. My question is - what's wrong here?
IDE: Code::Blocks
Also to make it even run i had to set up "-lpsapi" in
Settings -> Compiler -> Linker settings -> Other linker options
I was thinking about building this as admin but could't find such option in Code::Block (maybe build-in?)
Console output
Build messages
#define WINVER 0x0501
#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <Psapi.h>
#include <tlhelp32.h>
using namespace std;
HANDLE GetHandle()
{
string name = "PathOfExile_x64.exe";
DWORD pid = 0;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 process;
ZeroMemory(&process, sizeof(process));
process.dwSize = sizeof(process);
if (Process32First(snapshot, &process))
{
do
{
if (string(process.szExeFile) == name)
{
pid = process.th32ProcessID;
break;
}
} while (Process32Next(snapshot, &process));
}
CloseHandle(snapshot);
if (pid != 0)
{
cout << "pid = " << pid << endl;
return OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
}
return NULL;
}
HMODULE GetModule()
{
HMODULE hMods[1024];
HANDLE pHandle = GetHandle();
DWORD cbNeeded;
unsigned int i;
if (EnumProcessModules(pHandle, hMods, sizeof(hMods), &cbNeeded))
{
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(pHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
{
string wstrModName = szModName;
string wstrModContain = "PathOfExile_x64.exe";
if (wstrModName.find(wstrModContain) != string::npos)
{
CloseHandle(pHandle);
return hMods[i];
}
}
}
}
return nullptr;
}
int main()
{
HWND WindowHandle = FindWindow(nullptr, "Path of Exile");
DWORD PID;
GetWindowThreadProcessId(WindowHandle, &PID);
PVOID hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, PID);
HMODULE Module = GetModule();
DWORD BaseAddress = (DWORD)Module;
cout << BaseAddress << endl;
}
I would do it like this, tested working. I'm not familiar with the Enum functions, I prefer to use the ToolHelp32Snapshot function
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <tlhelp32.h>
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
uintptr_t GetModuleBaseAddress(DWORD procId, const char* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_stricmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
int main()
{
DWORD procId = GetProcId("PathOfExile_x64.exe");
uintptr_t modBase = GetModuleBaseAddress(procId, "PathOfExile_x64.exe");
std::cout << "0x" << std::hex << modBase << std::endl;
std::getchar();
return 0;
}
I was learning how to interact with processes from a channel called "null". I wrote his program and tried to understand how everything worked. But when i executed it the wpm function did work but then the target program immediately closed after it incremented the same variable I was writing to.
Anyways here's the code.
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
HANDLE hProc = NULL;
DWORD ProcId;
bool attatchProc(const char* ProcName)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(PROCESSENTRY32);
auto hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcSnap == INVALID_HANDLE_VALUE)
return false;
while (Process32Next(hProcSnap, &procEntry)) {
std::cout << procEntry.szExeFile << std::endl;
if (!strcmp(ProcName, procEntry.szExeFile)) {
std::cout << "Process Found!\n Heres the Process ID" << procEntry.th32ProcessID << std::endl;
ProcId = procEntry.th32ProcessID;
hProc = OpenProcess(PROCESS_ALL_ACCESS, false, ProcId);
if (hProc == NULL)
std::cout << "Sike you thought lmao" << std::endl;
CloseHandle(hProcSnap);
return true;
}
}
std::cout << "Process not found or other issue";
}
template <class DataType>
void wpm(DataType VarToWrite, DWORD addressToWrite)
{
WriteProcessMemory(hProc, (PVOID)addressToWrite, &VarToWrite, sizeof(DataType), 0);
}
int main()
{
DWORD memAddr = 0x012FF848;
attatchProc((char*)"Testing.exe");
while (1)
{
wpm<int>(68, memAddr);
}
}
You are not using Process32First to get the first entry in the snapshot. Microsoft Docs has a tutorial on how to do it correctly here
If you use the tutorial you can come up with your own version like mine, which includes exactly what you need and nothing else. I use TCHAR in this example so you can either include tchar.h or you can change it to match your coding style.
#include
DWORD GetProcId(const TCHAR* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_tcsicmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
After calling this function you would check if the return is nonzero and then call OpenProcess() using the process id and the memory access permissions you require. If the process handle is nonzero you may then continue to write to the process memory. If you write to the incorrect memory address you will crash the program, so ensure you have the correct address by using the Visual Studio Debugger and comparing what you see against what you see in the target process using another debugger like Cheat Engine.