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

XFEExtension.NetCore.MemoryEditor

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

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

XFEstudio/XFEExtension.NetCore.MemoryEditor

完善主体

9b69da7
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

5 个文件 +204 -43
Modified XFEExtension.NetCore.MemoryEditor/MemoryEditor.cs +136 -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 }
Modified XFEExtension.NetCore.MemoryEditor/ProcessAccessFlags.cs +42 -0
@@ -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 }
Added XFEExtension.NetCore.MemoryEditor/ProcessType.cs +7 -0
@@ -0,0 +1,7 @@
1 namespace XFEExtension.NetCore.MemoryEditor;
2
3 public enum ProcessType
4 {
5 Bit32,
6 Bit64
7 }
Modified XFEExtension.NetCore.MemoryEditor/XFEExtension.NetCore.MemoryEditor.csproj +19 -0
@@ -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>
Added logoIcon.png +0 -0
二进制文件已变更,无法进行逐行预览。