You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#程序查找并替换编译EXE中的指定十六进制值

在C#中实现十六进制值的查找与替换(针对多文件修补场景)

我明白你现在的痛点——要批量处理8个文件的十六进制修补,相同的待替换十六进制值但每个文件里的偏移量不一样,却卡在了关键的查找环节。咱们一步步来搞定这个问题,核心思路是把十六进制字符串转换成字节数组,然后在文件的字节流里精准定位这些字节的位置,最后完成替换。

关键步骤拆解

  • 十六进制转字节数组:因为文件本质是字节流,咱们需要把要查找/替换的十六进制字符串转换成对应的字节数组,才能和文件内容匹配。
  • 实现字节数组查找方法:.NET没有直接提供查找字节数组所有出现位置的API,所以咱们得自己写一个方法,能找出目标字节数组在源字节数组里的所有偏移量。
  • 批量处理文件:循环遍历你的8个文件,依次完成读文件→查找→替换→写回的操作。

完整代码示例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class HexPatcher
{
    static void Main(string[] args)
    {
        // 配置参数:要查找的十六进制值、要替换成的十六进制值、目标文件列表
        string searchHex = "A1B2C3D4"; // 替换成你实际要找的十六进制字符串
        string replaceHex = "E5F67890"; // 替换成你实际要替换的十六进制字符串
        string[] targetFiles = new[] { "file1.exe", "file2.dll", "file3.bin", /* 剩下的5个文件路径 */ };

        // 转成字节数组
        byte[] searchBytes = HexStringToByteArray(searchHex);
        byte[] replaceBytes = HexStringToByteArray(replaceHex);

        // 批量处理每个文件
        foreach (string filePath in targetFiles)
        {
            if (!File.Exists(filePath))
            {
                Console.WriteLine($"警告:文件 {filePath} 不存在,跳过");
                continue;
            }

            try
            {
                // 读取文件所有字节
                byte[] fileBytes = File.ReadAllBytes(filePath);
                // 查找所有匹配的偏移量
                List<int> matchOffsets = FindAllOccurrences(fileBytes, searchBytes);

                if (matchOffsets.Count == 0)
                {
                    Console.WriteLine($"文件 {filePath} 中未找到目标十六进制值,跳过");
                    continue;
                }

                // 执行替换(如果有多个匹配,这里会替换所有;如果只需要替换特定偏移,可筛选matchOffsets)
                foreach (int offset in matchOffsets)
                {
                    Array.Copy(replaceBytes, 0, fileBytes, offset, replaceBytes.Length);
                }

                // 写回文件(建议先备份原文件!)
                File.WriteAllBytes(filePath, fileBytes);
                Console.WriteLine($"文件 {filePath} 修补完成,共替换 {matchOffsets.Count} 处");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"处理文件 {filePath} 时出错:{ex.Message}");
            }
        }

        Console.WriteLine("批量修补操作完成");
    }

    // 十六进制字符串转字节数组的工具方法
    private static byte[] HexStringToByteArray(string hex)
    {
        // 去掉可能的空格
        hex = hex.Replace(" ", "");
        if (hex.Length % 2 != 0)
        {
            throw new ArgumentException("十六进制字符串长度必须是偶数");
        }

        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }

    // 在源字节数组中查找目标字节数组的所有出现位置
    private static List<int> FindAllOccurrences(byte[] source, byte[] target)
    {
        List<int> offsets = new List<int>();
        if (target.Length == 0 || source.Length < target.Length)
        {
            return offsets;
        }

        for (int i = 0; i <= source.Length - target.Length; i++)
        {
            bool match = true;
            for (int j = 0; j < target.Length; j++)
            {
                if (source[i + j] != target[j])
                {
                    match = false;
                    break;
                }
            }

            if (match)
            {
                offsets.Add(i);
                // 如果不需要查找重叠匹配,可以在这里加上 i += target.Length - 1;
            }
        }

        return offsets;
    }
}

注意事项

  • 备份原文件:在执行替换前,一定要先备份你的目标文件,避免操作失误导致文件损坏。
  • 重叠匹配处理:如果你的目标十六进制值存在重叠匹配的可能(比如查找"AAAA",源数组里有"AAAAAA"),可以根据需求修改FindAllOccurrences方法里的循环逻辑(注释里的代码)。
  • 权限问题:如果修补的是系统文件或受保护的应用程序,可能需要以管理员权限运行你的C#程序。
  • 编码与字节序:确保你要查找的十六进制值的字节序和文件里的实际字节序一致(比如大端/小端),如果不一致需要调整转换逻辑。

内容的提问来源于stack exchange,提问作者Kontorted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:39:32