【编程技术-C# .net内存特征码搜索和内存修改】此文章归类为:编程技术。
.net的内存特征码搜索
功能:
1、内存特征码搜索(支持堆栈搜索,半码F?、全码??)
2、程序集dll、C/C++模块的获取基址和映像大小
3、内存修改(可以带??,如:5F ?? 6E 7D ?? 8A)
部分实现代码:
获取程序集模块的基址
public static ulong Get_Assembly_Module_BaseAddress(string assemblyName)
{
try
{
if (string.IsNullOrEmpty(assemblyName)) return 0;
return (ulong)Marshal.GetHINSTANCE(
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(m => m.GetModules()
.Where(n => n.Name.Contains(assemblyName)))
.FirstOrDefault());
}
catch { return 0; }
}
获取模块的映像大小,.net和C/C++的通用public static ulong Get_Moule_SizeOfImage(ulong baseAddress)
{
try
{
IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure((IntPtr)baseAddress, typeof(IMAGE_DOS_HEADER));
IMAGE_NT_HEADERS ntHeader = (IMAGE_NT_HEADERS)Marshal.PtrToStructure((IntPtr)(baseAddress + (ulong)dosHeader.e_lfanew),
typeof(IMAGE_NT_HEADERS));
return (ulong)ntHeader.OptionalHeader.SizeOfImage;
}
catch { return 0; }
}
获取C/C++模块的基址
public static ulong Get_C_Module_BaseAddress(string cModuleName)
{
try
{
if (string.IsNullOrEmpty(cModuleName)) return 0;
return (ulong)Process.GetCurrentProcess()
.Modules.Cast<ProcessModule>()
.Where(m => m.ModuleName.Contains(cModuleName))
.ToArray().FirstOrDefault().BaseAddress;
}
catch { return 0; }
}
获取C/C++模块的映像大小
public static ulong Get_C_Module_SizeOfImage(string cModuleName)
{
try
{
if (string.IsNullOrEmpty(cModuleName)) return 0;
return (ulong)Process.GetCurrentProcess()
.Modules.Cast<ProcessModule>()
.Where(m => m.ModuleName.Contains(cModuleName))
.ToArray().FirstOrDefault().ModuleMemorySize;
}
catch { return 0; }
}
修改内存数据
public static bool WriteMemoryData(ulong baseAddress, string data)
{
try
{
if (string.IsNullOrEmpty(data)) return false;
data = data.Replace(" ", "");
if ((data.Length & 1) != 0) return false; // 不能为单数
uint len = (uint)data.Length / 2; // 计算特征码长度
uint oldProtect;
if (VirtualProtect((IntPtr)baseAddress, len, PAGE_EXECUTE_READWRITE, out oldProtect))
{
for (uint i = 0; i < len; i++)
{
string tempStr = data.Substring((int)i * 2, 2);
if (tempStr != "??")
Marshal.WriteByte((IntPtr)(baseAddress + i), Convert.ToByte(tempStr, 16));
}
VirtualProtect((IntPtr)baseAddress, len, oldProtect, out oldProtect);
return true;
}
}
catch { return false; }
return false;
}
调用:
private static void Main(string[] args)
{
// System.dll是.NET Framework的核心程序集,ntdll.dll是Windows系统的核心模块
var systemAssembly = PatchPattern.Get_Assembly_Module_BaseAddress("System.dll");
Console.WriteLine("System基址:0x" + systemAssembly.ToString("X"));
Console.WriteLine("System大小:0x" + PatchPattern.Get_Moule_SizeOfImage(systemAssembly).ToString("X"));
Console.WriteLine("ntdll基址:0x" + PatchPattern.Get_C_Module_BaseAddress("ntdll.dll").ToString("X"));
Console.WriteLine("ntdll大小:0x" + PatchPattern.Get_C_Module_SizeOfImage("ntdll.dll").ToString("X"));
// testtest 的特征码为 74006500730074007400650073007400
string testStr = "testtest";
string patternStr = "74 00 ?5 00 ?3 00 74 00 74 0? 65 00 ?? 00 74 00";
IntPtr hProcess = Process.GetCurrentProcess().Handle;
// 获取主模块基址和大小
ulong baseAddress = (ulong)Process.GetCurrentProcess().MainModule.BaseAddress;
ulong size = (ulong)Process.GetCurrentProcess().MainModule.ModuleMemorySize;
Console.WriteLine("模块基址:0x" + baseAddress.ToString("X") + "----模块大小:0x" + size.ToString("X"));
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
// 遍历内存,搜索特征码
// 注意:搜索前确保程序集或者dll已加载
List<ulong> result = PatchPattern.SundayPatternFind(hProcess, baseAddress, baseAddress + size, patternStr, 0);
stopwatch.Stop();
Console.WriteLine("搜索用时: " + stopwatch.ElapsedMilliseconds + " 毫秒");
Console.WriteLine("搜索到特征码:" + result.Count + "个");
foreach (ulong item in result)
{
Console.WriteLine("特征码地址:0x" + item.ToString("X"));
}
// 修改搜索到的内存数据
if (result.Count > 0)
if (PatchPattern.WriteMemoryData(result[0], "00??0000??55"))
Console.WriteLine("修改内存数据成功");
else Console.WriteLine("修改内存数据失败");
Console.ReadKey();
}
更多【编程技术-C# .net内存特征码搜索和内存修改】相关视频教程:www.yxfzedu.com