c - 十六进制查找和替换

标签 c replace find hex

如何更改二进制文件中的十六进制字符?

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define BUFFER_SIZE     4096
int main(void)
{
     uint8_t  *buffer;  // Explicit 8 bit unsigned, but should equal "unsigned char"
     FILE     *file;
     char     filename[512] = "test.bin";

     // We could also have used buffer[BUFFER_SIZE], but this shows memory alloc
     if (NULL == (buffer = malloc(BUFFER_SIZE)))
     {
          fprintf(stderr, "out of memory\n");
          return -1;
     }

     // Being inside a { }, crlf won't be visible outside, which is good.
     char     *crlf;
     if (NULL != (crlf = strchr(filename, '\n')))
          *crlf = 0x0;

     if (NULL == (file = fopen(filename, "rb")))
     {
         fprintf(stderr, "File not found: '%s'\n", filename);
         return -1;
     }
     while(!feof(file) && !ferror(file))
     {
          size_t i, n;
          if (0 == (n = (size_t)fread(buffer, sizeof(uint8_t), BUFFER_SIZE, file)))
               if (ferror(file))
                    fprintf(stderr, "Error reading from %s\n", filename);
                    // Here, n = 0, so we don't need to break: next i-cycle won't run
        for (i = 0; i < n; i++)
          {
               printf("%02X ", buffer[i]);
               if (15 == (i % 16))
                   printf("\n"); // Every 16th byte, a newline
         }
     }
     fclose(file); // file = NULL; // This ensures file won't be useable after fclose
     free(buffer); // buffer = NULL; // This ensures buffer won't be useable after free
     printf("\n");
     return 0;
}

读取十六进制 =“00 EB 00 00 50 E3 02” 替换十六进制 =“00 EB 01 00 37 E3 02”

最佳答案

首先,一些术语,吹毛求疵:您不想更改文件中的十六进制字符,而是更改字节缓冲区中的字节,然后以十六进制格式打印出来.

如果您的数据是chars,您可以使用string.h中的strstr来查找您的针,然后用字符串覆盖那里的数据与memcpy具有相同的长度。您需要一个类似的函数来查找字节数组中可能包含零的任何数据。 GNU 有 memmem,但它不是标准的,所以让我们写一个:

/*
 *  Find needle of length len in byte haystack [p, end).
 */
uint8_t *buf_find(uint8_t *p, uint8_t *end, uint8_t *needle, int len)
{
    end = end - len + 1;

    while (p < end) {
        if (memcmp(p, needle, len) == 0) return p;
        p++;
    }
    return NULL;
}

你可以

uint8_t what[] = {0x00, 0xEB, 0x00, 0x00, 0x50, 0xE3, 0x02};
uint8_t repl[] = {0x00, 0xEB, 0x01, 0x00, 0x37, 0xE3, 0x02};

char *p = buffer;
char *end = buffer + n;

for (;;) {
    uint8_t *q = buf_find(p, end, what, sizeof(what));

    if (q == NULL) break;
    memcpy(q, repl, sizeof(repl));
    p = q + sizeof(text);
}

当然,这不会捕获位于您读入的 4096 字节 block 边界的针。您可以通过读取整体 block 中的整个文件或通过一些巧妙的 block 管理来捕获这些文件,该管理允许您扫描前一个 block 的最后七个字节。

关于c - 十六进制查找和替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21181956/

相关文章:

c - 我将如何重构此 C 代码以消除重复

mysql - 仅使用 Mysql 替换替换中所需的匹配项

java - 搜索并替换 Java TextArea 中所有搜索到的文本

python - 将子字符串的多个实例替换为列表中的项目

linux - 查找在过去 15 分钟内更改的文件,不包括一些子目录并将其压缩

grails - 如何获取在grails中具有特定角色的所有用户

c++ - 通过包装程序从C访问C++ API时,如何访问枚举类型?

c - 如果我要重复引用它们,是否应该将 C 数组值存储在局部变量中?

c - 未定义对 `_fcloseall' 的引用

linux - find/grep 命令显示文件名和 java 包