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

如何在二进制文件中定位字节模式并完成替换?

二进制文件字节模式定位与替换实现方案

核心思路

先将二进制文件完整读入内存(大文件可改用流式处理),通过字节序列匹配算法定位目标模式的偏移量,修改对应位置的字节后,再将数据写回文件。

具体实现步骤

1. 读取二进制文件到内存

以二进制模式打开文件,将全部内容读入vector<uint8_t>,方便后续操作:

#include <fstream>
#include <vector>
#include <cstdint>
#include <stdexcept>
#include <iostream>
#include <algorithm>

std::vector<uint8_t> read_binary_file(const std::string& path) {
    std::ifstream file(path, std::ios::binary | std::ios::ate);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file for reading");
    }
    std::streamsize size = file.tellg();
    file.seekg(0, std::ios::beg);

    std::vector<uint8_t> buffer(static_cast<size_t>(size));
    if (!file.read(reinterpret_cast<char*>(buffer.data()), size)) {
        throw std::runtime_error("Failed to read file content");
    }
    return buffer;
}

2. 定位目标字节序列

实现字节匹配函数,这里用简单暴力匹配(小文件足够高效,大文件可改用KMP算法优化):

size_t find_byte_sequence(const std::vector<uint8_t>& data, const std::vector<uint8_t>& pattern) {
    if (pattern.empty() || data.size() < pattern.size()) {
        return std::string::npos;
    }

    for (size_t i = 0; i <= data.size() - pattern.size(); ++i) {
        bool match = true;
        for (size_t j = 0; j < pattern.size(); ++j) {
            if (data[i + j] != pattern[j]) {
                match = false;
                break;
            }
        }
        if (match) {
            return i;
        }
    }
    return std::string::npos;
}

如果需要查找所有匹配位置,可循环调用此函数,每次从上次找到的偏移量+1处开始搜索。

3. 替换匹配的字节序列

找到偏移量后,直接在内存缓冲区中替换对应字节:

void replace_byte_sequence(std::vector<uint8_t>& data, size_t offset, const std::vector<uint8_t>& replacement) {
    if (offset + replacement.size() > data.size()) {
        throw std::runtime_error("Replacement sequence exceeds file bounds");
    }
    std::copy(replacement.begin(), replacement.end(), data.begin() + offset);
}

4. 写回二进制文件

将修改后的缓冲区写入文件(建议先写入新文件,验证正确后再覆盖原文件):

void write_binary_file(const std::string& path, const std::vector<uint8_t>& data) {
    std::ofstream file(path, std::ios::binary);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file for writing");
    }
    if (!file.write(reinterpret_cast<const char*>(data.data()), data.size())) {
        throw std::runtime_error("Failed to write modified content");
    }
}

完整调用示例

int main() {
    try {
        // 定义目标模式和替换序列
        const std::vector<uint8_t> target_pattern = {0x70, 0x74, 0xFF, 0xFF};
        const std::vector<uint8_t> replacement = {0x50, 0x50, 0x50, 0xFF};

        // 读取原文件
        auto file_data = read_binary_file("target.bin");

        // 查找目标模式
        size_t offset = find_byte_sequence(file_data, target_pattern);
        if (offset == std::string::npos) {
            std::cerr << "Target byte sequence not found in file" << std::endl;
            return 1;
        }

        // 执行替换
        replace_byte_sequence(file_data, offset, replacement);

        // 写入修改后的文件(优先写新文件避免数据丢失)
        write_binary_file("modified_target.bin", file_data);
        std::cout << "Byte sequence replaced successfully" << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}

关键注意事项

  • 必须以std::ios::binary模式打开文件,否则会自动转换换行符,破坏二进制数据结构。
  • 操作大文件时,全读入内存会占用过多资源,可改用流式匹配:每次读取固定大小的缓冲区,维护滑动窗口匹配目标模式,找到后通过seekp定位文件偏移量直接修改。
  • 替换前建议备份原文件,或先写入新文件验证结果,避免操作失误导致数据丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:15:42