问题
How to change a binary file hexadecimal character in a binary file?
#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;
}
reading hex = "00 EB 00 00 50 E3 02" replace hex = "00 EB 01 00 37 E3 02"
回答1:
First, a bit of nomenclature, viz nitpicking: You don't want to change the hexadecimal characters in a file, but the bytes in a byte buffer, which you then print out in hexadecimal format.
If your data were chars, you could use strstr from string.h to find your needle and then overwrite data there with a string of the same length with memcpy. You need a similar function that finds any data which may contain zeros in a byte array. GNU has memmem, but it is non-standard, so let's write one:
/*
* 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;
}
You can the
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);
}
This will not catch needles that sit at the boundaries of the 4096-byte chunks you read in, of course. You can catch these by reading the whole file in a monolithic chunk or by some clever chunk management that allows you to scan the last seven bytes of the previous chunk.
来源:https://stackoverflow.com/questions/21181956/hexadecimal-find-and-replace