Openprocess/Readprocessmemory/Writeprocessmemory/Closehandle Equivalent

OpenProcess/ReadProcessMemory/WriteProcessMemory/CloseHandle equivalent

You're looking for ptrace. Despite the name, it will also target individual threads on Linux and possibly other systems. More info can be found with Google if that blog post doesn't help.

OpenProcess handle invalid for ReadProcessMemory


Memory::Memory()
{
Memory(0);
}

This isn't doing what you think its doing: it's not actually calling the other constructor, instead it's creating a temporary that gets discarded. So you are opening the process, but in a separate temporary object, while this object remains uninitialized.

Safer approach is to have a separate Initialize(offset) method that you call from both ctors.

(The advice in the other answers is also good; check your return values, and where you get a E_INVALID_HANDLE, check that the handle is something that looks like a handle. Or set a breakpoint at the OpenHandle and ReadProcessMemory and check that the same value is being used in both places. C++ is often full of surprises, and there's often no substitute for just stepping through the code to make sure it's doing what you think it's doing.)

C++ Qt WriteProcessMemory

In case you haven't solve this error:

mainwindow.cpp(103) : error C3861: 'Attach': identifier not found

function names are cases sensitive in C/C++ etc ... So rename your function to "Attach(...)"

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

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.

Open process with debug privileges and read/write memory

From you description, it appears that you have gotten to the point where you can open the process with SE_DEBUG. At this point you now have a handle to the target process.

What your code appears to be missing is the use of ReadProcessMemory.

First we need to look at the definition of ReadProcessMemory:

BOOL WINAPI ReadProcessMemory(
_In_ HANDLE hProcess,
_In_ LPCVOID lpBaseAddress,
_Out_ LPVOID lpBuffer,
_In_ SIZE_T nSize,
_Out_ SIZE_T *lpNumberOfBytesRead);

This function essentially gives you the ability to copy a block of memory from one process space into your process space. So you need to use this method to read a block of memory the size of the data structure you wish to read into your process space, then you can reinterpret the memory block as that data type.

So semi pseudocode for reading an unsigned int from your target process looks like this:

unsigned int ReadUInt(HANDLE process, const void * address)
{
// Add parameter validation

unsigned char buffer[sizeof(unsigned int)] = {};
size_t bytesRead = 0;

BOOL res = ::ReadProcessMemory(process, // The handle you opened with SE_DEBUG privs
address, // The location in the other process
buffer, // Where to transfer the memory to
sizeof(unsigned int), // The number of bytes to read
&bytesRead); // The number of bytes actually read

if (!res)
{
// Deal with the error
}

if (bytesRead != sizeof(unsigned int))
{
// Deal with error where we didn't get enough memory
}

return *reinterpret_cast<unsigned int *>(buffer);
}

Instead of using this line:

unsigned int * theValue = (unsigned int*) 0xDE123F00;

You would do this:

unsigned int theValue = ReadUInt(hproc, 0xDE123F00);

Keep in mind that this requires that you know the size and memory layout of the types you are trying to read. Simple types that are contained in contiguous memory can be retrieved in a single ReadProcessMemory call. Types that contain pointers as well as values will require you to make extra calls to ReadProcessMemory to find the values referenced by the pointers.

VB.NET ReadProcessMemory string

You are printing the value of sBuffer which is an integer which explains the results you are seeing. Besides, sBuffer does not contain the data which is read from memory. I think your lpBuffer parameter (and also stringinmemory as well) should not be a Long but instead be an Byte array. Something like this:

Const PROCESS_WM_READ As Integer = &H10

<DllImport("kernel32.dll")> _
Public Shared Function OpenProcess(dwDesiredAccess As Integer, bInheritHandle As Boolean, dwProcessId As Integer) As IntPtr
End Function

<DllImport("kernel32.dll")> _
Public Shared Function ReadProcessMemory(hProcess As Integer, lpBaseAddress As Integer, lpBuffer As Byte(), dwSize As Integer, ByRef lpNumberOfBytesRead As Integer) As Boolean
End Function

Public Shared Sub Main()
Dim notepadProcess As Process = Process.GetProcessesByName("notepad")(0)
Dim processHandle As IntPtr = OpenProcess(PROCESS_WM_READ, False, notepadProcess.Id)

Dim bytesRead As Integer = 0
Dim buffer As Byte() = New Byte(23) {}

'The address in this line is hard-coded. Use whatever is appropriate for your situation.
ReadProcessMemory(CInt(processHandle), &H36B9D0, buffer, buffer.Length, bytesRead)

Console.WriteLine(Encoding.Unicode.GetString(buffer))
Console.ReadLine()
End Sub

C++: reading memory of another process

Here is an example for your ReadMemoryInt() function:

int ReadMemoryInt(HANDLE processHandle, LPCVOID address) {
int buffer = 0;
SIZE_T NumberOfBytesToRead = sizeof(buffer); //this is equal to 4
SIZE_T NumberOfBytesActuallyRead;
BOOL err = ReadProcessMemory(processHandle, address, &buffer, NumberOfBytesToRead, &NumberOfBytesActuallyRead);
if (err || NumberOfBytesActuallyRead != NumberOfBytesToRead)
/*an error occured*/ ;
return buffer;
}

The & mean that the address of the variable is passed instead its value.

And in ReadMemoryString() you cannot know the actual size you need to read, you could either read a big block (size 999) or read many little blocks till you get one containing \0.

And if you want to know if it works, you can start it in a debugger and look if the values you expect are returned.



Related Topics



Leave a reply



Submit