[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern int ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[In, Out] byte[] buffer, int size, out IntPtr lpNumberOfBytesRead);
private byte[] ReadBytes(Process process, MemoryAddress address, int bytesToRead)
{
var value = new byte[bytesToRead];
var baseAddress = GetBaseAddressByModuleName(process, address.Module.Value) + address.BaseAddress;
var handle = GetProcessHandle(process);
ReadProcessMemory(handle, (IntPtr)baseAddress, value, bytesToRead, out var bytesRead);
foreach (var offset in address.Offsets)
{
ReadProcessMemory(handle,
new IntPtr(BitConverter.ToInt32(value, 0) + offset),
value,
bytesToRead,
out bytesRead);
}
return value;
}
private static int GetSize<T>()
{
return Marshal.SizeOf(typeof(T));
}
This works fine, along with float, int, double and strings:
public long ReadLong(Process process, MemoryAddress address)
{
return ReadBytes(process, address, GetSize<long>()).ConvertTo<long>();
}
Here is my problem (ConvertTo
is just an extension that uses BitConverter
.):
public short ReadShort(Process process, MemoryAddress address)
{
return ReadBytes(process, address, GetSize<short>()).ConvertTo<short>();
}
public byte ReadByte(Process process, MemoryAddress address)
{
return ReadBytes(process, address, 1)[0];
}
When those methods are used, an exception is thrown in the foreach loop of ReadBytes
: System.ArgumentException: 'Destination array is not long enough to copy all the items in the collection. Check array index and length.'
I presume it's related to BitConverter.ToInt32
. Using ToInt16
for short
gets rid of the exception, but yields the wrong result. How to treat short
and byte
values with offsets correctly?