IntPtr lpBaseAddress,
[In, Out] byte[] buffer,
UInt32 size,
out IntPtr lpNumberOfBytesRead
);
[DllImport(\"kernel32.dll\")] public static extern Int32 CloseHandle(
IntPtr hObject
);
如果你想知道在c++和c#之间有关类型转换的更多信息,我建议你从msdn.microsoft.com站点搜索此话题:“Marshaling Data with Platform Invoke”。 基本上, 如果你把逻辑上是正确的程序搁在那儿, 它便能运行, 但有时还需要一点点的调整。
在声明了这些函数之后,我要做的是用一个简单的类把它们包装起来,并使用这个类。我把声明放在一个叫做ProcessMemoryReaderApi的类中,这样做更有条有理。主要的实用类称为ProcessMemoryReade。这个类有一个ReadProcess属性,它源于System.Diagnostics.Process类型,用于存放你要读取其内存的进程。类中有一个方法,用来以读模式打开进程。
public void OpenProcess()
{
m_hProcess = ProcessMemoryReaderApi.OpenProcess(
ProcessMemoryReaderApi.PROCESS_VM_READ, 1,
(uint)m_ReadProcess.Id);
}
PROCESS_VM_READ 常量告诉系统以读模式打开进程, 而m_ReadProcess.Id 声明了我要打开的是什么进程。
在该类中最重要的是一个方法,它从进程中读取内存:
public byte[] ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead,
out int bytesReaded)
{
byte[] buffer = new byte[bytesToRead];
IntPtr ptrBytesReaded;
ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess,MemoryAddress,buffer,
bytesToRead,out ptrBytesReaded);
bytesReaded = ptrBytesReaded.ToInt32();
return buffer;
}
这个函数以所请求的大小声明一个字节数组,并使用API读取内存。就这么简单!
最后,下面这个方法关闭了进程。
public void CloseHandle()
{
int iRetValue;
iRetValue = ProcessMemoryReaderApi.CloseHandle(m_hProcess);
if (iRetValue == 0)
throw new Exception(\"CloseHandle failed\");
}
第三步 – 使用类
现在轮到了有趣的部分。使用这个类就是为了读取“扫雷”的内存并揭开布雷图。要使用类,需要先对其进行初始化:
ProcessMemoryReaderLib.ProcessMemoryReader pReader
= new ProcessMemoryReaderLib.ProcessMemoryReader();
接着,必须设置你想要读取其内存的进程。以下是如何获得“扫雷”进程的例子,这个进程一旦被装入,就被设置为ReadProcess属性:
System.Diagnostics.Process[] myProcesses
; = System.Diagnostics.Process.GetProcessesByName(\"winmine\");
pReader.ReadProcess = myProcesses[0];
我们现在需要做的是:打开进程,读取内存,并在完成后关闭它。下面还是有关操作的例子,它读取代表布雷图宽度的地址。