C#简单的跨线程内存读写库
实现x86 环境下的C#跨线程内存读写最低依赖 .net framework 2.0
使用方法和简单功能: 创建MemoryHelper的实例,然后可以读写某个内存,并且可以通过基址和偏移计算地址
```charp
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Shooan.Tools
{
#region 内存操作相关的权限 枚举
enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
#endregion
public class MemoryHelper
{
#region 内存操纵相关的库和方法
static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress,
byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);
static extern bool ReadProcessMemory(int hProcess,
int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
public void Write(int location, byte[] buffer)
{
if (IsProcessExitedOrNoExist)
{
throw new InvalidOperationException("尝试向已经关闭了的或者不存在的线程写入数据");
}
IntPtr processWriteHandle = OpenProcess((int)ProcessAccessFlags.All, false, _process.Id);
int bytesWritten = 0;
WriteProcessMemory((int)processWriteHandle, location, buffer, buffer.Length, ref bytesWritten);
}
public byte[] Read(int location, int size)
{
if (IsProcessExitedOrNoExist)
{
throw new InvalidOperationException("尝试从已经关闭了的或者不存在的线程读取数据");
}
IntPtr processReadHandle = OpenProcess((int)ProcessAccessFlags.VirtualMemoryRead, false, _process.Id);
int bytesRead = 0;
byte[] buffer = new byte;
ReadProcessMemory((int)processReadHandle, location, buffer, size, ref bytesRead);
return buffer;
}
/// <summary>
/// 传入基址和偏移,计算出最终的内存地址
/// </summary>
/// <returns>地址</returns>
public int GetLocation(int basePtr, params int[] offsets)
{
// x86 环境,一个指针大小为4个字节
const int size = 4;
byte[] buffer;
buffer = Read(basePtr, size);
int temp = BitConverter.ToInt32(buffer, 0);
for (int i = 0; i < offsets.Length-1; i++)
{
buffer = Read(temp + offsets, size);
temp = BitConverter.ToInt32(buffer, 0);
}
int finalLocation = temp + offsets;
return finalLocation;
}
#endregion
public MemoryHelper(string processName)
{
_processName = processName;
_process = null;
SetUpTimer();
}
// 用来检测线程是否退出或者不合法
public bool IsProcessExitedOrNoExist { get { return _process == null || _process.HasExited; } }
#region 内部
private string _processName;
private Process _process;
private Process GetProcess()
{
Process process = null;
try
{
process = Process.GetProcessesByName(_processName);
}
catch (IndexOutOfRangeException) { }
return process;
}
private void SetUpTimer()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += MonitorProcess;
timer.Interval = 300;
timer.Start();
}
private readonly object lockObj = new object();
private void MonitorProcess(object sender, System.Timers.ElapsedEventArgs e)
{
lock (lockObj)
{
// 检测进程是否退出,如果退出的话触发ProcessExited 事件
if (_process != null && _process.HasExited)
{
ProcessExited?.Invoke(this, new EventArgs());
_process = null;
}
Process process = GetProcess();
if (process == null)
{
return;
}
// 如果 "之前的" Process已经关闭了或者不存在,
// 并且当前获得的线程是可用的
if (IsProcessExitedOrNoExist)
{
EventArgs eventArgs = new EventArgs();
// 触发进程启动事件
ProcessStarted?.Invoke(this, eventArgs);
// 更新对象
_process = process;
}
}
}
#endregion
#region 事件
public event EventHandler ProcessStarted;
public event EventHandler ProcessExited;
#endregion
}
}
``` 马一下,内存辅助走起~~~:lol:lol 内存读写库还不错,刚刚自己试了一下,给力哈 学废了学废了(doge);www Hsm162636 发表于 2020-8-5 12:34
内存读写库还不错,刚刚自己试了一下,给力哈
谢谢支持 内存读写库还不错,刚刚自己试了一下,给力哈 受教了,学习下 是不是就可以写外挂了:Dweeqw lin326326 发表于 2020-8-5 13:43
是不是就可以写外挂了
可以实现内存挂 谢谢分享!
页:
[1]
2