Edited code using ReadProcessMemory has issues - c++

asked a question Call CloseHandle on handle that is a function parameter?
After someone edited the code, I updated it to find the code no longer works as intended.
intptr_t readMem(HANDLE processHandle, intptr_t address, int sizeToReadBytes)
{
intptr_t memValue = 0;
bool success = ReadProcessMemory(processHandle, (LPVOID)address, memValue, sizeToReadBytes, NULL);
if (!success)
std::wcout << "Memory read failed on address: " << std::hex << address << "\n";
return memValue;
}
In the line
ReadProcessMemory(processHandle, (LPVOID)address, memValue, sizeToReadBytes, NULL);
The memValue wouldn't compile without (LPVOID) or (LPCVOID) casts, but with them the code no longer reads the memory (or writes in the case of the functions using WriteProcessMemory
Originally (and now I've changed it back in my little program) it uses a reference &memValue and works fine.
My question is:
Should this work?
Or is the edit correct and the rest of my program potentially wrong?
I can provide more code if needed, just not sure which bits and didn't want to clog up the screen more than I have... Also should I rollback the edit?

The third parameter of ReadProcessMemory() is a memory address in the calling process where the function writes the read data to. You are not passing a memory address, though. In the code shown in the third revision to the original question, you were type-casting the value of an uninitialized integer variable into a memory pointer. So the function would try to write to random memory. Now you have removed the type-cast, so the code should not even compile anymore.
Your readMem() function is not designed correctly. You need to change it so that either:
The caller allocates memory of the required size and then the function simply fills the memory:
bool readMem(HANDLE processHandle, intptr_t address, void *memValue, int sizeToReadBytes)
{
bool success = ReadProcessMemory(processHandle, (LPVOID)address, memValue, sizeToReadBytes, NULL);
if (!success)
std::wcout << "Memory read failed on address: " << std::hex << address << "\n";
return success;
}
intptr_t memValue = 0;
readMem(processHandle, address, &memValue, sizeof(memValue));
The function allocates memory and returns it to the caller:
void* readMem(HANDLE processHandle, intptr_t address, int sizeToReadBytes)
{
uint8_t memValue = new uint8_t[sizeToReadBytes];
bool success = ReadProcessMemory(processHandle, (LPVOID)address, memValue, sizeToReadBytes, NULL);
if (!success) {
std::wcout << "Memory read failed on address: " << std::hex << address << "\n";
delete [] memValue;
memValue = NULL;
}
return memValue;
}
intptr_t *memValue = (intptr_t*) readMem(processHandle, address, sizeof(intptr_t));
...
delete [] memValue;
Or:
bool readMem(HANDLE processHandle, intptr_t address, int sizeToReadBytes, std:vector<uint8_t> &memValue)
{
memValue.resize(sizeToReadBytes);
bool success = ReadProcessMemory(processHandle, (LPVOID)address, &memValue[0], sizeToReadBytes, NULL);
if (!success)
std::wcout << "Memory read failed on address: " << std::hex << address << "\n";
return success;
}
std::vector<uint8_t> buffer;
readMem(processHandle, address, sizeof(intptr_t), buffer);
intptr_t memValue = (intptr_t*) &buffer[0];

Related

OpenClipboard crashes with CLIPBRD_E_CANT_OPEN

I have a problem with opening clipboard multiple times. It opens up fine on the first call, however, my program needs to access the clipboard several times, but shuts down on the second call of OpenClipboard(NULL) with the CLIPBRD_E_CANT_OPEN error).
This is a function that opens the clipboard
void Translator::process_copied()
{
//cout << "processing" << endl;
if (OpenClipboard(NULL))
{
HANDLE clip;
clip = GetClipboardData(CF_UNICODETEXT);
Relayout((WCHAR*)clip);
HANDLE res = GlobalAlloc(GMEM_FIXED, sizeof(WCHAR)*wcslen((WCHAR*)clip)+1);
res = clip;
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, res);
CloseClipboard();
}
else
{
std::cout << GetLastError();
//throw clipboard_did_not_open;
//cout << "error in opening clipboard" << endl;
}
}
I suspect that the problem appears in the SetClipboardData() function, because if I remove it, clipboard doesn't have any problem opening multiple times. The same goes to res = clip; line.
I am new to WinAPI and C++ in general, so I apologize if my question is silly.
When storing a memory block on the clipboard, the HANDLE given to SetClipboardData() must be allocated with the GMEM_MOVEABLE flag, per the SetClipboardData() documentation:
If the hMem parameter identifies a memory object, the object must have been allocated using the [GlobalAlloc] function with the GMEM_MOVEABLE flag.
As such, you must call GlobalLock() on the HANDLE returned by GetClipboardData() in order to access the data, per the GlobalAlloc() documentation:
GMEM_MOVEABLE
0x0002
Allocates movable memory. Memory blocks are never moved in physical memory, but they can be moved within the default heap.
The return value is a handle to the memory object. To translate the handle into a pointer, use the GlobalLock function.
Don't just type-cast the HANDLE as-is, like you can for a memory object allocated with the GMEM_FIXED flag.
You are also not putting any character data in the res memory that you allocate with GlobalAlloc(). Which is moot, since you are not putting your allocated memory on the clipboard at all, you are actually putting the original HANDLE from GetClipboardData() back onto the Clipboard, and then leaking your res memory.
Try something more like this instead:
void Translator::process_copied()
{
//cout << "processing" << endl;
HWND hwnd = ...; // a window that YOU own
if (OpenClipboard(hwnd))
{
HANDLE clip = GetClipboardData(CF_UNICODETEXT);
if (clip)
{
WCHAR *text = (WCHAR*) GlobalLock(clip);
Relayout(text);
HANDLE res = GlobalAlloc(GMEM_MOVABLE, (wcslen(text)+1) * sizeof(WCHAR));
if (res)
{
WCHAR *newText = (WCHAR*) GlobalLock(res);
// put characters in newText as needed...
wcscpy(newText, text);
GlobalUnlock(res);
GlobalUnlock(clip);
EmptyClipboard();
if (!SetClipboardData(CF_UNICODETEXT, res))
{
std::cout << GetLastError();
GlobalFree(res);
//throw clipboard_did_not_set;
//cout << "error in setting clipboard data" << endl;
}
}
else
{
std::cout << GetLastError();
//throw global_memory_not_allocated;
//cout << "error in allocating memory" << endl;
GlobalUnlock(clip);
}
}
else
{
std::cout << GetLastError();
//throw clipboard_data_not_get;
//cout << "error in getting clipboard data" << endl;
}
CloseClipboard();
}
else
{
std::cout << GetLastError();
//throw clipboard_did_not_open;
//cout << "error in opening clipboard" << endl;
}
}

ReadProcessMemory always reads 0

I'm creating a cheat for educational purpose (on windows for now) on a small game. My error is so far is that ReadProcessMemory always reads 0.
LPCVOID addr = (LPCVOID *) 0x1228A93C; // TO-DO: c++ casts
int dest = 0;
SIZE_T read = 0;
bool error = ReadProcessMemory(process, addr, &dest, sizeof(int), &read);
if (!error) {
printf("I read %llu w/ %u at %p\r\n", read, dest, addr);
} else {
printf("This isn't working: %p / %llu\r\n", addr, read);
std::cerr << "err: " << std::to_string(::GetLastError()) << std::endl;
return (1);
}
There, I try to read the amount on money in the game. By using Cheat Engine, I get the value that changes everytime you use your money which is 0x1228A93C in the code snippet above. If I change the value pointed by this address in cheat engine, the money also change in game so I guess this is right address.
Nonetheless when I run this snippet, I get this output:
I read 0 w/ 0 at 0x1228a93c
which means it doesn't read.
Note: There is more code, in my program, above this one but this is basically finding the game window, create a snapshot of the game and find the exe module.
This is probably what you want:
LPCVOID addr = (LPCVOID *) 0x1228A93C; // TO-DO: c++ casts
int dest = 0;
SIZE_T read = 0;
if (ReadProcessMemory(process, addr, &dest, sizeof(int), &read))
{
printf("I read %llu w/ %u at %p\r\n", read, dest, addr);
} else {
auto lasterror = ::GetLastError(); // first thing to do: call GetLastError
printf("This isn't working: %p / %llu\r\n", addr, read);
std::cerr << "err: " << lasterror << std::endl; // std::to_string is useless here
}
In case of error the first thing to do is call GetLastError() because you don't know if cout will call SetLastError() or not.

ReadProcessMemory Crashes Application When Trying to Read 32bit Integer From Another Process

I have been experimenting with various aspects of the Windows API and thought I would give process memory manipulation a try. Previously I had been trying to do this in native C++ using this method: C++ - Get value of a particular memory address
However, this method does not work and I found a response somewhere on the Cplusplus forum that told me to use ReadProcessMemory. I found that WriteProcessMemory works just fine when attempting to edit values, but ReadProcessMemory either fails (returning error code 299) or crashes the application.
Here is my code:
#include <iostream>
#include <cstdint>
#include <Windows.h>
#include <cstdio>
using namespace std;
int main()
{
LPVOID bytes;
DWORD pid;
SIZE_T *num_bytes_read;
int temp;
SIZE_T size = sizeof(temp);
LPCVOID address = reinterpret_cast<int*>(0x404004);
HWND hwnd = FindWindow(NULL, "C:\\Users\\Delkarix\\Desktop\\memory_edit_test.exe");
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
BOOL worked = ReadProcessMemory(hProcess, address, bytes, size, num_bytes_read);
cout << "ERROR: " << GetLastError() << endl;
cout << "PROCESS: " << hProcess << endl;
cout << "BYTES: " << bytes << endl;
cout << "BASE ADDRESS: " << address << endl;
cout << "FUNCTION SUCCESS: " << worked << endl;
cout << "BYTES READ: " << *num_bytes_read << endl;
CloseHandle(hProcess);
}
I have noticed that the application crashes when the num_bytes_read variable is a pointer (the 5th parameter of ReadProcessMemory is the num_bytes_read variable) and it throws error 299 when it is not a pointer (the 5th parameter of ReadProcessMemory is the pointer to the num_bytes_read variable).
Here is the code for the memory_edit_test.cpp:
#include <iostream>
using namespace std;
int test = 6;
int main() {
string input;
cout << &test << endl; // Where I got the address 0x404004
getline(cin, input);
cout << test << endl; // Used to check the value against the one I got from ReadProcessMemory
getline(cin, input);
}
How can I get ReadProcessMemory to succeed? Answers to similar questions on StackOverflow either do nothing or they just make the problem worse.
The problem is very simple, third parameter to ReadProcessMemory is meant to point to a buffer, where the memory read will be written to. You just give it an unintialised pointer. Similar problem with the fifth parameter as well.
Your code should look something like this
int temp;
SIZE_T num_bytes_read;
BOOL worked = ReadProcessMemory(hProcess, address, &temp, sizeof temp, &num_bytes_read);
Note third and fifth parameters are pointers to already existing memory. Declare a variable and use & to get its address.

Simple ReadProcessMemory not working

I googled a bit but can't seem to make this work.
privileges();
int pid = getPid("test.exe");
cout << "Process ID :" << pid << endl;
const char* prename;
HANDLE pHandle = OpenProcess(PROCESS_VM_READ , FALSE, pid);
if (pHandle)
{
cout << "Handle Open Success" << endl;
//SIZE_T bytesRead;
if (ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, strlen(prename), NULL))
{
cout << "Read Success" << endl;
cout << prename << endl;
}
else
cout << GetLastError() << endl;
}
return 0;
It prints "Read Success" but does not print the variable just blank. The address(address of a string in another process) I got is from ollydbg and verified it using a function as well.
I also wanted to replace the string using writeprocessmemory but before i get to that i needed to make sure reading is correct.
Any idea?
Your problem lies here:
const char* prename;
ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, strlen(prename), NULL)
Your char pointer is not initialized and neither is the random memory it points to. When you call strlen on it, it's trying to get the length of a random memory location.
Secondly you're using the address of the pointer &prename, that's the address of the pointer not the char array it should point to.
To fix do it like this:
char prename[100];
ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, sizeof(prename), NULL)
sizeof() will return 100, so you will be reading 100 bytes of memory

Remote Injection

So, i'm injecting a code in the memory of another process like this:
void RemoteInj::ExecuteFunction(DWORD Start, DWORD End, DWORD Entry, RemoteArgs* Args)
{
unsigned long Id;
int size = End - Start;
cout << size << endl;
void* Func = VirtualAllocEx(hProcess, NULL, size+10, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
void* ep = (void*)(Entry-Start+(DWORD)(Func));
WriteProcessMemory(hProcess, Func, (void*)Start, size, NULL);
void* Data = VirtualAllocEx(hProcess, NULL, sizeof(RemoteArgs)+1, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, Data, (void*)Args, sizeof(RemoteArgs), NULL);
cout << hex << Func << endl;
cout << "Function: 0x" << hex << Start << endl << "End: 0x" << hex << End << endl;
system("PAUSE");
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)ep, Data, NULL, NULL);
CloseHandle(hProcess);
}
My problem is: If i use calls in that thread, for example:
void F(RemoteArgs* arg)
{
while (true)
{
arg->pSleep(50); //Works
Sleep(50); //doesnt work
}
return;
}
No need to explain why it doesn't work, i know, it's another process....My question is: Is there a way to make function like this(Sleep()) work, i could try importing to the process also the IAT with the proper distance, do you have a better idea?Thanks!
As you suspect, the reason this doesn't work right off the bat is that the call to Sleep in your process actually goes to a location in your import address table (IAT) which has a jump to the real Sleep implementation in kernel32.dll. Even though the other process also imports kernel32.dll (all processes do), it obviously does not have an identical IAT.
There are ways, but none that I know of are trivial.