2014-01-17 3 views
0

이진 파일의 이진 파일 16 진수 문자를 변경하는 방법은 무엇입니까?16 진수 찾기 및 바꾸기

#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

16 진수 문자열을 다른 문자열로 바꾸는 문제는 텍스트 문자열 하나를 다른 문자열로 바꾸는 것과 같습니다. 유일한 차이점은 텍스트 패턴 대신 바이너리 패턴을 사용한다는 것입니다. 문제를 해결하려면 먼저 한 텍스트 문자열을 다른 텍스트 문자열로 바꾸는 문제를 해결하십시오. 이것은 strstr, memmove 및 strcpy를 포함합니다. 이진 문자열로 전환하려면 strstr 대신 memmem을 사용하고 strcpy 대신 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 21E 8D E2 D1 39 00 EB 21E 8D E2 8B 39 00 EB 00 30 –

+0

브랜든에게 감사드립니다. 바이너리 파일에서 직접 16 진수 값을 사용 하시겠습니까? –

답변

0

먼저 명명법의 비트, 즉 하찮은 일에 속 태우고 대체 : 당신 돈 파일의 16 진수 문자를 변경하려고하지만 바이트 버퍼의 바이트는 16 진수 형식으로 출력합니다. 데이터가 chars 인 경우

, 당신은 당신의 바늘을 찾은 다음 memcpy와 같은 길이의 문자열이 데이터를 덮어 string.h에서 strstr를 사용할 수 있습니다. 바이트 배열에 0을 포함 할 수있는 데이터를 찾는 유사한 함수가 필요합니다. GNU는 memmem이 있지만 비 표준입니다, 그래서 하나 쓸 수 : 당신은

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 바이트 청크의 경계에 앉아 바늘을 잡을 것입니다 수

/* 
* 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; 
} 

당신 물론 읽습니다. 모 놀리 식 청크에서 전체 파일을 읽거나 이전 청크의 마지막 7 바이트를 스캔 할 수있는 영리한 청크 관리를 통해이를 포착 할 수 있습니다.

+0

4kb 파일에서 작업 코드 인 M Oehm에 감사드립니다. 하지만 내 파일 32mb 결과 파일 0kb –

+0

@Mehmet_ : 아마도 당신이 파일에 바이트 배열을 작성하는 방식과 관련이 있습니다. 코드의 해당 부분이 위의 예에 나와 있지 않으므로 거기에 도움을 드릴 수 없습니다. –

+0

@M Oehm 버퍼 크기 오류 내 예제 코드가 느려졌습니다. 새 예제를 바꾸지 만 작동하지 않습니다. –