Write/Read Protected memory c++ - c++

I am trying to use VirtualProtectEx() to change the memory address protection from PAGE_NOACCESS to PAGE_READ_WRITE, but it's not working.
Here is the code:
#define WIN64_LEAN_AND_MEAN
#include <iostream>
#include <Windows.h>
#include <string>
#include <stdint.h>
#include <vector>
using namespace std;
char a[16] = {'c','a','m','o','_','0','2','a'};
int b = 33555192;
MEMORY_BASIC_INFORMATION mbi;
int main() {
if (HWND hWnd = FindWindowA("IW8",0)) {
DWORD oldprotect;
DWORD pID = 0;
GetWindowThreadProcessId(hWnd, &pID);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
uint64_t address = 0x7ff6f1ba0d07;
VirtualQueryEx(pHandle, (LPCVOID)address, &mbi, sizeof(mbi));
if (VirtualProtectEx(pHandle, (LPVOID)address, 74, PAGE_EXECUTE_READWRITE, &oldprotect )) cout << "Changed memory protection !";
else cout << "Protection changer failed !";
cout << "\n" << "HWND : " << hWnd << "\n" << "PID : " << pID << "\n" << "PHandle : " << pHandle << "\n";
if (ReadProcessMemory(pHandle, (LPVOID)address, &b, sizeof(b), nullptr)) cout << "Found : " << b;
else (cout << "Invalid address");
cout << "\n\nMbi : " << mbi.Protect;
CloseHandle(pHandle);
}
else cout << "Process not found !";
int abc;
cin >> abc;
}

Please note that PAGE_NO_ACCESS can also mean that The page is not allocated which means that VirtualProtectEx will fail no matter what. You can try to use VirtualAllocEx to try to Allocate some memory at the location 0x7ff6f1ba0d07 first preferably with MEM_COMMIT | MEM_RESERVE and PAGE_EXECUTE_READWRITE before trying using VirtualProtectEx
https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex

Related

ReadProcessMemory() Returning 0 ERROR_PARTIAL_COPY

#include <Windows.h>
#include <iostream>
#include <vector>
#include <TlHelp32.h>
#include <tchar.h>
using namespace std;
DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
{
MODULEENTRY32 lpModuleEntry = {0};
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
if(!hSnapShot)
return NULL;
lpModuleEntry.dwSize = sizeof(lpModuleEntry);
BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
while(bModule)
{
if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
{
CloseHandle( hSnapShot );
return (DWORDLONG)lpModuleEntry.modBaseAddr;
}
bModule = Module32Next( hSnapShot, &lpModuleEntry );
}
CloseHandle( hSnapShot );
return NULL;
}
int main() {
DWORD pID;
DWORDLONG off1, off2;
DWORDLONG baseAddress;
char moduleName[] = _T("AoE2DE_s.exe");
HWND hGameWindow;
HANDLE pHandle;
//Get Handles
hGameWindow = FindWindow(NULL, "Age of Empires II: Definitive Edition");
cout << "Game Window: " << hGameWindow << std::endl;
GetWindowThreadProcessId(hGameWindow, &pID);
cout << "Process ID: " << pID << std::endl;
pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
cout << "Process Handle: " << std::hex << pHandle << std::endl;
//Get Client Base Addy
DWORDLONG clientBase = GetModuleBase(moduleName, pID);
cout << "Client Base: " << clientBase << std::endl;
ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), NULL);
DWORD lastError = GetLastError();
cout << "Error: " << lastError << std::endl;
cout << "Base Address: " << std::hex << baseAddress << std::endl;
ReadProcessMemory(pHandle, (LPCVOID)(baseAddress + 0x18), &off1, sizeof(DWORDLONG), NULL);
cout << "After Offset 1: " << std::hex << off1 << std::endl;
ReadProcessMemory(pHandle, (LPCVOID)(off1 + 0x9230), &off2, sizeof(DWORDLONG), NULL);
cout << "After Final Offset: " << off2 << std::endl;
cin.get();
}
The error occurs on this line:
ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), NULL);
Application output for debugging purposes:
Game Window: 0x1307c2
Process ID: 11988
Process Handle: 0xec
Client Base: cc640000
Error: 12b
Base Address: 0
After Offset 1: 401519
After Final Offset: 8
Not sure how it is failing here, I'm somewhat new to this. Everything else goes through perfectly without error's but fails on the first ReadProcessMemory() if someone can help bring the solution for this to light I would be grateful.
ReadProcessMemory is defined like this:
BOOL ReadProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesRead
);
If it returns zero then there has been an error, and only in that case GetLastError will return a meaningfull error number.
So correct usage would be:
SIZE_T readBytes;
if (!ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), &readBytes)) {
DWORD lastError = GetLastError();
cout << "ReadProcessMemory failed: Error: " << lastError << " read " << readBytes << std::endl;
}
else
{
cout << "ReadProcessMemory succeeded"; << std::endl;
cout << "Base Address: " << std::hex << baseAddress << std::endl;
}

WriteProcessMemory not working for some reason

This is all the source code for a program i'm trying to make, and I can't get WriteProcessMemory to work at all. It returns the correct messages, saying that everything went successfully, but nothing actually changes in the game. Does anyone know of a fix?
#include <iostream>
#include <Windows.h>
using namespace std;
// variables
int plcHold = 1;
string hlthLoop = "OFF";
string ammoLoop = "OFF";
DWORD pid;
DWORD playerAddr;
DWORD hlthOffs = 0xF8;
// main function
int main()
{
// finding pid, opening proc, finding player address
HWND hwnd = FindWindowA(NULL, "AssaultCube");
if(hwnd == NULL)
{
cout << "Error; Couldn't find window" << endl;
} else{
GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(pHandle == NULL)
{
cout << "Error; Couldn't open process" << endl;
} else{
ReadProcessMemory(pHandle, (LPCVOID)0x50F4F4, &playerAddr, sizeof(playerAddr), 0);
if(ReadProcessMemory != FALSE)
{
cout << "Health successfully read!" << endl;
} else{
cout << "Error code " << GetLastError << endl;
}
}
while(plcHold == 1){
cout << "========== *****'s Assault Cube Trainer ==========\n" << endl;
cout << "=============== Health Loop - " << hlthLoop << " ================" << endl;
Sleep(1500);
system("cls");
if(GetAsyncKeyState(0x5A))
{
cout << "Health successfully edited!" << endl;
WriteProcessMemory(pHandle, LPVOID(playerAddr + hlthOffs), 0, sizeof(999), 0);
CloseHandle(pHandle);
}
}
}
return 0;
}
You're passing a null pointer to WriteProcessMemory for the third (lpBuffer) parameter. You have to pass the address of the actual value, not the value itself. If you want to write an integer value, try this:
DWORD val = 0; // or 999?
WriteProcessMemory(
pHandle, static_cast<LPVOID>(playerAddr + hlthOffs),
&val, sizeof(val), 0);

Exception thrown at 0x00007FFF168E1657 (vcruntime140d.dll) in "<name>.exe": 0xC0000005: Access violation writing location 0x0000000000000000

I tried creating two different visual c++ console applications for Inter Process Communication(IPC). The Build for both codes is successful.But,when I try to debug it, I get exception like this "Exception thrown at 0x00007FFF168E1657 (vcruntime140d.dll) in FileMapServer_Parent.exe: 0xC0000005: Access violation writing location 0x0000000000000000"
//PARENT PROCESS:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <Tlhelp32.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <cstring>
#include <cctype>
#include <fstream>
using namespace std
int main()
{
cout << "\t\t.....FILEMAPPING SERVER or PARENT....." << endl;
cout << endl;
//Local Variable Definitions
HANDLE hFileMap;
BOOL bResult;
PCHAR lpBuffer = NULL;
char Buffer[256] = "Hello From File Map Server";
size_t szBuffer = size(Buffer);
// STEP 1 : Create File Map
hFileMap = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
256,
L"LOCAL\\MyFileMap);
if (hFileMap == FALSE)
{
cout << "CreateFileMapping Failed & Error Number - " << GetLastError() << endl;
}
else
cout << "CreateFileMapping Success - " << endl;
// STEP 2 : Map View of File
lpBuffer = (PCHAR)MapViewOfFile(
hFileMap,
FILE_MAP_ALL_ACCESS,
0,
0,
256);
if (lpBuffer == NULL)
{
cout << "MapViewOf File Failes & Error No - " << GetLastError() << endl;
}
else
cout << "MapViewOf File Success " << endl;
//STEP 3 : Copy Memory Function
CopyMemory(lpBuffer,Buffer,szBuffer);
//STEP 4 : Unmap View Of File
bResult = UnmapViewOfFile(lpBuffer);
if (bResult == FALSE)
{
cout << "UnMapViewOfFile Failed & Error No - " << GetLastError() << endl;
}
else
cout << "UnMapViewOfFile FSuccess - " << endl;
system("PAUSE");
return 0;
}
Exception while running parent process:
[1]: https://i.stack.imgur.com/bomQB.png
//CHILD PREOCESS:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <Tlhelp32.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <cstring>
#include <cctype>
#include <fstream>
using namespace std;
int main()
{
cout << "\t\t.....FILEMAPPING CLIENT or CHILD....." << endl;
cout << endl;
// Local Variable Definitions
HANDLE hFileMap;
BOOL bResult;
PCHAR lpBuffer = NULL;
// STEP 1 : OpenFileMapping
hFileMap = OpenFileMapping(
FILE_MAP_ALL_ACCESS,
FALSE,
L"LOCAL\\MyFileMap");
if(hFileMap == NULL)
{
cout << "OpenFileMap Failed & error - " << GetLastError() << endl;
}
else
cout << "OpenFileMap success " << endl;
//STEP 2 : MapViewOfFile
lpBuffer = (PCHAR)MapViewOfFile(
hFileMap,
FILE_MAP_ALL_ACCESS,
0,
0,
256);
if (lpBuffer == NULL)
{
cout << "MapViewOf File Failes & Error No - " << GetLastError() << endl;
}
else
cout << "MapViewOf File Success " << endl;
//STEP 3 : Reading the data from File Map Object
cout << "DATA READING FROM PARENT PROCESS--->" <<lpBuffer<< endl;
//STEP 4 : UnMapViewOfFile
bResult = UnmapViewOfFile(lpBuffer);
if (bResult == FALSE)
{
cout << "UnMapViewOfFile Failed & Error No - " << GetLastError() << endl;
}
else
cout << "UnMapViewOfFile FSuccess - " << endl;
//STEP 5 : Close Handle
CloseHandle(hFileMap);
system("PAUSE");
return 0;
}
The problem is here:
hFileMap = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
256,
L"LOCAL\\MyFileMap");
From the documentation of Kernel object namespaces they are case sensitive so you must change LOCAL to Local for this to work.
In addition to the "Global\" prefix, client processes can use the "Local\" prefix to explicitly create an object in their session namespace. These keywords are case sensitive.
https://msdn.microsoft.com/en-us/library/aa382954(v=vs.85).aspx
While debugging this issue I also changed the code to exit if the mapping fails:
if (hFileMap == NULL)
{
cout << "CreateFileMapping Failed & Error Number - " << GetLastError() << endl;
return -1;
}
else
cout << "CreateFileMapping Success - " << endl;
This avoided the crash with the original "LOCAL" (mapping failed).

Win API ReadProcessMemory at base address of DLL returning unexpected data

I'm trying to read the contents of a DLL from memory for some academic research. Specifically, the NTDSA.DLL library for the purpose of mutating specific instructions to simulate programming errors to force the system to fail. The failure will then be recorded to train machine learning algorithms to predict future failures (this is an attempt to generalize previously published research seen here).
I'm getting what I believe to be the base address in virtual memory of the lsass.exe process (which loads the target DLL) through the process outlined here. I'm then calling ReadProcessMemory with an allocated buffer and the handle to lsass obtained by calling OpenProcess with 'PROCESS_ALL_ACCESS' set. The ReadProcessMemory returns with error code 299 80% of the time (partial read) with zero bytes read. My assumption is that the area I'm trying to access is in use when the call is made. Fortunately, it will occasionally return the number of bytes I'm requesting. Unfortunately, the data returned does not match what is on disk when compared to the static DLL in the System32 directory.
So the question is, is ReadProcessMemory doing something funny with the address that I give it, or is my virtual address wrong? Is there another way to figure out where that DLL gets loaded into memory? Any thoughts? Any help or suggestions would be greatly appreciated.
Adding Code:
// FaultInjection.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <psapi.h>
#include <string>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <io.h>
#include <tchar.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {
// Declarations
int pid = 0;
__int64* start_addr;
DWORD size_of_ntdsa;
DWORD aProcesses[1024], cbNeeded, cProcesses;
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HMODULE hmods[1024];
unsigned int i;
// Get All pids
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)){
cout << "Failed to get all PIDs: " << GetLastError() << endl;
return -1;
}
// Find pid for lsass.exe
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++) {
if (aProcesses[i] != 0) {
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
if (hProc != NULL) {
HMODULE hMod;
DWORD cbNeededMod;
if (EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeededMod)) {
GetModuleBaseName(hProc, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
}
if (wstring(szProcessName).find(L"lsass.exe") != string::npos) {
pid = aProcesses[i];
}
CloseHandle(hProc);
}
}
}
cout << "lsass pid: " << pid << endl;
HANDLE h_lsass = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!h_lsass) {
cout << "Failed to open process (are you root?): " << GetLastError() << endl;
return -1;
}
// Get Process Image File Name
char filename[MAX_PATH];
if (GetProcessImageFileName(h_lsass, (LPTSTR)&filename, MAX_PATH) == 0) {
cout << "Failed to get image file name: " << GetLastError() << endl;
CloseHandle(h_lsass);
return -1;
}
// Enumerate modules within process
if (EnumProcessModules(h_lsass, hmods, sizeof(hmods), &cbNeeded)) {
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(h_lsass, hmods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
if (wstring(szModName).find(L"NTDSA.dll") != string::npos) {
_tprintf(TEXT("%s\n"), szModName);
MODULEINFO lModInfo = { 0 };
if (GetModuleInformation(h_lsass, hmods[i], &lModInfo, sizeof(lModInfo))){
cout << "\t Base Addr: " << lModInfo.lpBaseOfDll << endl;
cout << "\t Entry Point: " << lModInfo.EntryPoint << endl;
cout << "\t Size of image: " << lModInfo.SizeOfImage << endl;
start_addr = (__int64*)lModInfo.lpBaseOfDll;
size_of_ntdsa = lModInfo.SizeOfImage;
}
else {
cout << "Failed to Print enumerated list of modules: " << GetLastError() << endl;
}
}
} else {
cout << "Failed to Print enumerated list of modules: " << GetLastError() << endl;
}
}
}
else {
cout << "Failed to enum the modules: " << GetLastError() << endl;
}
// Ready to continue?
string cont = "";
cout << "Continue? [Y|n]: ";
getline(cin, cont);
if (cont.find("n") != string::npos || cont.find("N") != string::npos) {
CloseHandle(h_lsass);
return 0;
}
void* buf = malloc(size_of_ntdsa);
if (!buf) {
cout << "Failed to allocate space for memory contents: " << GetLastError() << endl;
CloseHandle(h_lsass);
return -1;
}
SIZE_T num_bytes_read = 0;
int count = 0;
if (ReadProcessMemory(h_lsass, &start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
cout << "Read success. Got " << num_bytes_read << " bytes: " << endl;
} else {
int error_code = GetLastError();
if (error_code == 299) {
cout << "Partial read. Got " << num_bytes_read << " bytes: " << endl;
} else {
cout << "Failed to read memory: " << GetLastError() << endl;
CloseHandle(h_lsass);
free(buf);
return -1;
}
}
if (num_bytes_read > 0) {
FILE *fp;
fopen_s(&fp, "C:\\ntdsa_new.dll", "w");
SIZE_T bytes_written = 0;
while (bytes_written < num_bytes_read) {
bytes_written += fwrite(buf, 1, num_bytes_read, fp);
}
fclose(fp);
cout << "Wrote " << bytes_written << " bytes." << endl;
}
CloseHandle(h_lsass);
free(buf);
return 0;
}
Code works as described minus my amateur mistake of sending the address of the variable I was using to store the address of the location in virtual memory of the target application. In above code, changed:
if (ReadProcessMemory(h_lsass, &start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
to
if (ReadProcessMemory(h_lsass, start_addr, buf, size_of_ntdsa, &num_bytes_read) != 0) {
Works like a charm. Thank you ssbssa for pointing out mistake, sorry for wasting anyone's time.

WriteProcessMemory returns 0 in C++

I am developing a small cash hack for GTA V and I found that when I use
WriteProcessMemory(hp, (LPVOID)0x1417C4C18, &cashVal, (DWORD)sizeof(cashVal), 0)
that the WriteProcessMemory returns 0. Here is the full source code of my small hack.
#include <Windows.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int cashVal = 0;
cout << "Enter the amount of cash you want: " << endl;
cin >> cashVal;
HWND hwnd = FindWindow(0, "Grand Theft Auto V");
if (hwnd == 0) {
cout << "Cannot find the GTAV window. Make sure its running in Windowed mode!" << endl;
}
else {
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hp) {
cout << "Could not get a handle to GTAV. Try again :(" << endl;
}
else {
int success = WriteProcessMemory(hp, (LPVOID)0x1417C4C18, &cashVal, (DWORD)sizeof
(cashVal), 0);
if (success > 0) {
cout << "You now have " << cashVal << " money!" << endl;
}
else {
cout << "Writing the memory failed!" << endl;
cout << "Error code: " << success << endl;
}
CloseHandle(hp);
}
}
cin.get();
return 0;
}
I basically ask the user to input the cash they want, and it's meant to set it in the game, but it returns a code of 0 and fails. It doesn't fail trying to find the game window because it doesn't print that message to the standard output. Please help me!
NOTE: The hack will be used on single player
First, don't use PROCESS_ALL_ACCESS. Only request what you actually need. WriteProcessMemory() only needs PROCESS_VM_WRITE and PROCESS_VM_OPERATION access, so request only that.
Like many other API functions, when WriteProcessMemory() fails, GetLastError() will tell you why. Your code is assuming that WriteProcessMemory() itself returns an error code directly, but it does not. It returns a BOOL (not an int) to indicate success or failure, and then GetLastError() returns the error code if failure. This is documented behavior:
Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError. The function fails if the requested write operation crosses into an area of the process that is inaccessible.
Try this:
#include <windows.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int cashVal = 0;
cout << "Enter the amount of cash you want: " << endl;
cin >> cashVal;
HWND hwnd = FindWindow(0, "Grand Theft Auto V");
if (hwnd == 0) {
cout << "Cannot find the GTAV window. Make sure its running in Windowed mode!" << endl;
}
else {
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hp = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
if (!hp) {
cout << "Could not get a handle to GTAV. Try again :(" << endl;
}
else {
BOOL success = WriteProcessMemory(hp, (LPVOID)0x1417C4C18, &cashVal, sizeof(cashVal), 0);
if (success) {
cout << "You now have " << cashVal << " money!" << endl;
}
else {
DWORD errCode = GetLastError();
cout << "Writing the memory failed!" << endl;
cout << "Error code: " << errCode << endl;
}
CloseHandle(hp);
}
}
cin.get();
return 0;
}
You are most likely trying to write to a memory path where you don't have access to... probably you are using a 32-bit program to write to a 64-bit memory address(that's if u use a 64-bit computer), I think I had this problem a few years back porting solved my problem then forgive me if I am wrong atleast that was what I thought.
Try the code on a 32-bit address and if it works... that solves your problem.
And for the Getting_Last_Error you can add this lil' bit of functionality I use.
void PrintLastErrorMsg(){
LPTSTR pTmp = NULL;
DWORD errnum = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
errnum,
LANG_NEUTRAL,
(LPTSTR)&pTmp,
0,
NULL
);
cout << "Error(" << errnum << "): " << pTmp << endl;
}
Be free to make changes.