熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

“掃雷”游戲地幕後2

2013-11-13 09:58:08  來源: .NET編程 

  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();

  就是這些希望你能學到新的東西


From:http://tw.wingwit.com/Article/program/net/201311/12142.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.