title: Why does ReadProcessMemory always return zeros?
body: <p>Given the code below, ReadProcessMemory always returns an array of zeros. I'm trying to locate a string (which may be numeric) in a running process and identify all the locations where that string exists. But ReadProcessMemory always returns an array of zeros.  Why is that?</p>
  
  <ul>
  <li>I've tried running VS as administrator and removing the unsafe block.</li>
  <li>processPointer has a correct value for the process handle.</li>
  <li>BaseAddress does correctly iterate by one, and <em>appears</em> to be the memory location I'm looking for.</li>
  <li>Despite obviously not finding any matches, it does run fairly quickly. Several seconds for a 72MB process.</li>
  </ul>
  
  <p>.</p>
  
  <pre><code>// (other stuff in method...)
  IntPtr baseAddress = process.MainModule.BaseAddress;
  IntPtr lastAddress = baseAddress + process.MainModule.ModuleMemorySize;
  processPointer = OpenProcess((uint)(0x0020), 1, (uint)PID);
  for (int addr = (int)baseAddress; addr + value.Length &lt; (int)lastAddress; addr++)
  {
      string ActualValue = ReadMemory((IntPtr)addr, (uint)value.Length, (IntPtr)addr);
      if (string.IsNullOrEmpty(ActualValue)) continue;
      if (ActualValue.Trim().ToLower() == value.Trim().ToLower())
          PossibleAddresses.Add((IntPtr)addr);
  }
  // (other stuff in method...)
  
  CloseHandle(processPointer);
  
  private string ReadMemory(IntPtr memAddress, uint size, IntPtr  BaseAddress)
  {
      byte[] buffer = new byte[size];
      IntPtr bytesRead;
      unsafe
      {
          ReadProcessMemory(processPointer, BaseAddress, buffer, size, out bytesRead);
          return BitConverter.ToString(buffer); // always "00-00-00-00....."
      }
      return Encoding.Default.GetString(buffer); // Another way I tried to read the data
  }
  
  
  [DllImport("kernel32.dll")]
  public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
  [DllImport("kernel32.dll")]
  public static extern Int32 CloseHandle(IntPtr hObject);
  [DllImport("kernel32.dll")]
  public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
  </code></pre>