2012-03-03 25 views
1

我正在写一个程序,创建一个进程,然后读取他的记忆的一些位。为了得到地址,我使用了调试器OllyDbg。ReadProcessMemory与C#

using System; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace winapi 
{ 
    class Program 
    { 
     [DllImport("kernel32.dll", SetLastError = true)] 
     static extern bool ReadProcessMemory(
      IntPtr hProcess, 
      IntPtr lpBaseAddress, 
      [Out] byte[] lpBuffer, 
      int dwSize, 
      out UInt32 lpNumberOfBytesRead 
     ); 


     static void Main() 
     { 
      Console.WriteLine("WinAPI test"); 
      Console.WriteLine("---"); 
      Console.WriteLine(); 

      var startInfo = new ProcessStartInfo { FileName = "Program.exe" }; 
      Process p = Process.Start(startInfo); 
      var bytes = new byte[4]; 
      uint read = 0; 
      p.WaitForInputIdle(); 
      // 

      while (read == 0) 
      { 
       ReadProcessMemory(p.MainWindowHandle, (IntPtr)0x052f820, bytes, bytes.Length, out read);  
       System.Threading.Thread.Sleep(10); 
      } 

      Console.WriteLine(read.ToString()); 
      Console.ReadLine(); 
     } 
    } 
} 

该过程开始后,我的循环永远不会结束。 来自调试器的数据:

0052F820 | 75 2F 3F 72 61 67 65 5F 69 64 3D 31 33 

我的错误在哪里?

+0

根据文档,如果函数失败,它返回0.你没有检查返回值,你确定它是成功的吗?如果没有,我相信*它*能够告诉你你做错了什么。 – 2012-03-03 10:18:32

+0

另请注意,内存地址每次都可能完全不同。 – Deanna 2012-03-05 12:30:01

回答

2

答案已由@zmbq提供。 ReadProcessMemory不像Stream,其中每个读操作都将总读取计数添加到流位置。

我仍然可以看到与代码中的另一个问题,要传递窗口句柄代替工艺处理。所以即使你得到了结果,它实际上也不会读取你的目标进程的内存。

+1

谢谢!我将'p.MainWindowHandle'改为'p.Handle',现在它可以工作。 – Anton 2012-03-03 10:23:27

2

为什么会结束?你一遍又一遍地读取相同的4个字节。 ReadProcessMemory不像流一样工作。

+0

lpNumberOfBytesRead返回相关字节数。如果count = 0,我会再读一遍。 – Anton 2012-03-03 10:16:15