In all the examples I've seen the third parameter or the buffer
is an integer but I'm not quite sure wtf this value is supposed to represent or how it's useful in anyway so I tried a char
array and got random garbage so I'm curious as to what this value can be used for and the best container to put it in and if the data type is dependent on the value we're inquiring about.
After looking at my code I realized I made a really stupid mistake by not initializing the process handle when declaring it. Here is my code though and now I'm getting ERROR_PARTIAL_COPY
. And dwRead
is 0. wtf
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
system("tasklist");
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD proc_Id = 0;
cin >> proc_Id;
HANDLE hProc = INVALID_HANDLE_VALUE;
char value[500];
SIZE_T dwRead;
hProc = OpenProcess(PROCESS_ALL_ACCESS, TRUE, proc_Id);
if(hProc == NULL)
{
cout << "Error when trying to retrieve process handle" << endl;
}
void *baseAddr = (void*)hProc;
if(VirtualAllocEx(hProc, NULL, SysInfo.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ) == NULL)
{
cout << "VirtualAllocEx error" << endl;
}
if(ReadProcessMemory(hProc, baseAddr, &value, sizeof(value), &dwRead) == 0)
{
cout << "ReadProcessMemory failed: " << GetLastError() << endl;
}
cout << "Value is: " << value << endl;
cout << "Amount read successfully: " << dwRead << endl;
}
BOOL WINAPI ReadProcessMemory( HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead );
The parameter is declared as LPVOID
(a typedef
for void*
). Any pointer can implicitly convert to a pointer-to-void - meaning that the buffer you provide can actually be any type you like. The only restriction is that it has to be large enough to hold nSize
bytes of data.
SIZE_T dwRead;
int iValue;
if (ReadProcessMemory(hProcess, lpAddress, &iValue, sizeof(iValue), &dwRead)) // read an int
{
if (dwRead == sizeof(iValue))
{
// got int successfully
}
}
char buf[256];
if (ReadProcessMemory(hProcess, lpAddress, buf, sizeof(buf), &dwRead)) // read 256 chars
{
// got dwRead bytes successfully
}
If you're getting garbage in the returned buffer it's probably because the read failed, or didn't read as much data as you requested, and you didn't check the return value properly. If the function succeeds the lpNumberOfBytesRead
parameter lets you find out how many bytes were read successfully.
If the function returns 0
it means it failed altogether - in this case, the contents of the buffer you provided are undefined and should not be used.