#include #include #include #include #include #include union key_type { unsigned int number; char bytes[sizeof(int)]; }; static void fill_in_some_byte(int remaining_bytes, unsigned int *data, union key_type key) { char *start_data = (char*) data; switch(remaining_bytes) { case 3: start_data[2] ^= key.bytes[2]; case 2: start_data[1] ^= key.bytes[1]; case 1: *start_data ^= key.bytes[0]; } } static int calculate_memory(int block_counter, int size, int pos) { return block_counter*size + (pos+1)*sizeof(int); } int main(int argc, char **argv) { int fd, size, pgs, offset, pos, block_counter, next_used_memory; unsigned int *data; union key_type key; struct stat sb; size = 4096; offset = 0; block_counter = 0; key.number = ~ (unsigned int) strtol(argv[2], NULL, 10); pgs = getpagesize(); size = ((size-1) / pgs+1) * pgs; if(argc != 3) { perror("enter only three params"); return 1; } fd = open(argv[1], O_RDWR); if(fd == -1) { perror("can't open file"); return 2; } fstat(fd, &sb); while(offset < sb.st_size-1) { data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); if(data == MAP_FAILED) { perror("mapping error"); return 3; } pos = 0; next_used_memory = calculate_memory(block_counter, size, pos); while(next_used_memory <= sb.st_size && next_used_memory <= size) { data[pos] ^= key.number; ++pos; next_used_memory = calculate_memory(block_counter, size, pos); } if(next_used_memory > sb.st_size && next_used_memory <= size) { fill_in_some_byte(sizeof(int) - (next_used_memory - sb.st_size), data+pos, key); } munmap(data, size); offset += size; ++block_counter; } close(fd); return 0; }