返回提交历史
Modified
XFEExtension.NetCore.MemoryEditor/MemoryEditor.cs
+136
-43
Modified
XFEExtension.NetCore.MemoryEditor/ProcessAccessFlags.cs
+42
-0
Added
XFEExtension.NetCore.MemoryEditor/ProcessType.cs
+7
-0
Modified
XFEExtension.NetCore.MemoryEditor/XFEExtension.NetCore.MemoryEditor.csproj
+19
-0
Added
logoIcon.png
+0
-0
XFEstudio/XFEExtension.NetCore.MemoryEditor
完善主体
9b69da7
代码差异
5 个文件
+204
-43
@@ -3,20 +3,64 @@ using System.Runtime.InteropServices;
3
3
4
4
namespace XFEExtension.NetCore.MemoryEditor;
5
5
6
/// <summary>
7
/// 内存编辑器
8
/// </summary>
6
9
public partial class MemoryEditor
7
10
{
8
#region DLL引用
9
[LibraryImport("kernel32.dll")]
10
internal static partial nint OpenProcess(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
11
12
[LibraryImport("kernel32.dll", SetLastError = true)]
13
[return: MarshalAs(UnmanagedType.Bool)]
14
internal static partial bool WriteProcessMemory(nint hProcess, nint lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
15
16
[LibraryImport("kernel32.dll")]
17
[return: MarshalAs(UnmanagedType.Bool)]
18
internal static partial bool ReadProcessMemory(nint hProcess, nint lpBaseAddress, [Out] byte[] lpBuffer, uint dwSize, out int lpNumberOfBytesRead);
19
#endregion
11
/// <summary>
12
/// 目标进程
13
/// </summary>
14
public Process TargetProcess { get; set; }
15
/// <summary>
16
/// 进程句柄
17
/// </summary>
18
public nint ProcessHandle { get; set; }
19
/// <summary>
20
/// 读取指定地址的内存
21
/// </summary>
22
/// <typeparam name="T">目标类型(int,float,long等)</typeparam>
23
/// <param name="address">指定地址</param>
24
/// <returns></returns>
25
public T ReadMemory<T>(nint address) where T : struct => ReadMemory<T>(ProcessHandle, address);
26
/// <summary>
27
/// 在指定内存地址中写入数据
28
/// </summary>
29
/// <typeparam name="T">数据类型(int,float,long等)</typeparam>
30
/// <param name="address">目标地址</param>
31
/// <param name="source">待写入值</param>
32
public void WriteMemory<T>(nint address, T source) where T : struct => WriteMemory<T>(ProcessHandle, address, source);
33
/// <summary>
34
/// 内存编辑器
35
/// </summary>
36
/// <param name="process"></param>
37
/// <param name="processAccessFlags">进程权限</param>
38
public MemoryEditor(Process process, ProcessAccessFlags processAccessFlags = ProcessAccessFlags.All)
39
{
40
TargetProcess = process;
41
ProcessHandle = GetProcessHandle(TargetProcess.Id, processAccessFlags);
42
}
43
/// <summary>
44
/// 内存编辑器
45
/// </summary>
46
/// <param name="processName"></param>
47
/// <param name="processAccessFlags">进程权限</param>
48
public MemoryEditor(string processName, ProcessAccessFlags processAccessFlags = ProcessAccessFlags.All)
49
{
50
TargetProcess = Process.GetProcessesByName(processName).First();
51
ProcessHandle = GetProcessHandle(TargetProcess.Id, processAccessFlags);
52
}
53
/// <summary>
54
/// 内存编辑器
55
/// </summary>
56
/// <param name="processId"></param>
57
/// <param name="processAccessFlags">进程权限</param>
58
public MemoryEditor(int processId, ProcessAccessFlags processAccessFlags = ProcessAccessFlags.All)
59
{
60
TargetProcess = Process.GetProcessById(processId);
61
ProcessHandle = GetProcessHandle(TargetProcess.Id, processAccessFlags);
62
}
63
#region 静态方法
20
64
/// <summary>
21
65
/// 获取程序句柄
22
66
/// </summary>
@@ -31,20 +75,26 @@ public partial class MemoryEditor
31
75
/// <summary>
32
76
/// 获取程序句柄
33
77
/// </summary>
34
///
78
/// <param name="processName">进程名称</param>
35
79
/// <param name="flags">权限</param>
36
80
/// <returns></returns>
37
81
public static nint GetProcessHandle(string processName, ProcessAccessFlags flags)
38
82
{
39
nint processHandle = OpenProcess((int)flags, false, processId);
83
nint processHandle = OpenProcess((int)flags, false, Process.GetProcessesByName(processName).First().Id);
40
84
return processHandle;
41
85
}
42
86
/// <summary>
87
/// 读取指定地址的内存
88
/// </summary>
89
/// <typeparam name="T">目标类型(int,float,long等)</typeparam>
90
/// <param name="processHandle">进程句柄</param>
91
/// <param name="address">指定地址</param>
92
/// <returns></returns>
43
93
public static T ReadMemory<T>(nint processHandle, nint address) where T : struct
44
94
{
45
95
unsafe
46
96
{
47
var size = sizeof(T);
97
var size = Marshal.SizeOf<T>();
48
98
var buffer = new byte[size];
49
99
ReadProcessMemory(processHandle, address, buffer, (uint)size, out _);
50
100
fixed (byte* pBuffer = buffer)
@@ -53,55 +103,98 @@ public partial class MemoryEditor
53
103
}
54
104
}
55
105
}
56
57
// 写入进程内存
58
public static void WriteMemory(nint processHandle, nint address, byte[] buffer)
106
/// <summary>
107
/// 在指定内存中写入数据
108
/// </summary>
109
/// <typeparam name="T">数据类型(int,float,long等)</typeparam>
110
/// <param name="processHandle">进程句柄</param>
111
/// <param name="address">目标地址</param>
112
/// <param name="source">待写入值</param>
113
public static void WriteMemory<T>(nint processHandle, nint address, T source) where T : struct
59
114
{
115
var buffer = StructureToByteArray(source);
60
116
WriteProcessMemory(processHandle, address, buffer, (uint)buffer.Length, out _);
61
117
}
62
63
// 解析指针地址
64
public static nint ResolvePointerAddress(string processName, string moduleName, int firstAddress, int[] offsets, int size)
118
/// <summary>
119
/// 解析基址对应的实际地址
120
/// </summary>
121
/// <param name="processName">进程名称</param>
122
/// <param name="moduleName">模块名称(基址的进程部分,可以是DLL等)</param>
123
/// <param name="baseAddress">基址的地址部分</param>
124
/// <param name="processType">目标进程类型</param>
125
/// <param name="offsets">基址的偏移组</param>
126
/// <returns>实际地址</returns>
127
public static nint ResolvePointerAddress(string processName, string moduleName, int baseAddress, ProcessType processType, params int[] offsets)
65
128
{
66
// 获取游戏进程
67
129
var gameProcess = GetGameProcessByName(processName);
68
130
if (gameProcess == null)
69
131
{
70
Console.WriteLine("游戏进程未找到!");
132
Trace.WriteLine("游戏进程未找到!");
71
133
return nint.Zero;
72
134
}
73
74
// 获取模块基址
75
135
var moduleBaseAddress = GetModuleBaseAddress(gameProcess, moduleName);
76
136
if (moduleBaseAddress == nint.Zero)
77
137
{
78
Console.WriteLine($"未找到模块:{moduleName}");
138
Trace.WriteLine($"未找到模块:{moduleName}");
79
139
return nint.Zero;
80
140
}
81
82
// 解析指针地址
83
var resolvedAddress = nint.Add(moduleBaseAddress, firstAddress);
141
var resolvedAddress = nint.Add(moduleBaseAddress, baseAddress);
84
142
foreach (int offset in offsets)
85
143
{
86
var longAddress = ReadMemory<long>(gameProcess.Handle, resolvedAddress);
87
var pointerValue = new nint(longAddress);
88
resolvedAddress = nint.Add(pointerValue, offset);
144
if (processType == ProcessType.Bit32)
145
{
146
var nextAddress = ReadMemory<int>(gameProcess.Handle, resolvedAddress);
147
var pointerValue = new nint(nextAddress);
148
Trace.WriteLine(pointerValue.ToString("X"));
149
resolvedAddress = nint.Add(pointerValue, offset);
150
}
151
else
152
{
153
var nextAddress = ReadMemory<long>(gameProcess.Handle, resolvedAddress);
154
var pointerValue = new nint(nextAddress);
155
Trace.WriteLine(pointerValue.ToString("X"));
156
resolvedAddress = nint.Add(pointerValue, offset);
157
}
89
158
}
90
91
159
return resolvedAddress;
92
160
}
93
94
// 获取进程对象
95
public static Process? GetGameProcessByName(string processName)
96
{
97
Process[] processes = Process.GetProcessesByName(processName);
98
return processes.Length > 0 ? processes[0] : null;
99
}
100
101
// 获取模块基址
161
/// <summary>
162
/// 通过模块名称获取模块地址
163
/// </summary>
164
/// <param name="process">模块所在进程</param>
165
/// <param name="moduleName">模块名称</param>
166
/// <returns></returns>
102
167
public static nint GetModuleBaseAddress(Process process, string moduleName)
103
168
{
104
169
var module = process.Modules.Cast<ProcessModule>().FirstOrDefault(m => m.ModuleName.Equals(moduleName, StringComparison.OrdinalIgnoreCase));
105
170
return module != null ? module.BaseAddress : nint.Zero;
106
171
}
172
internal static Process? GetGameProcessByName(string processName)
173
{
174
var processes = Process.GetProcessesByName(processName);
175
return processes.Length > 0 ? processes[0] : null;
176
}
177
private static byte[] StructureToByteArray<T>(T source) where T : struct
178
{
179
var size = Marshal.SizeOf<T>();
180
var buffer = new byte[size];
181
IntPtr ptr = Marshal.AllocHGlobal(size);
182
Marshal.StructureToPtr(source, ptr, true);
183
Marshal.Copy(ptr, buffer, 0, size);
184
Marshal.FreeHGlobal(ptr);
185
return buffer;
186
}
187
#endregion
188
#region DLL引用
189
[LibraryImport("kernel32.dll")]
190
internal static partial nint OpenProcess(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
191
192
[LibraryImport("kernel32.dll", SetLastError = true)]
193
[return: MarshalAs(UnmanagedType.Bool)]
194
internal static partial bool WriteProcessMemory(nint hProcess, nint lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
195
196
[LibraryImport("kernel32.dll")]
197
[return: MarshalAs(UnmanagedType.Bool)]
198
internal static partial bool ReadProcessMemory(nint hProcess, nint lpBaseAddress, [Out] byte[] lpBuffer, uint dwSize, out int lpNumberOfBytesRead);
199
#endregion
107
200
}
@@ -1,19 +1,61 @@
1
1
namespace XFEExtension.NetCore.MemoryEditor;
2
2
3
/// <summary>
4
/// 进程访问权限
5
/// </summary>
3
6
[Flags]
4
7
public enum ProcessAccessFlags : uint
5
8
{
9
/// <summary>
10
/// 允许对进程进行所有操作的权限。
11
/// </summary>
6
12
All = 0x001F0FFF,
13
/// <summary>
14
/// 终止进程的权限。
15
/// </summary>
7
16
Terminate = 0x00000001,
17
/// <summary>
18
/// 在远程进程中创建线程的权限。
19
/// </summary>
8
20
CreateThread = 0x00000002,
21
/// <summary>
22
/// 对进程进行虚拟内存操作的权限。
23
/// </summary>
9
24
VirtualMemoryOperation = 0x00000008,
25
/// <summary>
26
/// 从进程中读取虚拟内存的权限。
27
/// </summary>
10
28
VirtualMemoryRead = 0x00000010,
29
/// <summary>
30
/// 向进程写入虚拟内存的权限。
31
/// </summary>
11
32
VirtualMemoryWrite = 0x00000020,
33
/// <summary>
34
/// 复制句柄的权限。
35
/// </summary>
12
36
DuplicateHandle = 0x00000040,
37
/// <summary>
38
/// 创建进程的权限。
39
/// </summary>
13
40
CreateProcess = 0x000000080,
41
/// <summary>
42
/// 设置进程配额的权限。
43
/// </summary>
14
44
SetQuota = 0x00000100,
45
/// <summary>
46
/// 设置进程信息的权限。
47
/// </summary>
15
48
SetInformation = 0x00000200,
49
/// <summary>
50
/// 查询进程信息的权限。
51
/// </summary>
16
52
QueryInformation = 0x00000400,
53
/// <summary>
54
/// 有限查询进程信息的权限。
55
/// </summary>
17
56
QueryLimitedInformation = 0x00001000,
57
/// <summary>
58
/// 同步的权限。
59
/// </summary>
18
60
Synchronize = 0x00100000
19
61
}
@@ -0,0 +1,7 @@
1
namespace XFEExtension.NetCore.MemoryEditor;
2
3
public enum ProcessType
4
{
5
Bit32,
6
Bit64
7
}
@@ -9,6 +9,25 @@
9
9
<Authors>XFEstudio</Authors>
10
10
<Company>寰宇朽力网络科技</Company>
11
11
<Description>内存读写工具</Description>
12
<PackageIcon>logoIcon.png</PackageIcon>
13
<PackageReadmeFile>README.md</PackageReadmeFile>
14
<RepositoryUrl>https://github.com/XFEstudio/XFEExtension.NetCore.MemoryEditor.git</RepositoryUrl>
15
<PackageTags>XFE;XFEExtension;MemoryEdit;Memory</PackageTags>
16
<PackageReleaseNotes>FirstRelease</PackageReleaseNotes>
17
<Copyright>寰宇朽力网络科技版权所有</Copyright>
18
<PackageProjectUrl>https://github.com/XFEstudio/XFEExtension.NetCore.MemoryEditor.git</PackageProjectUrl>
19
<GenerateDocumentationFile>True</GenerateDocumentationFile>
12
20
</PropertyGroup>
13
21
22
<ItemGroup>
23
<None Include="..\logoIcon.png">
24
<Pack>True</Pack>
25
<PackagePath>\</PackagePath>
26
</None>
27
<None Include="..\README.md">
28
<Pack>True</Pack>
29
<PackagePath>\</PackagePath>
30
</None>
31
</ItemGroup>
32
14
33
</Project>
二进制文件已变更,无法进行逐行预览。