十六进制查找和替换

时间:2014-01-17 09:15:35

标签: 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” 替换hex =“00 EB 01 00 37 E3 02”

1 个答案:

答案 0 :(得分:0)

首先,有点命名, viz 挑剔:你不想改变文件中的十六进制字符,而是改变字节缓冲区中的字节,然后以十六进制格式打印出来

如果您的数据为chars,则可以使用strstr中的string.h找到针头,然后使用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字节块边界的针。您可以通过在单个块中读取整个文件或通过一些巧妙的块管理来捕获这些,这些管理允许您扫描前一个块的最后七个字节。