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.
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);
}
}
}
}
MemoryEditor Class
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"开发者_如何学Go)]
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));
}
}
}
}
For ReadProcessMemory
you need PROCESS_VM_READ
permission and for WriteProcessMemory
you need PROCESS_VM_OPERATION
permission.
see http://msdn.microsoft.com/en-us/library/ms680553%28v=vs.85%29.aspx
and http://msdn.microsoft.com/en-us/library/ms681674%28v=vs.85%29.aspx
Very likely you need Administrator
rights, perhaps even SeDebugPrivilege
(which you would need to elevate your process to even with Administrator rights)...
精彩评论