2014-01-17 39 views
0

如何更改二進制文件中的二進制文件十六進制字符?十六進制查找和替換

#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」

+0

將另一個十六進制字符串替換爲另一個字符串的問題與將另一個替換爲另一個文本字符串的問題相同。唯一的區別是使用二進制模式而不是文本模式。爲了解決這個問題,首先解決用另一個替換一個文本字符串的問題。這將通常涉及strstr,memmove和strcpy。要切換到二進制字符串,只需使用memmem而不是strcpy而不是strstr和memcpy。另見http://stackoverflow.com/questions/1992253/a-pure-bytes-version-of-strstr – Brandin

+0

test.bin 8D E2 21 0E 8D E2 E6 39 00 EB 21 0E 8D E2 A0 39 00 EB 00 30 A0 E1 78 00 9F E5 01 2C A0 E3 05 10 A0 E1 73 39 00 EB 00 00 50 E3 02 00 00 1A 00 00 E0 E3 27 DE 8D E2 70 80 BD E8 14 50 94 E2 45 6F 84 E2 0F 00 00 0A 21 0E 8D E2 C2 39 00 EB 14 20 A0 E3 04 10 A0 E1 21 0E 8D E2 D1 39 00 EB 21 0E 8D E2 8B 39 00 EB 00 30 –

+0

感謝Brandin。你會直接使用二進制文件中的十六進制值嗎? –

回答

0

首先,位命名,挑剔:你不不想更改文件中的十六進制字符,而是更改字節緩衝區中的字節,然後以十六進制格式打印出來。

如果你的數據是chars,你可以使用strstrstring.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字節塊的邊界針你當然,請閱讀。您可以通過讀取整塊文件或通過一些聰明的塊管理來捕獲這些文件,這些塊管理允許您掃描前一個塊的最後七個字節。

+0

感謝M Oehm,工作代碼在4kb文件中。但我的文件32MB結果文件0kb –

+0

@Mehmet_:這可能與您將字節數組寫入文件的方式有關。代碼的那部分不在上面的示例中,所以我無法幫助您。 –

+0

@M Oehm緩衝區大小錯誤我的例子它的wery慢你的代碼替換我的新例子,但不工作 –