diff --git a/src/main.c b/src/main.c index 883b5b4..760ba45 100644 --- a/src/main.c +++ b/src/main.c @@ -1,26 +1,59 @@ +#include #include #include #include +#include +#include #include +#include "config.h" +#include "corrupt.h" #include "dosfs.h" static void usage(void) __dead; static int list_img(char *); +static int do_corrupt(char *, config_t *, uint32_t); int main(int argc, char *argv[]) { - int ch, list_mode; + int ch, list_mode, res, preseed; + uint32_t seed; + char *cfg_path, *ep; + config_t *conf; setprogname(argv[0]); list_mode = 0; - while ((ch = getopt(argc, argv, "l")) != -1) { + seed = 0; + preseed = 0; + cfg_path = NULL; + while ((ch = getopt(argc, argv, "lc:s:")) != -1) { switch (ch) { case 'l': list_mode = 1; break; + case 'c': + cfg_path = optarg; + break; + case 's': + errno = 0; + if (optarg[0] == '0' && optarg[1] == 'x') { + // strtoul hex + optarg += 2; + seed = strtoul(optarg, &ep, 16); + } else { + seed = strtoul(optarg, &ep, 10); + } + if (errno) { + perror("couldn't parse seed parameter"); + return EXIT_FAILURE; + } else if (optarg == ep || *ep != 0) { + fprintf(stderr, "defined seed is malformed\n"); + return EXIT_FAILURE; + } + preseed = 1; + break; case '?': default: usage(); @@ -39,10 +72,28 @@ main(int argc, char *argv[]) return list_img(argv[0]); } - /* TODO: rest of the owl */ - fprintf(stderr, "not yet implemented :(\n"); + if (!preseed) { + seed = time(NULL) & 0xffffffff; + } - return EXIT_FAILURE; + printf("using seed 0x%x\n", seed); + + if (cfg_path != NULL) { + conf = parse_config(cfg_path); + if (conf == NULL) { + fprintf(stderr, "failed to parse config\n"); + return EXIT_FAILURE; + } + } else { + fprintf(stderr, "no default config implemented\n"); + return EXIT_FAILURE; + } + + res = do_corrupt(argv[0], conf, seed); + + free_config(conf); + + return res; } static int @@ -54,7 +105,7 @@ list_img(char *path) res = open_image(path, O_RDONLY, &img); if (res != 0) { - fprintf(stderr, "err: couldn't open image (errno %d)\n", res); + fprintf(stderr, "err: couldn't open image: %s\n", strerror(res)); return EXIT_FAILURE; } @@ -77,10 +128,48 @@ list_img(char *path) return EXIT_SUCCESS; } +static int +do_corrupt(char *path, config_t *conf, uint32_t seed) +{ + dosfs_t img = { 0 }; + dosfile_t *rootdir, *cur; + config_t *match; + int res; + + res = open_image(path, O_RDWR, &img); + if (res != 0) { + fprintf(stderr, "err: couldn't open image: %s\n", strerror(res)); + return EXIT_FAILURE; + } + + rootdir = dos_listdir(&img, img.root_loc); + if (rootdir == NULL) { + perror("couldn't read root dir"); + close_image(&img); + return EXIT_FAILURE; + } + + for (cur = rootdir; cur->next != NULL; cur = cur->next) { + match = match_rule(conf, cur); + if (match != NULL) { + printf("Corrupting %s.%s... (x%u a%u l%u r%u)\n", + cur->fname, cur->fext, match->opts.bit_xor, + match->opts.add, match->opts.shl, match->opts.shr); + res = corrupt_file(&img, cur, match, &seed); + if (res != 0) { + fprintf(stderr, "Corrupting file failed...\n"); + } + } + } + + close_image(&img); + return 0; +} + static void usage(void) { - fprintf(stderr, "usage: %s [-l] image\n", getprogname()); + fprintf(stderr, "usage: %s [-l] [-s seed] [-c config] image\n", getprogname()); exit(EXIT_FAILURE); }