wtujoxk 发表于 2025-1-19 13:47:02

[限时分享]C# .net内存特征码搜索和内存修改

本帖最后由 wtujoxk 于 2025-3-17 14:45 编辑

.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;
}
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)
{
……略……
}
调用:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Net内存特征码搜索
{
    internal class Program
    {
      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, "60 4F 7D 59 0C FF 16 4E 4C 75 01 FF" + "0000"))
                {
                  Console.WriteLine("修改内存数据成功");
                  Console.WriteLine("修改为:" + Marshal.PtrToStringAuto((IntPtr)result));
                }
                else Console.WriteLine("修改内存数据失败");

            Console.ReadKey();
      }
    }
}



实战:.net 劫持 使用特征码一补丁通杀某标签软件所有版本






super_king 发表于 2025-1-19 14:04:24


感谢表哥分享

慕若曦 发表于 2025-1-19 14:58:49

学习了

netle8 发表于 2025-1-19 18:28:37

己下载,大牛能不能找个例子出个视频怎么用啊?{:handshake:}

yuan71058 发表于 2025-1-20 09:14:42

感谢发布原创作品,PYG有你更精彩!

轩轩1018 发表于 2025-1-20 10:37:59

感谢提供精品

xingbing 发表于 2025-1-20 11:06:09

感谢提供精品

wtujoxk 发表于 2025-1-20 13:02:25

netle8 发表于 2025-1-19 18:28
己下载,大牛能不能找个例子出个视频怎么用啊?


https://www.chinapyg.com/thread-157797-1-1.html

halewandering 发表于 2025-1-20 16:42:55

原创作品,支持!

杨林 发表于 2025-1-21 01:17:35

感谢分享,下载备用了!
页: [1] 2 3 4
查看完整版本: [限时分享]C# .net内存特征码搜索和内存修改