问题
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