2009-11-17 4 views
0

바이너리 파일을 몇 바이트 검색하여 다른 바이트 묶음으로 바꾸는 작은 프로그램을 작성하려고합니다. 하지만 매번이 작은 응용 프로그램을 실행하려고하면 메시지가 나타납니다 istream_iterator는 역 참조가되지 않습니다. 누군가 다른 방법으로 이것을 수행하는 방법을 제안했을 수도 있습니다 (반복자는 새로운 주제입니다).바이너리 파일 수정하기

#include <fstream> 
#include <iterator> 
#include <algorithm> 

using namespace std; 

int main() { 

typedef istream_iterator<char> input_iter_t; 

const off_t SIZE = 4; 
char before[SIZE] = { 0x12, 0x34, 0x56, 0x78 }; 
char after[SIZE] = { 0x78, 0x12, 0x34, 0x65 }; 

fstream filestream("numbers.exe", ios::binary | ios::in | ios::out); 

if (search(input_iter_t(filestream), input_iter_t(), before, before + SIZE) != input_iter_t()) { 
    filestream.seekp(-SIZE, ios::cur); 
    filestream.write(after, SIZE); 
} 

return 0; 
} 

이 이렇게 내 두 번째 시도입니다뿐만 아니라 뭔가 잘못된 것입니다. 작은 파일은 정상적으로 보이는 것처럼 보이지만 크고 (약 2MB) 매우 천천히 작동하고 내가 원하는 것을 찾지 못합니다.

#include <iostream> 
#include <cstdlib> 
#include <string> 
#include <fstream> 
#include <iterator> 
#include <vector> 
#include <algorithm> 
#include <windows.h> 

using namespace std; 

int main() { 

const off_t Size = 4; 
unsigned char before[Size] = { 0x12, 0x34, 0x56, 0x78 }; 
unsigned char after[Size] = { 0x90, 0xAB, 0xCD, 0xEF }; 

    vector<char> bytes; 
    { 
     ifstream iFilestream("numbers.exe", ios::in|ios::binary); 
     istream_iterator<char> begin(iFilestream), end; 
     bytes.assign(begin, end) ; 
    } 

    vector<char>::iterator found = search(bytes.begin(), bytes.end(), before, before + Size); 
    if(found != bytes.end()) 
    { 
     copy(after, after + Size, found); 
     { 
      ofstream oFilestream("number-modified.exe"); 
      copy(bytes.begin(), bytes.end(), ostream_iterator<unsigned char>(oFilestream)); 
     } 
    } 
return 0; 
} 

건배, 토마스

답변

1

는 메모리에 파일의 큰 부분을 읽어 메모리에 교체 한 후 디스크에 무리를 덤프. 한 번에 한 바이트 씩 읽는 것은 입니다. 매우입니다.

또한 mmap (또는 Win32의 MapViewOfFile)에 대해 읽어 보시기 바랍니다.

0

search은 이터레이터의 특성 때문에 istream_iterator에서 작동하지 않습니다. 입력 반복자입니다. 이는 단순히 앞으로 이동 함을 의미합니다. 이는 스트림에서 읽는 것이므로 스트림에서 읽은 후에 되돌릴 수 없기 때문입니다. search전달 반복자이 필요합니다.이 반복자는 중지하고 사본을 만들고 이전 것을 유지하면서 앞으로 이동할 수있는 입력 반복기입니다. 순방향 반복자의 예는 단일 연결 목록입니다. 거꾸로 갈 수는 없지만, 당신이 어디에 있는지 기억하고 거기에서 다시 시작할 수 있습니다.

속도 문제는 벡터가 알 수없는 데이터를 처리하는 데 정말로 끔찍하기 때문입니다. 공간이 부족할 때마다 전체 버퍼를 새로운 메모리로 복사합니다. 하나씩 데이터를 처리 할 수있는 deque으로 바꿉니다. 또한 한 번에 한 블록 씩 스트림에서 읽으려는 성능이 향상 될 수 있습니다. 문자 단위로 액세스하면 전체 파일을 메모리에로드하는 것이 매우 어렵습니다.

0

파일이 너무 크지 않다는 가정하에 파일을 메모리로 읽어 들인 다음 메모리 버퍼를 수정 한 다음 다시 파일에 기록하십시오.

예. (테스트 안 함) :

FILE *f_in = fopen("inputfile","rb"); 
fseek(f_in,0,SEEK_END); 

long size = ftell(f_in); 
rewind(f_in); 

char* p_buffer = (char*) malloc (size); 
fread (p_buffer,size,1,f_in); 
fclose(f_in); 

unsigned char *p= (unsigned char*)p_buffer; 

// process. 

FILE *f_out = fopen("outoutfile","wb"); 
fwrite(p_buffer,size,1,f_out); 
fclose(f_out); 

free(p_buffer); 
관련 문제