I have made a method that will read a multi-pointer by providing the wanted offsets + the start adress. (Code below). To summarize, Im trying to streamline this method and below I will explain my problem.
I have been strugling around with the conversion. The parameter is an IntPtr and the output of a read adress is an byte array, my first idea was: "Convert Byte array to IntPtr, reprocess it and finally convert the last read adress into a int32 (since the last adress is not a pointer it will never be read so converting here to Int32 should be allright)",
However that did not give a nice result. So currently Im stuck with the solution of converting Byte array to Int32, then Int32 to IntPtr. People do say that the bitconverter is a bad approach because it might cause issues on 64-bit platforms and I do also believe there is an approach that may give a better performence (since Im converting an object 2 times).
Finally if anyone think it would be possible to make a similar function in C++ and then P/Invoke it in C# (I guess it would be more efficient that way?) please tell me. (Im trying to adapt my programming knowledges. And find combination of languages very interesting)
[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[In, Out] byte[] buffer, Int32 sizeout, out IntPtr lpNumberOfBytesRead);
public Int32 ReadBytes(IntPtr Handle, IntPtr Address, int[] Offsets, int BytesToRead = 4)
{
IntPtr ptrBytesRead;
byte[] value = new byte[BytesToRead];
ReadProcessMemory(Handle, Address, value, BytesToRead, out ptrBytesRead);
//Read Offsets
for (int i = 0; i < Offsets.Length; i++)
{
ReadProcessMemory(Handle,
new IntPtr(BitConverter.ToInt32(value, 0) + Offsets[i]),
value,
BytesToRead,
out ptrBytesRead);
}
return BitConverter.ToInt32(value, 0);
}
Any ideas to streamline this method would be very well appreciated! Thanks on advance!
As @usr stated, the performance of the code will be entirely dominated by the calls to ReadProcessMemory
. You should not expect to improve the performance from its current level.
However, you can make the code much easier to read by avoiding byte arrays and BitConverter
. Like this:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
out IntPtr lpBuffer,
IntPtr nSize,
out IntPtr lpNumberOfBytesRead
);
private static IntPtr ReadProcessPointer(IntPtr hProcess, IntPtr Address)
{
IntPtr result;
IntPtr NumberOfBytesRead;
if (ReadProcessMemory(hProcess, Address, out result, (IntPtr)IntPtr.Size, out NumberOfBytesRead) == 0)
throw new Win32Exception();
return result;
}
public static IntPtr FollowPointers(IntPtr hProcess, IntPtr Address, int[] Offsets)
{
IntPtr ptr = ReadProcessPointer(hProcess, Address);
for (int i = 0; i < Offsets.Length; i++)
ptr = ReadProcessPointer(hProcess, ptr + Offsets[i]);
return ptr;
}