返回提交历史
Modified
README.md
+59
-5
Modified
XFEExtension.NetCore.MemoryEditor/Manager/DynamicMemoryItem.cs
+1
-0
Modified
XFEExtension.NetCore.MemoryEditor/Manager/MemoryItem.cs
+18
-8
Modified
XFEExtension.NetCore.MemoryEditor/Manager/MemoryListenerManager.cs
+17
-12
Modified
XFEExtension.NetCore.MemoryEditor/Manager/StaticMemoryItem.cs
+1
-0
Modified
XFEExtension.NetCore.MemoryEditor/Manager/UpdatableMemoryItem.cs
+1
-0
Modified
XFEExtension.NetCore.MemoryEditor/MemoryEditor.cs
+7
-0
Modified
XFEExtension.NetCore.MemoryEditor/MemoryListener.cs
+12
-4
Modified
XFEExtension.NetCore.MemoryEditor/XFEExtension.NetCore.MemoryEditor.csproj
+3
-3
XFEstudio/XFEExtension.NetCore.MemoryEditor
fix-修复部分bug 完善md文档
63bc58f
代码差异
9 个文件
+119
-32
@@ -2,15 +2,29 @@
2
2
3
3
## 内存管理器
4
4
5
### 创建内存管理器(推荐使用可更新内存管理器)
5
### 内存管理器类型说明
6
7
内存管理器是本开源包中力推的类,使用内存管理器可以方便快捷的开发出基于指定偏移地址的内存修改工具
8
9
### 内存管理器类型
10
11
- 静态内存管理器`StaticMemoryManager`:在这个内存管理器中,存放静态地址,该地址不会随着进程的不同而变动,是始终如一的
12
- 动态内存管理器`DynamicMemoryManager`:在这个内存管理器中,存放的是地址的获取方法,也就是动态的,每次监听器检测地址的时候都会调用一遍该方法来获取地址
13
- 可更新内存管理器`UpdatableMemoryManager`:如其名,在此内存管理器中,存放静态地址和该地址对应的更新方法,管理器默认会在目标进程更改时调用一次该方法,当然用户也可以手动调用该方法来更新
14
15
### 内存管理器结构
16
17
内存管理器里面包含了一个内存编辑器,而内存编辑器里面则是内置了一个内存监听器管理器
18
19
### 创建内存管理器(推荐使用动态内存管理器或可更新内存管理器)
6
20
7
21
```csharp
8
22
public static class Program
9
23
{
10
public static UpdatableMemoryManager Manager { get; } = MemoryManager.CreateBuilder() //创建内存管理器的构建器
24
public static DynamicMemoryManager Manager { get; } = MemoryManager.CreateBuilder() //创建内存管理器的构建器
11
25
.WithAutoReacquireProcess("ExampleGame") //当目标进程退出后,自动重新获取目标名称的进程
12
26
.WithFindProcessWhenCreate() //创建管理器时,开始寻找目标名称的进程(如果前面设置了目标进程名称此处可以不用设置)
13
.BuildUpdatableManager(
27
.BuildDynamicManager(
14
28
MemoryItemBuilder.Create<int>("Level") //为每个地址添加一个名称
15
29
.WithResolvePointer("xxx-xxx-xx.dll", 0x0072A200, 0x14A0, 0x0, 0x80, 0xE4, 0x0, 0x1EC) //内存地址的模块名称、基址和偏移部分
16
30
.WithListener(), //添加监听器
@@ -20,7 +34,6 @@ public static class Program
20
34
MemoryItemBuilder.Create<float>("Stamina")
21
35
.WithResolvePointer("xxx-xxx-xx.dll", 0x0072A200, 0x14E0, 0x48, 0x10, 0x20, 0x50, 0x20, 0x1B0)
22
36
.WithListener());
23
//推荐使用可更新内存管理器
24
37
}
25
38
```
26
39
@@ -66,4 +79,45 @@ public partial class MainForm : Form
66
79
}
67
80
}
68
81
}
69
```
82
```
83
84
---
85
86
## 内存修改器
87
88
### 内存修改器类型说明
89
90
内存管理器可以通过类名.来调用静态方法,也可以创建对象,来针对某个进程进行内存编辑
91
92
### 内存修改器层次结构
93
94
内存管理器的实例里面内置一个内存监听器管理器
95
96
### 创建内存修改器
97
98
```csharp
99
var memoryEditor = new MemoryEditor();
100
memoryEditor.CurrentProcess = Process.GetProcessesFromName("Your Process Name");
101
var writeSuccess = memoryEditor.WriteMemory(0x007621B5, 1234);
102
var readSuccess = memoryEditor.ReadMemory<int>(0x007621B5, out var result);
103
Console.WriteLine(resule);
104
```
105
106
### 使用内存修改器(不创建实例)
107
108
```csharp
109
var writeSuccess = MemoryEditor.WriteMemory(0x00000a8c, 0x007621B5, 1234); //通过进程句柄0x00000a8c向地址0x007621B5中写入值1234
110
var readSuccess = MemoryEditor.ReadMemory<int>(0x00000a8c, 0x007621B5, out var result); //通过进程句柄0x00000a8c读取指定数据类型为int的地址0x007621B5中的值
111
```
112
113
---
114
115
## 内存监听器管理器
116
117
### 内存监听器管理器说明
118
119
推荐使用内存管理器,内存监听器管理器实际是为内存管理器服务的,当然也可以单独使用
120
121
### 内存监听器管理器层次结构
122
123
主要有一个Dictionary对象,该对象是对所有已创建监听器的管理
@@ -45,6 +45,7 @@ public abstract class DynamicMemoryItem(string name, Func<nint?> memoryAddressGe
45
45
{
46
46
if (Listener is null)
47
47
throw new InvalidOperationException($"{nameof(Listener)} 监听器为空");
48
memoryEditor.ListenerManager.IsListening = true;
48
49
await Listener.StartListen(processHandler, frequency);
49
50
}
50
51
}
@@ -3,20 +3,17 @@
3
3
/// <summary>
4
4
/// 内存条目
5
5
/// </summary>
6
/// <param name="name">名称</param>
7
/// <param name="memoryItemType">内存地址数据类型</param>
8
/// <param name="memoryEditor">修改器</param>
9
public abstract class MemoryItem(string name, Type memoryItemType, MemoryEditor memoryEditor)
6
public abstract class MemoryItem
10
7
{
11
private protected MemoryEditor memoryEditor = memoryEditor;
8
private protected MemoryEditor memoryEditor;
12
9
/// <summary>
13
10
/// 内存地址数据类型
14
11
/// </summary>
15
public Type MemoryItemType { get; set; } = memoryItemType;
12
public Type MemoryItemType { get; set; }
16
13
/// <summary>
17
14
/// 内存地址标识名
18
15
/// </summary>
19
public string Name { get; init; } = name;
16
public string Name { get; init; }
20
17
/// <summary>
21
18
/// 该地址是否被监听
22
19
/// </summary>
@@ -29,7 +26,7 @@ public abstract class MemoryItem(string name, Type memoryItemType, MemoryEditor
29
26
/// 开始监听该地址
30
27
/// </summary>
31
28
/// <param name="frequency">监听频率,单位为毫秒</param>
32
public async Task StartListen(int frequency = 1) => await StartListen(TimeSpan.FromMilliseconds(frequency));
29
public async Task StartListen(int frequency) => await StartListen(TimeSpan.FromMilliseconds(frequency));
33
30
/// <summary>
34
31
/// 开始监听该地址
35
32
/// </summary>
@@ -81,4 +78,17 @@ public abstract class MemoryItem(string name, Type memoryItemType, MemoryEditor
81
78
/// <param name="result">读取的值</param>
82
79
/// <returns>是否读取成功</returns>
83
80
public abstract bool Read<T>(out T result) where T : struct;
81
/// <summary>
82
/// 内存条目
83
/// </summary>
84
/// <param name="name">名称</param>
85
/// <param name="memoryItemType">内存地址数据类型</param>
86
/// <param name="memoryEditor">修改器</param>
87
protected MemoryItem(string name, Type memoryItemType, MemoryEditor memoryEditor)
88
{
89
this.memoryEditor = memoryEditor;
90
MemoryItemType = memoryItemType;
91
Name = name;
92
memoryEditor.ListeningStateChanged += (sender, e) => IsListening = e;
93
}
84
94
}
@@ -16,6 +16,10 @@ public class MemoryListenerManager : MemoryListenerManagerBase, IDisposable, IEn
16
16
/// </summary>
17
17
public event XFEEventHandler<MemoryListener, MemoryValue>? ValueChanged;
18
18
/// <summary>
19
/// 当监听器监听状态改变时触发
20
/// </summary>
21
public event XFEEventHandler<MemoryListener, bool>? ListeningStateChanged;
22
/// <summary>
19
23
/// 当前进程结束时触发
20
24
/// </summary>
21
25
public event EventHandler? CurrentProcessExit;
@@ -53,17 +57,15 @@ public class MemoryListenerManager : MemoryListenerManagerBase, IDisposable, IEn
53
57
ProcessName = value.ProcessName;
54
58
ProcessHandler = MemoryEditor.GetProcessHandle(value.Id, ProcessAccessFlags);
55
59
currentProcess.Exited += CurrentProcess_Exited;
56
if (IsListening)
60
61
foreach (var listener in listenerDictionary.Values)
57
62
{
58
foreach (var listener in listenerDictionary.Values)
63
if (listener is UpdatableMemoryListener updatableMemoryListener)
64
updatableMemoryListener.UpdateAddress(ProcessHandler);
65
listener.ProcessHandler = ProcessHandler;
66
if (IsListening && !listener.IsListening)
59
67
{
60
if (listener is UpdatableMemoryListener updatableMemoryListener)
61
updatableMemoryListener.UpdateAddress(ProcessHandler);
62
if (!listener.IsListening)
63
{
64
listener.ProcessHandler = ProcessHandler;
65
_ = listener.StartListen(ProcessHandler, listener.Frequency);
66
}
68
_ = listener.StartListen(ProcessHandler, listener.Frequency);
67
69
}
68
70
}
69
71
CurrentProcessEntered?.Invoke(value, EventArgs.Empty);
@@ -105,33 +107,36 @@ public class MemoryListenerManager : MemoryListenerManagerBase, IDisposable, IEn
105
107
}
106
108
internal override StaticMemoryListener AddStaticListener(string customName, nint memoryAddress, TimeSpan? frequency, Type type, bool startListen)
107
109
{
108
if (!IsListening)
110
if (!IsListening && startListen)
109
111
IsListening = true;
110
112
var staticMemoryListener = MemoryListener.CreateStaticListener(customName, memoryAddress, type);
111
113
listenerDictionary.Add(customName, staticMemoryListener);
112
114
staticMemoryListener.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
115
staticMemoryListener.ListeningStateChanged += (sender, e) => ListeningStateChanged?.Invoke(sender, e);
113
116
if (startListen)
114
117
_ = staticMemoryListener.StartListen(ProcessHandler, frequency);
115
118
return staticMemoryListener;
116
119
}
117
120
internal override DynamicMemoryListener AddDynamicListener(string customName, Func<nint?> memoryAddressGetFunc, TimeSpan? frequency, Type type, bool startListen)
118
121
{
119
if (!IsListening)
122
if (!IsListening && startListen)
120
123
IsListening = true;
121
124
var dynamicMemoryListener = MemoryListener.CreateDynamicListener(customName, memoryAddressGetFunc, type);
122
125
listenerDictionary.Add(customName, dynamicMemoryListener);
123
126
dynamicMemoryListener.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
127
dynamicMemoryListener.ListeningStateChanged += (sender, e) => ListeningStateChanged?.Invoke(sender, e);
124
128
if (startListen)
125
129
_ = dynamicMemoryListener.StartListen(ProcessHandler, frequency);
126
130
return dynamicMemoryListener;
127
131
}
128
132
internal override UpdatableMemoryListener AddUpdatableListener(string customName, Func<nint?> memoryAddressUpdateFunc, TimeSpan? frequency, Type type, bool startListen)
129
133
{
130
if (!IsListening)
134
if (!IsListening && startListen)
131
135
IsListening = true;
132
136
var updatableMemoryListener = MemoryListener.CreateUpdatableListener(customName, memoryAddressUpdateFunc, type);
133
137
listenerDictionary.Add(customName, updatableMemoryListener);
134
138
updatableMemoryListener.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
139
updatableMemoryListener.ListeningStateChanged += (sender, e) => ListeningStateChanged?.Invoke(sender, e);
135
140
if (startListen)
136
141
_ = updatableMemoryListener.StartListen(ProcessHandler, frequency);
137
142
return updatableMemoryListener;
@@ -45,6 +45,7 @@ public abstract class StaticMemoryItem(string name, nint memoryAddress, Type mem
45
45
{
46
46
if (Listener is null)
47
47
throw new InvalidOperationException($"{nameof(Listener)} 监听器为空");
48
memoryEditor.ListenerManager.IsListening = true;
48
49
await Listener.StartListen(processHandler, frequency);
49
50
}
50
51
}
@@ -83,6 +83,7 @@ public abstract class UpdatableMemoryItem(string name, Func<nint?> memoryAddress
83
83
{
84
84
if (Listener is null)
85
85
throw new InvalidOperationException($"{nameof(Listener)} 监听器为空");
86
memoryEditor.ListenerManager.IsListening = true;
86
87
await Listener.StartListen(processHandler, frequency);
87
88
}
88
89
}
@@ -17,6 +17,10 @@ public partial class MemoryEditor : MemoryListenerManagerBase, IDisposable
17
17
/// </summary>
18
18
public event XFEEventHandler<MemoryListener, MemoryValue>? ValueChanged;
19
19
/// <summary>
20
/// 当监听器监听状态改变时触发
21
/// </summary>
22
public event XFEEventHandler<MemoryListener, bool>? ListeningStateChanged;
23
/// <summary>
20
24
/// 当前进程结束时触发
21
25
/// </summary>
22
26
public event EventHandler? CurrentProcessExit;
@@ -127,6 +131,7 @@ public partial class MemoryEditor : MemoryListenerManagerBase, IDisposable
127
131
CurrentProcess = process;
128
132
ProcessBiteType = processType;
129
133
ListenerManager.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
134
ListenerManager.ListeningStateChanged += (sender, e) => ListeningStateChanged?.Invoke(sender, e);
130
135
ListenerManager.CurrentProcessExit += (sender, e) => CurrentProcessExit?.Invoke(sender, e);
131
136
ListenerManager.CurrentProcessEntered += (sender, e) => CurrentProcessEntered?.Invoke(sender, e);
132
137
}
@@ -140,6 +145,7 @@ public partial class MemoryEditor : MemoryListenerManagerBase, IDisposable
140
145
CurrentProcess = Process.GetProcessesByName(processName).First();
141
146
ProcessBiteType = processType;
142
147
ListenerManager.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
148
ListenerManager.ListeningStateChanged += (sender, e) => ListeningStateChanged?.Invoke(sender, e);
143
149
ListenerManager.CurrentProcessExit += (sender, e) => CurrentProcessExit?.Invoke(sender, e);
144
150
ListenerManager.CurrentProcessEntered += (sender, e) => CurrentProcessEntered?.Invoke(sender, e);
145
151
}
@@ -153,6 +159,7 @@ public partial class MemoryEditor : MemoryListenerManagerBase, IDisposable
153
159
CurrentProcess = Process.GetProcessById(processId);
154
160
ProcessBiteType = processType;
155
161
ListenerManager.ValueChanged += (sender, e) => ValueChanged?.Invoke(sender, e);
162
ListenerManager.ListeningStateChanged += (sender, e) => ListeningStateChanged?.Invoke(sender, e);
156
163
ListenerManager.CurrentProcessExit += (sender, e) => CurrentProcessExit?.Invoke(sender, e);
157
164
ListenerManager.CurrentProcessEntered += (sender, e) => CurrentProcessEntered?.Invoke(sender, e);
158
165
}
@@ -1,5 +1,4 @@
1
using System.Diagnostics;
2
using XFEExtension.NetCore.DelegateExtension;
1
using XFEExtension.NetCore.DelegateExtension;
3
2
4
3
namespace XFEExtension.NetCore.MemoryEditor;
5
4
@@ -17,12 +16,21 @@ public abstract class MemoryListener(string customName, Type memoryAddressType)
17
16
/// 当监听值发生改变时触发
18
17
/// </summary>
19
18
public event XFEEventHandler<MemoryListener, MemoryValue>? ValueChanged { add => valueChanged += value; remove => valueChanged -= value; }
19
private protected XFEEventHandler<MemoryListener, bool>? listeningStateChanged;
20
/// <summary>
21
/// 当监听状态改变时触发
22
/// </summary>
23
public event XFEEventHandler<MemoryListener, bool>? ListeningStateChanged
24
{
25
add => listeningStateChanged += value;
26
remove => listeningStateChanged -= value;
27
}
20
28
private protected string name = customName;
21
29
/// <summary>
22
30
/// 监听器自定义标识名
23
31
/// </summary>
24
32
public string Name { get => name; }
25
private protected TimeSpan frequency;
33
private protected TimeSpan frequency = TimeSpan.FromMilliseconds(1);
26
34
/// <summary>
27
35
/// 监听检测频率
28
36
/// </summary>
@@ -38,7 +46,7 @@ public abstract class MemoryListener(string customName, Type memoryAddressType)
38
46
public bool IsListening
39
47
{
40
48
get { return isListening; }
41
set { isListening = value; }
49
set { isListening = value; listeningStateChanged?.Invoke(this, value); }
42
50
}
43
51
private protected nint processHandler;
44
52
/// <summary>
@@ -13,13 +13,13 @@
13
13
<PackageReadmeFile>README.md</PackageReadmeFile>
14
14
<RepositoryUrl>https://github.com/XFEstudio/XFEExtension.NetCore.MemoryEditor.git</RepositoryUrl>
15
15
<PackageTags>XFE;XFEExtension;MemoryEdit;Memory</PackageTags>
16
<PackageReleaseNotes>fix-修复了基址解析表达式可能会出现的报错</PackageReleaseNotes>
16
<PackageReleaseNotes>fix-修复了部分bug</PackageReleaseNotes>
17
17
<Copyright>寰宇朽力网络科技版权所有</Copyright>
18
18
<PackageProjectUrl>https://github.com/XFEstudio/XFEExtension.NetCore.MemoryEditor.git</PackageProjectUrl>
19
19
<GenerateDocumentationFile>True</GenerateDocumentationFile>
20
20
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
21
21
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
22
<Version>2.0.1</Version>
22
<Version>2.0.2</Version>
23
23
</PropertyGroup>
24
24
25
25
<ItemGroup>
@@ -38,7 +38,7 @@
38
38
</ItemGroup>
39
39
40
40
<ItemGroup>
41
<PackageReference Include="XFEExtension.NetCore" Version="2.7.1" />
41
<PackageReference Include="XFEExtension.NetCore" Version="2.9.1" />
42
42
</ItemGroup>
43
43
44
44
</Project>