ReadProcessMemory和WriteProcessMemory错了

时间:2011-08-04 02:15:15

标签: c# winapi c#-4.0 pinvoke

我正在创建这个内存编辑器,但是子程序ReadProcessMemory失败了; WriteProcessMemory也是如此。我试图通过使用GetLastError子例程获取最后一个错误,但它返回0,即ERROR_SUCCESS。这是程序和类的代码。

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")]
        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));
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

对于ReadProcessMemory,您需要PROCESS_VM_READ权限;对于WriteProcessMemory,您需要PROCESS_VM_OPERATION权限。

http://msdn.microsoft.com/en-us/library/ms680553%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/ms681674%28v=vs.85%29.aspx

您很可能需要Administrator权限,甚至可能SeDebugPrivilege(您需要提升您的流程,即使拥有管理员权限)...