문제

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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top