I've tried running this with Process.EnterDebugMode()
, but it also doesn't work.
I want to read out the Notepad-memory
but I don't know how to access it, or if the 64bit system is doing troubles.
This is what I've done:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
public class MemoryRead
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(int hProcess, Int64 lpBaseAddress, byte[] buffer, int size, ref int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr hObject);
static void Main(string[] args)
{
var pid = 10956; //notepad.exe
var processHandle = OpenProcess(0x10, false, pid);
byte[] buffer = new byte[24];
int bytesRead = 0;
ReadProcessMemory((int)processHandle, 0x21106B35770, buffer, buffer.Length, ref bytesRead); //0x21106B35770 is the address where "hello world" is written in notepad
Console.WriteLine(Encoding.Unicode.GetString(buffer) +
" (" + bytesRead.ToString() + "bytes)");
Console.ReadLine();
CloseHandle(processHandle);
Console.ReadLine();
}
}
Your PInvoke declaration of ReadProcessMemory is incorrect (though it should work on a 32 bit system).
As can be seen from the native declaration of this function
BOOL WINAPI ReadProcessMemory(
_In_ HANDLE hProcess,
_In_ LPCVOID lpBaseAddress,
_Out_ LPVOID lpBuffer,
_In_ SIZE_T nSize,
_Out_ SIZE_T *lpNumberOfBytesRead
);
its first parameter is HANDLE
, and it is a PVOID
:
A pointer to any type.
This type is declared in WinNT.h as follows:
typedef void *PVOID;
And pointer to anything in 64-bit process is a 64-bit value - IntPtr.
Basically the same goes to the size
and lpNumberOfBytesRead
parameters - they are 64 bit as well in a 64 bit process.
Thus your declaration should be something like:
[[DllImport("kernel32.dll", SetLastError = true)]]
[return: MarshalAs(UnmanagedType.Bool)]
static extern Boolean ReadProcessMemory(
[In] IntPtr hProcess,
[In] IntPtr lpBaseAddress,
[Out] Byte[] lpBuffer,
[In] UIntPtr nSize,
[Out] out UIntPtr lpNumberOfBytesRead
);
P.S.: And a bit of shameless self-promotion - if you ever have to work a lot with PInvoke, then there are a few good recommendations I've learned a hard way.