diff --git a/configure.ac b/configure.ac index efc8c0b..1704ae1 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,7 @@ if test "$build" != "$host" -a "${PKG_CONFIG_LIBDIR}" = ""; then export PKG_CONFIG_LIBDIR=/dev/null fi -AC_CHECK_HEADERS(getopt.h) +AC_CHECK_HEADERS(inttypes.h stdint.h getopt.h) AC_CHECK_FUNCS(getopt_long, [AC_DEFINE(HAVE_GETOPT_LONG, 1, Define to 1 if you have the `getopt_long' function.)], diff --git a/src/Makefile.am b/src/Makefile.am index 83aa693..60bd199 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ bin_PROGRAMS = zzuf -zzuf_SOURCES = zzuf.c +zzuf_SOURCES = zzuf.c random.c diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..b6ba1d1 --- /dev/null +++ b/src/random.c @@ -0,0 +1,46 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2006 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * random.c: pseudorandom number generator + */ + +#include "config.h" + +#if defined HAVE_STDINT_H +# include +#elif defined HAVE_INTTYPES_H +# include +#endif +#include + +#include "random.h" + +void zzuf_srand(uint64_t seed) +{ + uint32_t a = seed & 0xffffffff; + uint32_t b = seed >> 32; + + srand((a ^ 0x12345678) * (b ^ 0x87654321)); +} + +uint64_t zzuf_rand(uint64_t max) +{ + if(max <= RAND_MAX) + return rand() % max; + + /* Could be better, but do we care? */ + return (uint64_t)((max * 1.0) * (rand() / (RAND_MAX + 1.0))); +} + diff --git a/src/random.h b/src/random.h new file mode 100644 index 0000000..14cfe03 --- /dev/null +++ b/src/random.h @@ -0,0 +1,21 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2006 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * random.h: pseudorandom number generator + */ + +void zzuf_srand(uint64_t); +uint64_t zzuf_rand(uint64_t); + diff --git a/src/zzuf.c b/src/zzuf.c index 78f2de1..48f510b 100644 --- a/src/zzuf.c +++ b/src/zzuf.c @@ -1 +1,188 @@ -int main(void) { return 0; } +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2006 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +/* + * main.c: main program + */ + +#include "config.h" + +#if defined HAVE_STDINT_H +# include +#elif defined HAVE_INTTYPES_H +# include +#endif +#if defined(HAVE_GETOPT_H) +# include +#endif +#include +#include +#include + +#include "random.h" + +static void version(void); +#if defined(HAVE_GETOPT_H) +static void usage(void); +#endif + +int main(int argc, char *argv[]) +{ + char *input = NULL, *output = NULL; + FILE *in, *out; + char *data; + long int i, todo, size, seed = -1; + float percent = -1.0; + +#if defined(HAVE_GETOPT_H) + for(;;) + { +# ifdef HAVE_GETOPT_LONG +# define MOREINFO "Try `%s --help' for more information.\n" + int option_index = 0; + static struct option long_options[] = + { + /* Long option, needs arg, flag, short option */ + { "input", 1, NULL, 'i' }, + { "output", 1, NULL, 'o' }, + { "seed", 1, NULL, 's' }, + { "percent", 1, NULL, 'p' }, + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'v' }, + }; + + int c = getopt_long(argc, argv, "i:o:s:p:hv", + long_options, &option_index); +# else +# define MOREINFO "Try `%s -h' for more information.\n" + int c = getopt(argc, argv, "i:o:s:p:hv"); +# endif + if(c == -1) + break; + + switch(c) + { + case 'i': /* --input */ + input = optarg; + break; + case 'o': /* --output */ + output = optarg; + break; + case 's': /* --seed */ + seed = atol(optarg); + break; + case 'p': /* --percent */ + percent = atof(optarg); + break; + case 'h': /* --help */ + usage(); + return 0; + case 'v': /* --version */ + version(); + return 0; + default: + printf("%s: invalid option -- %c\n", argv[0], c); + printf(MOREINFO, argv[0]); + return 1; + } + } +#else +# define MOREINFO "Usage: %s message...\n" + int optind = 1; +#endif + + /* Open the files */ + if(input) + { + in = fopen(input, "rb"); + if(!in) + { + fprintf(stderr, "could not open `%s'\n", input); + return 1; + } + } + else + in = stdin; + + if(output) + { + out = fopen(output, "wb"); + if(!out) + { + fprintf(stderr, "could not open `%s' for writing\n", output); + return 1; + } + } + else + out = stdout; + + /* Checking parameters */ + if(seed == -1) + { + unsigned long int a = getpid(); + seed = (0x7931fea7 * a) ^ (0xb7390af7 + a); + fprintf(stderr, "no seed specified, using %lu\n", seed); + } + + if(percent == -1.0) + { + percent = 0.1; + fprintf(stderr, "no percent specified, using %g\n", percent); + } + + /* Read file contents */ + fseek(in, 0, SEEK_END); + size = ftell(in); + data = malloc(size); + fseek(in, 0, SEEK_SET); + fread(data, size, 1, in); + fclose(in); + + /* Randomise shit */ + zzuf_srand(seed); + todo = percent * 0.01 * size; + while(todo--) + { + i = zzuf_rand(size); + data[i] ^= 1 << zzuf_rand(8); + } + + /* Write result */ + fwrite(data, size, 1, out); + fclose(out); + + return 0; +} + +static void version(void) +{ + printf("zzuf %s by Sam Hocevar \n", VERSION); +} + +#if defined(HAVE_GETOPT_H) +static void usage(void) +{ + printf("Usage: zuff [ -vh ] [ -i input ] [ -o output ]\n"); + printf(" [ -p percent ] [ -s seed ]\n"); +# ifdef HAVE_GETOPT_LONG + printf(" -h, --help display this help and exit\n"); + printf(" -v, --version output version information and exit\n"); +# else + printf(" -h display this help and exit\n"); + printf(" -v output version information and exit\n"); +# endif +} +#endif + +