Thanks for your help. I checked out the OpenProcess and ReadProcessMemory
and with a little fiddling managed to get it to read the memory. Great. Now
the problem is to see if I can alter it and write it back. I tried using
WriteProcessMemory, and I've set the DesiredAccess when opening the process
to PROCESS_VM_READ | PROCESS_VM_WRITE but it comes back with a system error
code for ERROR_ACCESS_DENIED?
Any ideas what I need to do to be able to write stuff back (if it's even
possible)? Here's my code now, it opens the process, reads 200 bytes,
displays it on the console and then tries to write the same 200 bytes back:
class Class1
{
[DllImport("Kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool
bInheritHandle, Int32 dwProcessId);
[DllImport("Kernel32.dll")]
public static extern unsafe bool ReadProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, byte* lpBuffer, int nSize, int* lpNumberOfBytesRead);
[DllImport("Kernel32.dll")]
public static extern unsafe bool WriteProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, byte* lpBuffer, int nSize, int* lpNumberOfBytesWritten);
[DllImport("Kernel32.dll")]
public static extern int GetLastError();
public static readonly int PROCESS_VM_READ = 0x0010;
public static readonly int PROCESS_VM_WRITE = 0x0020;
[STAThread]
static unsafe void Main(string[] args)
{
Process[] p = Process.GetProcessesByName("notepad");
ProcessModule pm = p[0].MainModule;
Console.WriteLine(pm.BaseAddress + ":" + p[0].Id);
byte[] buffer = new byte[200];
fixed(byte* cptr = &buffer[0])
{
int x = 0;
int* xptr = &x;
IntPtr hProcess = OpenProcess(PROCESS_VM_READ,false,p[0].Id);
Console.WriteLine(hProcess);
bool result = ReadProcessMemory(hProcess,pm.BaseAddress,cptr,200 ,xptr);
Console.WriteLine(result + ":" + x);
for (int i=0; i<200; i++)
{
byte b = *(cptr+i);
string s = b.ToString("x");
s = s.PadLeft(2,'0');
Console.Write(s + " ");
}
x = 0;
Console.WriteLine();
result = WriteProcessMemory(hProcess,pm.BaseAddress,cptr,20 0,xptr);
Console.WriteLine(result+":"+*xptr);
Console.WriteLine(GetLastError());
}
Console.ReadLine();
}
}
"Scott Allen" <bitmask@[nospam].fred.net> wrote in message
news:fu********************************@4ax.com...
Hi Matt:
Every process in Win32 has it's own address space, and actually if you
check the BaseAddress for every process on the system you'll find many
of them are the same.
To pull this off you'll need to PInvoke OpenProcess and
ReadProcessMemory. Looking those API functions up in the SDK on MSDN
will get you started. ReadProcessMemory will copy bytes from the other
process into your address space.
--
Scott
http://www.OdeToCode.com
On Mon, 16 Aug 2004 11:05:04 -0500, "Matt Burland" <wjousts@[no
spam]hotmail.com> wrote:
I am trying to read the memory being used by a process but I can't
quite figure out how to do it (or if it's even possible). I can get a
reference to the process using Process.GetProcessesByName and I can get
thebase address using Process.MainModule.BaseAddress (which returns a
IntPtr).I thought that by using IntPtr.ToPointer() and casting to a char* I would
beable to read the memory as a stream of chars but it doesn't work because
italways throws a NullReferenceException when I try and dereference the
pointer.
Can anybody help me out here?
Thanks
class Class1 { [STAThread] static unsafe void Main(string[] args) {
Process[] p = Process.GetProcessesByName("notepad"); ProcessModule pm =
p[0].MainModule; Console.WriteLine(pm.BaseAddress); char* ptr = (char*)
pm.BaseAddress.ToPointer(); char c = *ptr; // Throws
System.NullReferenceException Console.WriteLine(c);
Console.ReadLine(); } }