0

以下の方法を使用して、メモリ内のバイトを読み取ります。互いに非常に近いメモリアドレスの値を読み取りたいです。以前は、メモリ内の各バイトに対して個別の呼び出しを行い、for ループを使用して結果を配列に追加していました。これは非常に非効率的になったため、代わりに以下のコードを適応させて大きなメモリ ブロックを読み取り、配列を反復処理して必要なバイトを引き出すようにします。私はそれを解決しようと少し時間を費やしましたが、本当に苦労しています。参考までに、このメソッドはポインターを読み取り、その値がポインターの場合はそのポインターを読み取り、静的アドレスに到達するまでそのアドレスのバイト値を読み取ります。

[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;
}

私がこれまでに持っているもの:

 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 seperate these as if I had read each one in memory one at a time. 
}

string TestString = MYConvertedBytes[0].ToString();
                label1.Text = TestString;
    }

要約すると、上記の方法を使用して、より大きなメモリブロック(一度に200アドレスなど)を読み取る方法がわかりません。結果の配列から値を抽出して、バイトが分離された新しい配列を形成する最善の方法がわかりません。何か不明な点があればお尋ねください。私はまったく新しく、本当に学びたいので、ヒントや助けをいただければ幸いです。

4

1 に答える 1

1

あなたの相互運用署名は私には完全に間違っているように見えます。

c 署名は次のとおりです。

BOOL WINAPI ReadProcessMemory(
  __in   HANDLE hProcess,
  __in   LPCVOID lpBaseAddress,
  __out  LPVOID lpBuffer,
  __in   SIZE_T nSize,
  __out  SIZE_T *lpNumberOfBytesRead
);

次のようになります。

[DllImport("kernel32", EntryPoint = "ReadProcessMemory",SetLastError=true)]
private static extern unsafe bool NativeReadProcessMemory(IntPtr processHandle, IntPtr baseAddress, byte* buffer, IntPtr size, out IntPtr bytesRead);

static unsafe void ReadProcessMemory(IntPtr processHandle, IntPtr baseAddress, byte[] buffer,int start, int size)
{
    fixed(byte* pBuffer=buffer)
    {
        IntPtr bytesRead;
        if(!NativeReadProcessMemory(processHandle, baseAddress, pBuffer+start,(IntPtr)size, out bytesRead))
           throw new Win32Exception(Marshal.GetLastWin32Error());
        if((int)bytesRead!=size)
            throw new Exception("Incomplete read");//User better exception type here
    }
}
于 2012-06-29T09:48:31.437 に答える