Make Readprocessmemory code much more efficient

Introduction

I am currently using a class to read bytes in memory (via pointers). The code that I still work fine, I really do not want to change the way the class is installed, if possible (because it works), but hopefully some minor changes can be made to the class and my code to make it highly efficient.

What I am achieving at the moment:

  • Start with the address of the pointer in memory, read the byte at this address, add data to the array, add 1 to the source address so that we can now read the next address (for example, the source address is 24004, after saving the byte, increment 1 and the next address to read become 24005).

  • Reads a byte to the following address (24005), adds it to the same array, adds 1 to this address (next to reading it becomes 24006).

  • And so on for a fixed number of iterations (approximately 10,000).

Problem:

Making 10,000 readprocessmemory calls one by one causes a system delay of 20 seconds while she goes about her business.

I hope you can achieve:

Readprocessmemory , 10 000 , ( 10 000 ), , , ( {0} (1) (2).. .. {0}, , 10 000 ( )) , , . , 5 : {12345} {1} {2} {3} {4} {5}. , 1 2 3 4 5 1 200 40 43 20.

, , ( , , ):

:

 private void label1_Click(object sender, EventArgs e)
    {
        int[] valuesSeperated[200];
        List<byte> PreArray = new List<byte>();
        Process[] test = Process.GetProcessesByName("MyProcess"); //Get process handle 
        int baseAddress = test[0].MainModule.BaseAddress.ToInt32(); //Get base address
        byte ReadX  = MyClass.ReadPointerByte("MyProcess", BaseAddress, new int[] { 0xc, 0x0, 0x2 }); //call memory reading function (including memory offsets)
        PreArray.Add(ReadX);
                byte[] PreArrayToInt = PreArray.ToArray();
                int[] MYConvertedBytes = PreArray ToInt.Select(x => (int)x).ToArray();
                foreach (int i in MYConvertedBytes)
{
valuesSeperated // (don't really know what to do here, if the read was successful I would have a long number at [0], so now need to separate these as if I had read each one in memory one at a time. 
}

//new array with 10,000 values created.
    }

:

[DllImport("kernel32", EntryPoint = "ReadProcessMemory")]
private static extern byte ReadProcessMemoryByte(int Handle, int Address, ref byte Value, int Size, ref int BytesRead);

public static byte ReadPointerByte(string EXENAME, int Pointer, int[] Offset)
{
    byte Value = 0;
    checked
    {
        try
        {
            Process[] Proc = Process.GetProcessesByName(EXENAME);
            if (Proc.Length != 0)
            {
                int Bytes = 0;
                int Handle = OpenProcess(PROCESS_ALL_ACCESS, 0, Proc[0].Id);
                if (Handle != 0)
                {
                    foreach (int i in Offset)
                    {
                        ReadProcessMemoryInteger((int)Handle, Pointer, ref Pointer, 4, ref Bytes);
                        Pointer += i;
                    }
                    ReadProcessMemoryByte((int)Handle, Pointer, ref Value, 2, ref Bytes);
                    CloseHandle(Handle);
                }
            }
        }
        catch
        { }
    }
    return Value;
}
+5
1

:

:

// from http://www.pinvoke.net/default.aspx/kernel32.readprocessmemory
[DllImport("kernel32", EntryPoint = "ReadProcessMemory")]
private static extern bool ReadProcessMemory(IntPtr Handle, IntPtr Address, 
    [Out] byte[] Arr, int Size, out int BytesRead);

public static byte[] ReadBytes(IntPtr hnd, IntPtr Pointer, int Length)
{
    byte[] Arr = new byte[Length];
    int Bytes = 0;
    if(!ReadProcessMemory(hnd, Pointer, Arr, Length, out Bytes)){
        // Throw exception ...
    }
    // Check if Bytes == Length ...
    return Arr;
}

private void button1_Click(object sender, EventArgs e)
{
    //Get process handle
    Process[] test = Process.GetProcessesByName("notepad++");  

    //Get base address
    IntPtr baseAddress = test[0].MainModule.BaseAddress; 

    int bytesToRead = 16;
    int[] valuesSeparated = new int[bytesToRead / 4];
    byte[] ret = ReadBytes(test[0].Handle, baseAddress, bytesToRead);

    // Interpret ret as you like ...

    // Convert ret to int[]
    valuesSeparated = ....

}

[ ]

:

  • []
  • readprocessmemory . , .

, ( ...):

: BaseAddress ,

: byte [] Ret

:

1: LastPtr = BaseAddress
2: IdxOffset = 0
3: Offset = Offsets[IdxOffset]
4: LastValue = Memory[LastPtr + Offset]
5: Ret.Add(LastValue)
6: IdxOffset++
7: LastPtr = LastValue // Is this it?????
8: If IdxOffset < Offsets.Length then return else goto 3
+3

All Articles