电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

“扫雷”游戏地幕后2


发布日期:2019/7/7
 

IntPtr lpBaseAddress

[In Out] byte[] buffer

UInt size

out IntPtr lpNumberOfBytesRead

);

[DllImport(\kerneldll\)] public static extern Int CloseHandle(

IntPtr hObject

);

如果你想知道在c++和c#之间有关类型转换的更多信息我建议你从站点搜索此话题Marshaling Data with Platform Invoke 基本上 如果你把逻辑上是正确的程序搁在那儿 它便能运行 但有时还需要一点点的调整

在声明了这些函数之后我要做的是用一个简单的类把它们包装起来并使用这个类我把声明放在一个叫做ProcessMemoryReaderApi的类中这样做更有条有理主要的实用类称为ProcessMemoryReade这个类有一个ReadProcess属性它源于SystemDiagnosticsProcess类型用于存放你要读取其内存的进程类中有一个方法用来以读模式打开进程

public void OpenProcess()

{

m_hProcess = ProcessMemoryReaderApiOpenProcess(

ProcessMemoryReaderApiPROCESS_VM_READ

(uint)m_ReadProcessId);

}

PROCESS_VM_READ 常量告诉系统以读模式打开进程 而m_ReadProcessId 声明了我要打开的是什么进程

在该类中最重要的是一个方法它从进程中读取内存

public byte[] ReadProcessMemory(IntPtr MemoryAddress uint bytesToRead

out int bytesReaded)

{

byte[] buffer = new byte[bytesToRead];

IntPtr ptrBytesReaded;

ProcessMemoryReaderApiReadProcessMemory(m_hProcessMemoryAddressbuffer

bytesToReadout ptrBytesReaded);

bytesReaded = ptrBytesReadedToInt();

return buffer;

}

这个函数以所请求的大小声明一个字节数组并使用API读取内存就这么简单!

最后下面这个方法关闭了进程

public void CloseHandle()

{

int iRetValue;

iRetValue = ProcessMemoryReaderApiCloseHandle(m_hProcess);

if (iRetValue == )

throw new Exception(\CloseHandle failed\);

}

第三步 – 使用类

现在轮到了有趣的部分使用这个类就是为了读取扫雷的内存并揭开布雷图要使用类需要先对其进行初始化

ProcessMemoryReaderLibProcessMemoryReader pReader

= new ProcessMemoryReaderLibProcessMemoryReader();

接着必须设置你想要读取其内存的进程以下是如何获得扫雷进程的例子这个进程一旦被装入就被设置为ReadProcess属性

SystemDiagnosticsProcess[] myProcesses

; = SystemDiagnosticsProcessGetProcessesByName(\winmine\);

pReaderReadProcess = myProcesses[];

我们现在需要做的是打开进程读取内存并在完成后关闭它下面还是有关操作的例子它读取代表布雷图宽度的地址

pReaderOpenProcess();

int iWidth;

byte[] memory;

memory = pReaderReadProcessMemory((IntPtr)xout bytesReaded);

iWidth = memory[];

pReaderCloseHandle();

简单吧!

在结论部分我列出了显示布雷图的完整代码别忘了我要访问的所有内存位置就是在本文第一部分中所找到位置

// 布雷图的资料管理器

SystemResourcesResourceManager resources = new SystemResourcesResourceManager(typeof(Form));

ProcessMemoryReaderLibProcessMemoryReader pReader

= new ProcessMemoryReaderLibProcessMemoryReader();

SystemDiagnosticsProcess[] myProcesses

= SystemDiagnosticsProcessGetProcessesByName(\winmine\);

// 获得扫雷进程的第一个实列

if (myProcessesLength == )

{

MessageBoxShow(\No MineSweeper process found!\);

return;

}

pReaderReadProcess = myProcesses[];

// 以读内存模式打开进程

pReaderOpenProcess();

int bytesReaded;

int iWidth iHeight iMines;

int iIsMine;

int iCellAddress;

byte[] memory;

memory = pReaderReadProcessMemory((IntPtr)xout bytesReaded);

iWidth = memory[];

txtWidthText = iWidthToString();

memory = pReaderReadProcessMemory((IntPtr)xout bytesReaded);

iHeight = memory[];

txtHeightText = iHeightToString();

memory = pReaderReadProcessMemory((IntPtr)xout bytesReaded);

iMines = memory[];

txtMinesText = iMinesToString();

// 删除以前的按钮数组

thisControlsClear();

thisControlsAddRange(MainControls);

// 创建一个按钮数组 用于画出布雷图的每一格

ButtonArray = new SystemWindowsFormsButton[iWidthiHeight];

int xy;

for (y= ; y<iHeight ; y++)

for (x= ; x<iWidth ; x++)

{

ButtonArray[xy] = new SystemWindowsFormsButton();

ButtonArray[xy]Location = new SystemDrawingPoint( + x* + y*);

ButtonArray[xy]Name = \\;

ButtonArray[xy]Size = new SystemDrawingSize();

iCellAddress = (x) + ( * (y+)) + (x+);

memory = pReaderReadProcessMemory((IntPtr)iCellAddressout bytesReaded);

iIsMine = memory[];

if (iIsMine == xf)//如果有雷则画出地雷位图

ButtonArray[xy]Image = ((SystemDrawingBitmap)

(resourcesGetObject(\buttonImage\)));

thisControlsAdd(ButtonArray[xy]);

}

// 关闭进程句柄

pReaderCloseHandle();

就是这些希望你能学到新的东西

上一篇:利用窗体的自定义属性实现窗体传值

下一篇:在VC中怎样实现软件的注册机制