/* * replace_data v1.3 (c) 1998,2004 by van Hauser / THC * http://www.thc.org * * searchs for data on a blockdevice */ #include #include #include #include #include #include #define NEEDLE_SIZE 1024 #define BUFSIZE 65536 FILE *f; char needle[NEEDLE_SIZE]; char *thumb; unsigned long add_count = 0; off_t count = 0; unsigned int son; char *prog; void help() { printf("Syntax: %s [-i] blockdevice searchstring replacestring\n", prog); printf("[-i] ignore case\n"); exit(1); } void clean_string (char *buf) { unsigned int i = son; char *c_ptr = buf + son - 1; do { c_ptr++; i++; if ( (*c_ptr < 32) || (*c_ptr > 126) || (i > 60) ) { *c_ptr = '\0'; } } while (*c_ptr != '\0'); } void search_and_replace (char *buf, unsigned long bufsize, unsigned long readsize) { unsigned int i = 0; char *c_ptr = buf; long where; while (bufsize >= (son + i)) { if (strncmp(c_ptr, needle, son) == 0) { if (bufsize == readsize) where = (long) (c_ptr - buf) - (long) readsize; else where = -1 * ((long) readsize + son - 1 - (long)(c_ptr - buf)); fseek(f, where, SEEK_CUR); fwrite(thumb, son, 1, f); fseek(f, -where, SEEK_CUR); if (sizeof(count) < 8) printf("found at %lu, replaced\n", (unsigned long) (count + add_count + i)); else printf("found at %llu, replaced\n", (unsigned long long) (count + add_count + i)); } c_ptr++; i++; } } int main (int argc, char *argv[]) { char dev[100]; struct stat st; unsigned long loop = 0, read_error = 0; size_t reat, reat_old = 0; unsigned int jump_size, ignore = 0, i = 1; char buf[BUFSIZE]; char tmpbuf[(NEEDLE_SIZE - 1)*2]; prog = argv[0]; if ((argc < 4) || (argc >5)) { help(1); } if (argc == 5) { if (strncmp(argv[i++], "-i", 2) != 0) { help(); } ignore++; } strncpy(dev, argv[i++], sizeof(dev) - 1); strncpy(needle, argv[i++], sizeof(needle) - 1); thumb = argv[argc - 1]; if (strlen(thumb) != strlen(needle)) { printf("Error: searchstring and replacestring need to have the same length\n"); exit(1); } if (lstat(dev, &st) != 0) { perror("Can't access blockdevice"); exit(1); } if ((st.st_mode & S_IFBLK) != S_IFBLK) { printf("Warning: %s is not a block device\n", dev); } if ((f = fopen(dev, "r+")) == NULL) { perror("Can't open blockdevice for reading and writing"); exit(1); } jump_size = strlen(needle) - 1; son = strlen(needle); if (ignore) { for (i=0; i 0) { if (ignore) { for (i=0; i 1) { add_count = (unsigned long) (BUFSIZE + 1 - son); memcpy(tmpbuf + son - 1, buf, jump_size); search_and_replace(tmpbuf, son - 1 + jump_size, reat); count = count + reat_old; add_count = 0; } search_and_replace(buf, reat, reat); memcpy(tmpbuf, buf + reat - son + 1, son - 1); reat_old = reat; } } while ((feof(f) == 0) && (read_error == 0)); fclose(f); exit(0); }