首页
社区
课程
招聘
2
[原创]C# .net内存特征码搜索和内存修改
发表于: 2025-3-17 14:57 2495

[原创]C# .net内存特征码搜索和内存修改

2025-3-17 14:57
2495

.net的内存特征码搜索
功能:
1、内存特征码搜索(支持跨进程,堆栈搜索,半码F?、全码??,编写自己的搜索工具)
2、程序集dll、C/C++模块的获取基址和映像大小
3、内存修改(可以带??,如:5F ?? 6E 7D ?? 8A)

部分实现代码
获取程序最小地址

public static ulong Get_Application_MinAddress()
{
    try
    {
        SYSTEM_INFO systemInfo;
        GetSystemInfo(out systemInfo);
        return (ulong)systemInfo.minimumApplicationAddress;
    }
    catch { return 0; }
}

获取程序最大地址

public static ulong Get_Application_MaxAddress()
{
    try
    {
        SYSTEM_INFO systemInfo;
        GetSystemInfo(out systemInfo);
        return (ulong)systemInfo.maximumApplicationAddress;
    }
    catch { return 0; }
}

获取程序集模块的基址

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.Equals(assemblyName, StringComparison.OrdinalIgnoreCase)))
            .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.Equals(cModuleName, StringComparison.OrdinalIgnoreCase))
            .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.Equals(cModuleName, StringComparison.OrdinalIgnoreCase))
            .ToArray().FirstOrDefault().ModuleMemorySize;
    }
    catch { return 0; }
}

Sunday算法搜索特征码 x86/x64

/// <summary>
/// Sunday算法搜索特征码 x86/x64
/// </summary>
/// <param name="hProcess">进程句柄</param>
/// <param name="startAddress">搜索的起始地址</param>
/// <param name="endAddress">搜索的结束地址</param>
/// <param name="pattern">特征码支持半码?F、全码??</param>
/// <param name="searchNum">搜索数量,0表示无限制</param>
/// <returns>返回搜索到的特征码地址列表</returns>
public static List<ulong> SundayPatternFind(IntPtr hProcess, ulong startAddress, ulong endAddress, string pattern, int searchNum = 0)
{
    ……略……
}

调用

private static void Main(string[] args)
{
    Console.WriteLine("程序最小地址:0x" + PatchPattern.Get_Application_MinAddress().ToString("X"));
    Console.WriteLine("程序最大地址:0x" + PatchPattern.Get_Application_MaxAddress().ToString("X"));

    // 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"));

    // Hello World! 的特征码为 48 00 65 00 6C 00 6C 00 6F 00 20 00 57 00 6F 00 72 00 6C 00 64 00 21 00
    string testStr = "Hello World!";
    string patternStr = "48 00 65 00 6C 00 6C ?? 6F 00 20 00 ?7 00 6F ?? 72 00 6C 00 64 00 21 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);
    // 整个进程搜索
    //List<ulong> result = PatchPattern.SundayPatternFind(hProcess, PatchPattern.Get_Application_MinAddress(), PatchPattern.Get_Application_MaxAddress(), patternStr);
    stopwatch.Stop();

    Console.WriteLine("搜索用时: " + stopwatch.ElapsedMilliseconds + " 毫秒");
    Console.WriteLine("搜索到特征码:" + result.Count + "个");
    result.ForEach(x => Console.WriteLine("特征码地址:0x" + x.ToString("X")));

    // 你好,世界!的unicode编码为 60 4F 7D 59 0C FF 16 4E 4C 75 01 FF
    Encoding.Unicode.GetBytes("你好,世界!").ToList().ForEach(x => Console.Write(x.ToString("X2") + " "));
    Console.WriteLine();
    // 修改搜索到的内存数据
    if (result.Count > 0)
        // 将特征码替换为你好,世界!的unicode编码,并添加截断0000字节
        if (PatchPattern.WriteMemoryData(result[0], "60 4F 7D 59 0C FF 16 4E 4C 75 01 FF" + "0000"))
        {
            Console.WriteLine("修改内存数据成功");
            Console.WriteLine("修改为:" + Marshal.PtrToStringAuto((IntPtr)result[0]));
        }
        else Console.WriteLine("修改内存数据失败");

    Console.ReadKey();
}



[注意]看雪招聘,专注安全领域的专业人才平台!

上传的附件:
收藏
免费 2
支持
分享
赞赏记录
参与人
雪币
留言
时间
ldljlzw
感谢你的贡献,论坛因你而更加精彩!
2025-3-22 10:22
许可飞
+1
感谢你分享这么好的资源!
2025-3-17 21:21
最新回复 (3)
雪    币: 9681
活跃值: (5984)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jgs
2
用了都说好!谢谢楼主提供。
2025-3-17 20:19
0
雪    币: 225
活跃值: (615)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享蛤~你们的帖子怎么审核的这么快,我刚来论坛滴第一次(帖)都快等了一天了。
2025-3-17 20:36
0
雪    币: 4428
活跃值: (4771)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
厉害,先收藏。
2025-3-18 12:40
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册