XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.MemoryEditor

【DLL】内存读写工具/编辑器

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.MemoryEditor

添加监听器功能

7d2b0a8
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

2 个文件 +156 -0
Modified XFEExtension.NetCore.MemoryEditor/MemoryEditor.cs +26 -0
@@ -1,4 +1,5 @@
1 1 using System.Diagnostics;
2 using System.Net;
2 3 using System.Runtime.InteropServices;
3 4 using XFEExtension.NetCore.DelegateExtension;
4 5
@@ -22,6 +23,10 @@ public partial class MemoryEditor
22 23 /// </summary>
23 24 public nint ProcessHandle { get; set; }
24 25 /// <summary>
26 /// 内存监听器
27 /// </summary>
28 public MemoryListener Listener { get; set; }
29 /// <summary>
25 30 /// 进程位数类型(32/64)
26 31 /// </summary>
27 32 public ProcessType ProcessBiteType { get; set; }
@@ -40,6 +45,21 @@ public partial class MemoryEditor
40 45 /// <param name="source">待写入值</param>
41 46 public void WriteMemory<T>(nint address, T source) where T : struct => WriteMemory<T>(ProcessHandle, address, source);
42 47 /// <summary>
48 /// 添加监听器
49 /// </summary>
50 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
51 /// <param name="address">待监听的内存地址</param>
52 public void AddListener<T>(nint address) where T : struct => _ = Listener.StartListen<T>(address);
53 /// <summary>
54 /// 移除并停止指定监听器
55 /// </summary>
56 /// <param name="address">监听地址</param>
57 public void RemoveListener(nint address) => Listener.StopListener(address);
58 /// <summary>
59 /// 移除所有监听器
60 /// </summary>
61 public void RemoveListeners()=> Listener.StopListener();
62 /// <summary>
43 63 /// 解析基址对应的实际地址
44 64 /// </summary>
45 65 /// <param name="moduleName">模块名称(基址的进程部分,可以是DLL等)</param>
@@ -58,6 +78,8 @@ public partial class MemoryEditor
58 78 TargetProcess = process;
59 79 ProcessHandle = GetProcessHandle(TargetProcess.Id, processAccessFlags);
60 80 ProcessBiteType = processType;
81 Listener = new(ProcessHandle);
82 Listener.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
61 83 }
62 84 /// <summary>
63 85 /// 内存编辑器
@@ -70,6 +92,8 @@ public partial class MemoryEditor
70 92 TargetProcess = Process.GetProcessesByName(processName).First();
71 93 ProcessHandle = GetProcessHandle(TargetProcess.Id, processAccessFlags);
72 94 ProcessBiteType = processType;
95 Listener = new(ProcessHandle);
96 Listener.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
73 97 }
74 98 /// <summary>
75 99 /// 内存编辑器
@@ -82,6 +106,8 @@ public partial class MemoryEditor
82 106 TargetProcess = Process.GetProcessById(processId);
83 107 ProcessHandle = GetProcessHandle(TargetProcess.Id, processAccessFlags);
84 108 ProcessBiteType = processType;
109 Listener = new(ProcessHandle);
110 Listener.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
85 111 }
86 112 #region 静态方法
87 113 /// <summary>
Added XFEExtension.NetCore.MemoryEditor/MemoryListener.cs +130 -0
@@ -0,0 +1,130 @@
1 using XFEExtension.NetCore.DelegateExtension;
2
3 namespace XFEExtension.NetCore.MemoryEditor;
4
5 /// <summary>
6 /// 内存监听器
7 /// </summary>
8 public class MemoryListener : IDisposable
9 {
10 private bool disposedValue;
11 private readonly Dictionary<nint, bool> listeningList = [];
12 /// <summary>
13 /// 当监听值发生改变时触发
14 /// </summary>
15 public event XFEEventHandler<nint, object>? ValueChanged;
16 /// <summary>
17 /// 进程句柄
18 /// </summary>
19 public nint ProcessHandler { get; set; }
20 /// <summary>
21 /// 是否启用监听
22 /// </summary>
23 public bool IsListening { get; set; }
24 /// <summary>
25 /// 开始监听
26 /// </summary>
27 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
28 /// <param name="memoryAddress">待监听的内存地址</param>
29 /// <returns></returns>
30 public async Task StartListen<T>(nint memoryAddress) where T : struct
31 {
32 IsListening = true;
33 listeningList.Add(memoryAddress, true);
34 await Task.Run(() =>
35 {
36 var lastValue = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress);
37 while (listeningList[memoryAddress] && IsListening)
38 {
39 var currentValue = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress);
40 if (!currentValue.Equals(lastValue))
41 {
42 ValueChanged?.Invoke(ProcessHandler, currentValue);
43 currentValue = lastValue;
44 }
45 }
46 listeningList.Remove(memoryAddress);
47 });
48 }
49 /// <summary>
50 /// 开始监听
51 /// </summary>
52 /// <typeparam name="T">待监听的内存的数据类型(int,float,long等)</typeparam>
53 /// <param name="memoryAddress">待监听的内存地址</param>
54 /// <param name="delay">检测频率,以毫秒为单位</param>
55 /// <returns></returns>
56 public async Task StartListen<T>(nint memoryAddress, int delay = 10) where T : struct
57 {
58 IsListening = true;
59 listeningList.Add(memoryAddress, true);
60 await Task.Run(() =>
61 {
62 var lastValue = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress);
63 while (listeningList[memoryAddress] && IsListening)
64 {
65 var currentValue = MemoryEditor.ReadMemory<T>(ProcessHandler, memoryAddress);
66 if (!currentValue.Equals(lastValue))
67 {
68 ValueChanged?.Invoke(ProcessHandler, currentValue);
69 currentValue = lastValue;
70 }
71 Thread.Sleep(delay);
72 }
73 listeningList.Remove(memoryAddress);
74 });
75 }
76 /// <summary>
77 /// 停止所有监听
78 /// </summary>
79 public void StopListener() => IsListening = false;
80 /// <summary>
81 /// 停止指定进程的监听
82 /// </summary>
83 /// <param name="memoryAddress"></param>
84 public void StopListener(nint memoryAddress) => listeningList[memoryAddress] = false;
85 /// <summary>
86 /// 内存监听器
87 /// </summary>
88 /// <param name="processName">进程名称</param>
89 public MemoryListener(string processName) => ProcessHandler = MemoryEditor.GetProcessHandle(processName, ProcessAccessFlags.All);
90 /// <summary>
91 /// 内存监听器
92 /// </summary>
93 /// <param name="processHandler">进程句柄</param>
94 public MemoryListener(nint processHandler) => ProcessHandler = processHandler;
95 /// <summary>
96 /// 释放资源
97 /// </summary>
98 /// <param name="disposing"></param>
99 protected virtual void Dispose(bool disposing)
100 {
101 if (!disposedValue)
102 {
103 if (disposing)
104 {
105 IsListening = false;
106 }
107
108 // TODO: 释放未托管的资源(未托管的对象)并重写终结器
109 // TODO: 将大型字段设置为 null
110 disposedValue = true;
111 }
112 }
113
114 // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
115 // ~MemoryListener()
116 // {
117 // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
118 // Dispose(disposing: false);
119 // }
120
121 /// <summary>
122 /// 释放资源
123 /// </summary>
124 public void Dispose()
125 {
126 // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
127 Dispose(disposing: true);
128 GC.SuppressFinalize(this);
129 }
130 }