新建窗体应用程序MemoryReadWriteDemo,将默认的Form1重命名为FormReadWriteMemory。窗体FormReadWriteMemory设计如下:
一、新建内存读写类MemoryUtil.cs.源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace MemoryReadWriteDemo
{
///
/// 模仿CE软件(Cheat Engine)读写单机游戏内存
///
public class MemoryUtil
{
///
///
/// 渴望得到的访问权限(标志),0x1F0FFF表示最高权限 /// 是否继承句柄 /// 进程标示符 ///
[DllImport(“kernel32.dll”, EntryPoint = “OpenProcess”)]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
///
///
/// 远程进程句柄。 被读取者 /// 远程进程中内存地址。 从具体何处读取 /// 本地进程中内存地址. 函数将读取的内容写入此处 /// 要传送的字节数。要写入多少 /// 实际传送的字节数. 函数返回时 告实际写入多少 ///
[DllImport(“kernel32.dll”, EntryPoint = “ReadProcessMemory”)]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesRead);
///
///
/// 由OpenProcess返回的进程句柄 /// 要写的内存首地址 /// 指向要写的数据的指针 /// 要写入的字节数 /// 实际数据的长度 ///
[DllImport(“kernel32.dll”, EntryPoint = “WriteProcessMemory”)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, int[] lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);
///
///
/// 欲关闭的对象句柄 [DllImport(“kernel32.dll”)]
private static extern void CloseHandle(IntPtr hObject);
///
///
/// 进程名 /// 内存地址 /// 返回的内存值 ///
public static bool ReadMemoryInt(string processName, int baseAddress, out int memoryValue)
{
memoryValue = -1;
int processId = -1;
//找出指定进程名的第一个进程
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(processName);
if (processes.Length > 0)
{
processId = processes[0].Id;
}
byte[] buffer = new byte[4];
try
{
//获取缓冲区地址 :固定数组元素的不安全地址
IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
//获取进程的最高权限
IntPtr hProcess = OpenProcess(0x1F0FFF, false, processId);
//将指定内存中的值读入缓冲区
ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero);
CloseHandle(hProcess);
memoryValue = Marshal.ReadInt32(byteAddress);
return true;
}
catch (Exception ex)
{
Console.WriteLine($”读取内存出错:{ex.Message}”);
return false;
}
}
///
///
/// 进程名 /// 内存地址 /// 写入的内存值 ///
public static bool WriteMemoryInt(string processName, int baseAddress, int memoryValue)
{
int processId = -1;
//找出指定进程名的第一个进程
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(processName);
if (processes.Length > 0)
{
processId = processes[0].Id;
}
try
{
IntPtr hProcess = OpenProcess(0x1F0FFF, false, processId); //0x1F0FFF 最高权限
WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { memoryValue }, 4, IntPtr.Zero);
CloseHandle(hProcess);
return true;
}
catch (Exception ex)
{
Console.WriteLine($”写入内存出错:{ex.Message}”);
return false;
}
}
}
}
二、FormReadWriteMemory窗体按钮绑定事件如下:(忽略设计器自动生成的代码)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MemoryReadWriteDemo
{
public partial class FormReadWriteMemory : Form
{
public FormReadWriteMemory()
{
InitializeComponent();
}
private void btnOpenProcess_Click(object sender, EventArgs e)
{
int processId = -1;
//找出指定进程名的第一个进程
string processName = txtProcessName.Text.Trim();
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(processName);
if (processes.Length > 0)
{
processId = processes[0].Id;
}
if (processId != -1)
{
MessageBox.Show($”仙剑奇侠传三游戏进程已打开,进程ID:{processId}”);
}
else
{
MessageBox.Show(“没有找到仙剑奇侠传三游戏进程!n请先打开运行游戏”);
}
}
private void btnReadMemory_Click(object sender, EventArgs e)
{
int memoryValue;
MemoryUtil.ReadMemoryInt(txtProcessName.Text.Trim(), Convert.ToInt32(txtMemoryAddress.Text.Trim(), 16), out memoryValue);
txtMemoryValueDecimal.Text = memoryValue.ToString();
txtMemoryValue.Text = memoryValue.ToString(“X8”);
MessageBox.Show($”{memoryValue}”);
}
private void btnWriteMemory_Click(object sender, EventArgs e)
{
bool result = MemoryUtil.WriteMemoryInt(txtProcessName.Text.Trim(), Convert.ToInt32(txtMemoryAddress.Text.Trim(), 16), int.Parse(txtMemoryValueDecimal.Text));
MessageBox.Show($”写入值的结果:{result}”);
}
}
}
三、程序测试运行如图:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!