diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2e221e1 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +.POSIX: +CFLAGS = -O3 -Wall -Wextra +PREFIX = /usr/local +main: main.c + $(CC) $(CFLAGS) main.c -o corrupt + +all: main + +clean: + rm -f corrupt + +install: + cp corrupt $(DESTDIR)$(PREFIX)/bin/ + +uninstall: + rm $(DESTDIR)$(PREFIX)/bin/corrupt + +PHONY = all clean install uninstall diff --git a/README.md b/README.md index 20e68a0..805bcec 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,21 @@ # Corrupt -A CLI tool for simple and efficient file shredding +A minimal tool that shreds files using the Gutmann method + +## Installation +You need just a C compiler with the default libraries, and `make` +```shell +# Compiles to `corrupt` +make +# Optional, copy the binary to /usr/local/bin +sudo make install +``` + +## Example +```shell +# Corrupts a file +corrupt file +# Corrupts multiple files +corrupt file2 file3 +# Files still exist, but its contents were overwritten multiple times +cat file file2 file3 +``` diff --git a/main.c b/main.c new file mode 100644 index 0000000..d957c4d --- /dev/null +++ b/main.c @@ -0,0 +1,109 @@ +#include /* time */ +#include /* FILE, fopen, fwrite, fclose, fprintf */ +#include /* uint*_t int*_t */ +#include /* strlen */ +#include /* srand, rand */ +#include /* stat */ +#include /* off_t */ + +static uint8_t +CorruptStep(const char *filename, const off_t filesize, const char *pattern) +{ + uint8_t ret = 0; + + FILE* fp = fopen(filename, "w"); + if (fp != NULL) + { + off_t i; + uint8_t length = (uint8_t) strlen(pattern); + if (length > 0) + { + off_t times = (filesize / length) + (filesize % length); + for (i = 0; i < times; i++) + { + fwrite(pattern, sizeof(char), length, fp); + } + } + else + { + srand((unsigned int) time(NULL)); + for (i = 0; i < filesize; i++) + { + int n = rand(); + fwrite(&n, sizeof(char), 1, fp); + } + } + fclose(fp); + } + else + { + ret = 1; + } + return ret; +} + +static uint8_t +CorruptFile(const char *filename) +{ + uint8_t ret = 0; + + struct stat st; + if(stat(filename, &st) == 0) + { + if (S_ISREG(st.st_mode) != 0) + { + off_t filesize = st.st_size; + const char* steps[35] = {"", "", "", "", "\x55", "\xAA", + "\x92\x49\x24", "\x49\x24\x92", + "\x24\x92\x49", "\x00", "\x11", + "\x22", "\x33", "\x44", "\x55", + "\x66", "\x77", "\x88", "\x99", + "\xAA", "\xBB", "\xCC", "\xDD", + "\xEE", "\xFF", "\x92\x49\x24", + "\x49\x24\x92", "\x24\x92\x49", + "\x6D\xB6\xDB", "\xB6\xDB\x6D", + "\xDB\x6D\xB6", "", "", "", ""}; + uint8_t i; + for (i = 0; i < 35; i++) + { + if (CorruptStep(filename, filesize, steps[i]) != 0) + { + fprintf(stderr, "corrupt: shredding of '%s' ", filename); + fprintf(stderr, "failed on step %d\n", i); + ret = 1; + break; + } + } + } + else + { + fprintf(stderr, "corrupt: '%s' is not a regular file\n", filename); + ret = 1; + } + } + else + { + fprintf(stderr, "corrupt: '%s' not found\n", filename); + ret = 1; + } + return ret; +} + +int +main(int argc, char* argv[]) +{ + if (argc > 1) + { + int i; + for (i = 1; i < argc; i++) + { + CorruptFile(argv[i]); + } + } + else + { + fprintf(stderr, "Usage: corrupt FILES...\n"); + fprintf(stderr, "Shreds files using the Gutmann method\n"); + } + return 0; +}