So I've been fighting through issue after issue with external process memory reading (reading the memory of processes I don't have access to.) My understanding of several things has changed, but there is one thing which I simply cannot get my head around.
The win32api function ReadProcessMemory() accepts several arguments, as seen here:
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
I'm passing those arguments like this:
public byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
{
IntPtr ptrBytesRead;
byte[] buffer = new byte[BytesToRead];
ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out ptrBytesRead);
return buffer;
}
It was, until recently, my understanding that the Address listed here was the only thing really important to reading the memory, and that was what found me the correct value in memory. Unfortunately, that appears to be a load of tosh, and it seems that actually the handle controls which window I am interacting with. For example:
I am running 2 versions of the Process "Notepad.exe".
Each instance of the process has an integer in it, the first one contains the number 12345, the second contains 54321.
I'm looking to read that integer, and let's say (though I haven't confirmed this, so it may be untrue) memory address within that programs memory space is 0x1000.
If I run for example:
ReadProcessMemory(NP.Handle, NP.MainModule.BaseAddress + 0x1000, buffer, 32, bread);
That will read the process with that handle, at that base address added to that offset. However this code will read exactly the same value:
ReadProcessMemory(NP.Handle, NP2.MainModule.BaseAddress + 0x1000, buffer, 32, bread);
Note that NP2 is supposed to be the second notepad window, and NP is the first. On top of the above, this will read a different value (in spite of the address we're reading being the same as the first example):
ReadProcessMemory(NP2.Handle, NP.MainModule.BaseAddress + 0x1000, buffer, 32, bread);
Surely this means that the handle is controlling where the memory is read, and not the address, and that in fact the address is completely irrelevant to what I'm actually trying to do? Can anyone explain to me why that would be the case?
Apologies if this question is excessively specific, but this issue has been racking my brain for a long time now, and although I speak to numerous programmers on a daily basis, none of them have been able to (or perhaps it's more that they haven't been willing to) help me.
I am fully aware that this will only work for 2 running instances of the same exe, so it won't work if you're gonna read Firefox and Notepad (I think). I'm just wondering why it is the handle that makes this change, and not the address.
Thanks