title: ReadProcessMemory and WriteProcessMemory Gone Wrong
body: <p>I am creating this memory editor, but the subroutine ReadProcessMemory fails; so does WriteProcessMemory. I have tried to get the last error by using the GetLastError subroutine but it returns 0 which is ERROR_SUCCESS. Here is the code of both the program and the class.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using Memedit;
  using System.Runtime.InteropServices;
  namespace Memory_Editor
  {
      public partial class Form1 : Form
      {
          public Form1()
          {
              InitializeComponent();
          }
  
          private void textBox1_DragEnter(object sender, DragEventArgs e)
          {
              if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
              {
                  e.Effect = DragDropEffects.All;
              }
          }
  
          private void textBox1_DragDrop(object sender, DragEventArgs e)
          {
  
                  string[] data = e.Data.GetData(DataFormats.FileDrop, false) as string[];
                  process.Text = data[0];
  
          }
  
          private void button1_Click(object sender, EventArgs e)
          {
              MemoryEditor editor = new MemoryEditor(process.Text);
              int addr;
              if (int.TryParse(address1.Text, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out addr))
              {
                 result.Text = editor.ReadString(addr, 1000, isunicode.Checked);
              }
              else
              {
  
                  MessageBox.Show("Error: It is not a real number!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
              }
          }
  
          private void button2_Click(object sender, EventArgs e)
          {
              MemoryEditor editor = new MemoryEditor(process.Text);
              int addr;
              if (int.TryParse(address1.Text, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out addr))
              {
                  result.Text = Convert.ToString(editor.ReadInt32(addr), 16);
              }
              else
              {
                  MessageBox.Show("Error: It is not a real number!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
              }
          }
      }
  }
  </code></pre>
  
  <p>MemoryEditor Class</p>
  
  <pre><code>using System;
  using System.Text;
  using System.Collections.Generic;
  using System.Data;
  using System.Linq;
  using System.Diagnostics;
  using System.Runtime.InteropServices;
  
  namespace Memedit
  {
  
      public class MemoryEditor
      {
  
          [DllImport("kernel32.dll")]
          static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out IntPtr lpNumberOfBytesWritten);
  
          [DllImport("Kernel32.dll")]
          static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 nSize, ref UInt32 lpNumberOfBytesRead);
          string pname = "";
          IntPtr hand;
          public MemoryEditor(string ProcName)
          {
              pname = ProcName.Replace(".exe", "");
              Process[] proclist = Process.GetProcesses();
              foreach (Process pr in proclist)
              {
  
                  if (pr.ToString() == "System.Diagnostics.Process (" + pname + ")")
                  {
                      hand = pr.Handle;
                  }
              }
          }
  
          public bool Write(int Address, byte[] data)
          {
              bool success = false;
              Process[] proclist = Process.GetProcesses();
              IntPtr bytesout;
              success = WriteProcessMemory(hand, (IntPtr)Address, data, (UIntPtr)data.Length, out bytesout);
              return success;
          }
  
          public byte[] Read(int Address, int length)
          {
              byte[] ret = new byte[length];
              uint o = 0;
              ReadProcessMemory(hand, (IntPtr)Address, ret, (UInt32)ret.Length, ref o);
              return ret;
          }
          public int ReadInt32(int Address)
          {
              return BitConverter.ToInt32(Read(Address, 4), 0);
          }
          public float ReadSingle(int Address)
          {
              return BitConverter.ToSingle(Read(Address, 4), 0);
          }
          public string ReadString(int Address, int length, bool isUnicode)
          {
              if (isUnicode)
              {
                  UnicodeEncoding enc = new UnicodeEncoding();
                  return enc.GetString(Read(Address, length));
              }
              else
              {
                  ASCIIEncoding enc = new ASCIIEncoding();
                  return enc.GetString(Read(Address, length));
              }
          }
      }
  }
  </code></pre>