* First somewhat working version.
This commit is contained in:
parent
e09dc41893
commit
c77ff249ed
5
README
5
README
@ -0,0 +1,5 @@
|
||||
About Zzuf
|
||||
==========
|
||||
Zzuf is a transparent application input fuzzer. It works by intercepting
|
||||
file operations and changing random bits in the program's input.
|
||||
|
||||
1
TODO
1
TODO
@ -0,0 +1 @@
|
||||
* Only very basic support for [f]open/[f]read, no seek, no close, etc.
|
||||
@ -1,9 +1,9 @@
|
||||
|
||||
bin_PROGRAMS = zzuf
|
||||
zzuf_SOURCES = zzuf.c random.c
|
||||
zzuf_SOURCES = zzuf.c
|
||||
|
||||
pkglib_LTLIBRARIES = libzzuf.la
|
||||
libzzuf_la_SOURCES = libzzuf.c
|
||||
libzzuf_la_SOURCES = libzzuf.c libzzuf.h fuzz.c fuzz.h debug.c debug.h preload.c preload.h random.c random.h
|
||||
libzzuf_la_LDFLAGS = -module
|
||||
libzzuf_la_LIBADD = -ldl
|
||||
|
||||
|
||||
49
src/debug.c
Normal file
49
src/debug.c
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* debug.c: debugging support
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#elif defined HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "debug.h"
|
||||
|
||||
void zzuf_debug(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int saved_errno;
|
||||
|
||||
if(!_zzuf_debug)
|
||||
return;
|
||||
|
||||
saved_errno = errno;
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "** zzuf debug ** ");
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
21
src/debug.h
Normal file
21
src/debug.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* debug.h: debugging support
|
||||
*/
|
||||
|
||||
extern void zzuf_debug(const char *format, ...);
|
||||
#define debug zzuf_debug
|
||||
|
||||
75
src/fuzz.c
Normal file
75
src/fuzz.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* fuzz.c: fuzz functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#elif defined HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "debug.h"
|
||||
#include "random.h"
|
||||
#include "fuzz.h"
|
||||
|
||||
#define CHUNK_SIZE 1024
|
||||
|
||||
void zzuf_fuzz(int fd, uint8_t *buf, uint64_t len)
|
||||
{
|
||||
uint8_t bits[CHUNK_SIZE];
|
||||
uint64_t pos;
|
||||
unsigned int i;
|
||||
|
||||
if(!files[fd].managed)
|
||||
return;
|
||||
|
||||
pos = files[fd].pos;
|
||||
|
||||
debug("fuzzing %lu bytes", (unsigned long int)len);
|
||||
debug("offset is %lu", (unsigned long int)pos);
|
||||
|
||||
for(i = pos / CHUNK_SIZE; i < (pos + len) / CHUNK_SIZE + 1; i++)
|
||||
{
|
||||
uint64_t offset;
|
||||
int todo;
|
||||
|
||||
offset = i * CHUNK_SIZE;
|
||||
todo = _zzuf_percent * CHUNK_SIZE;
|
||||
|
||||
zzuf_srand(_zzuf_seed ^ (i * 0x23ea84f7) ^ (todo * 0x783bc31f));
|
||||
memset(bits, 0, CHUNK_SIZE);
|
||||
while(todo--)
|
||||
{
|
||||
int idx = zzuf_rand(CHUNK_SIZE);
|
||||
uint8_t byte = (1 << zzuf_rand(8));
|
||||
|
||||
if(offset + idx < pos)
|
||||
continue;
|
||||
|
||||
if(offset + idx >= pos + len)
|
||||
continue;
|
||||
|
||||
buf[idx] ^= byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
src/fuzz.h
Normal file
20
src/fuzz.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* fuzz.h: fuzz functions
|
||||
*/
|
||||
|
||||
extern void zzuf_fuzz(int, uint8_t *, uint64_t);
|
||||
|
||||
111
src/libzzuf.c
111
src/libzzuf.c
@ -25,93 +25,66 @@
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define STR(x) #x
|
||||
#define ORIG(x) x##_orig
|
||||
#define LOADSYM(x) \
|
||||
do { \
|
||||
ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \
|
||||
if(!ORIG(x)) \
|
||||
{ \
|
||||
debug("could not load %s", STR(x)); \
|
||||
abort(); \
|
||||
} \
|
||||
} while(0)
|
||||
#include "libzzuf.h"
|
||||
#include "debug.h"
|
||||
#include "preload.h"
|
||||
|
||||
static int do_debug = 0;
|
||||
static void debug(const char *format, ...)
|
||||
{
|
||||
if(!do_debug)
|
||||
return;
|
||||
/* Global variables */
|
||||
int _zzuf_debug = 0;
|
||||
int _zzuf_seed = 0;
|
||||
float _zzuf_percent = 0.04f;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
fprintf(stderr, "** zzuf debug ** ");
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Library functions that we divert */
|
||||
static FILE * (*fopen_orig) (const char *path, const char *mode);
|
||||
static int (*open_orig) (const char *file, int oflag, ...);
|
||||
static int (*open64_orig) (const char *file, int oflag, ...);
|
||||
#define MAXFD 1024
|
||||
struct zzuf files[MAXFD];
|
||||
|
||||
/* Library initialisation shit */
|
||||
void zzufinit(void) __attribute__((constructor));
|
||||
void zzufinit(void)
|
||||
void zzuf_init(void)
|
||||
{
|
||||
char *tmp;
|
||||
int i;
|
||||
|
||||
LOADSYM(fopen);
|
||||
LOADSYM(open);
|
||||
LOADSYM(open64);
|
||||
if(zzuf_preload())
|
||||
abort();
|
||||
|
||||
tmp = getenv("ZZUF_DEBUG");
|
||||
if(tmp && *tmp)
|
||||
do_debug = 1;
|
||||
_zzuf_debug = 1;
|
||||
|
||||
tmp = getenv("ZZUF_SEED");
|
||||
if(tmp && *tmp)
|
||||
_zzuf_seed = atol(tmp);
|
||||
|
||||
tmp = getenv("ZZUF_PERCENT");
|
||||
if(tmp && *tmp)
|
||||
_zzuf_percent = atof(tmp);
|
||||
if(_zzuf_percent < 0.0f)
|
||||
_zzuf_percent = 0.0f;
|
||||
else if(_zzuf_percent > 1.0f)
|
||||
_zzuf_percent = 1.0f;
|
||||
|
||||
for(i = 0; i < MAXFD; i++)
|
||||
files[i].managed = 0;
|
||||
}
|
||||
|
||||
/* Our function wrappers */
|
||||
FILE *fopen(const char *path, const char *mode)
|
||||
/* Deinitialisation */
|
||||
void zzuf_fini(void)
|
||||
{
|
||||
debug("fopen(\"%s\", \"%s\");", path, mode);
|
||||
return fopen_orig(path, mode);
|
||||
}
|
||||
|
||||
#define OPEN(ret, fn, file, oflag) \
|
||||
do { if(oflag & O_CREAT) \
|
||||
{ \
|
||||
int mode; \
|
||||
va_list va; \
|
||||
va_start(va, oflag); \
|
||||
mode = va_arg(va, int); \
|
||||
va_end(va); \
|
||||
debug(STR(fn) "(\"%s\", %i, %i);", file, oflag, mode); \
|
||||
ret = ORIG(fn)(file, oflag, mode); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
debug(STR(fn) "(\"%s\", %i);", file, oflag); \
|
||||
ret = ORIG(fn)(file, oflag); \
|
||||
} } while(0)
|
||||
|
||||
int open(const char *file, int oflag, ...)
|
||||
{
|
||||
int ret;
|
||||
OPEN(ret, open, file, oflag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int open64(const char *file, int oflag, ...)
|
||||
{
|
||||
int ret;
|
||||
OPEN(ret, open64, file, oflag);
|
||||
return ret;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAXFD; i++)
|
||||
{
|
||||
if(!files[i].managed)
|
||||
continue;
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
src/libzzuf.h
Normal file
37
src/libzzuf.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* libzzuf.h: preloaded wrapper library
|
||||
*/
|
||||
|
||||
struct zzuf
|
||||
{
|
||||
int managed;
|
||||
uint64_t seed;
|
||||
uint64_t pos;
|
||||
char *data;
|
||||
};
|
||||
|
||||
extern struct zzuf files[];
|
||||
|
||||
/* Internal stuff */
|
||||
extern int _zzuf_debug;
|
||||
extern int _zzuf_seed;
|
||||
extern float _zzuf_percent;
|
||||
|
||||
/* Library initialisation shit */
|
||||
extern void zzuf_init(void) __attribute__((constructor));
|
||||
extern void zzuf_fini(void) __attribute__((destructor));
|
||||
|
||||
154
src/preload.c
Normal file
154
src/preload.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* preload.c: preloaded library functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#elif defined HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "libzzuf.h"
|
||||
#include "debug.h"
|
||||
#include "fuzz.h"
|
||||
#include "preload.h"
|
||||
|
||||
/* Library functions that we divert */
|
||||
static FILE * (*fopen_orig) (const char *path, const char *mode);
|
||||
static size_t (*fread_orig) (void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
static int (*open_orig) (const char *file, int oflag, ...);
|
||||
static int (*open64_orig) (const char *file, int oflag, ...);
|
||||
static ssize_t (*read_orig) (int fd, void *buf, size_t count);
|
||||
|
||||
#define STR(x) #x
|
||||
#define ORIG(x) x##_orig
|
||||
|
||||
#define LOADSYM(x) \
|
||||
do { \
|
||||
ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \
|
||||
if(!ORIG(x)) \
|
||||
return -1; \
|
||||
} while(0)
|
||||
|
||||
int zzuf_preload(void)
|
||||
{
|
||||
LOADSYM(fopen);
|
||||
LOADSYM(fread);
|
||||
LOADSYM(open);
|
||||
LOADSYM(open64);
|
||||
LOADSYM(read);
|
||||
|
||||
debug("libzzuf initialised");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our function wrappers */
|
||||
FILE *fopen(const char *path, const char *mode)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen_orig(path, mode);
|
||||
debug("fopen(\"%s\", \"%s\") = %p", path, mode, f);
|
||||
if(!f)
|
||||
return NULL;
|
||||
|
||||
files[fileno(f)].managed = 1;
|
||||
files[fileno(f)].pos = 0;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
size_t ret = fread_orig(ptr, size, nmemb, stream);
|
||||
debug("fread(%p, %li, %li, \"%s\") = %li",
|
||||
ptr, (long int)size, (long int)nmemb, stream, (long int)ret);
|
||||
if(ret > 0)
|
||||
{
|
||||
zzuf_fuzz(fileno(stream), ptr, ret * size);
|
||||
files[fileno(stream)].pos += ret * size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OPEN(ret, fn, file, oflag) \
|
||||
do \
|
||||
{ \
|
||||
if(oflag & O_CREAT) \
|
||||
{ \
|
||||
int mode; \
|
||||
va_list va; \
|
||||
va_start(va, oflag); \
|
||||
mode = va_arg(va, int); \
|
||||
va_end(va); \
|
||||
ret = ORIG(fn)(file, oflag, mode); \
|
||||
debug(STR(fn) "(\"%s\", %i, %i) = %i", file, oflag, mode, ret); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ret = ORIG(fn)(file, oflag); \
|
||||
debug(STR(fn) "(\"%s\", %i) = %i", file, oflag, ret); \
|
||||
} \
|
||||
\
|
||||
if(ret >= 0) \
|
||||
{ \
|
||||
if((oflag & (O_RDONLY | O_RDWR | O_WRONLY)) != O_WRONLY) \
|
||||
{ \
|
||||
files[ret].managed = 1; \
|
||||
files[ret].pos = 0; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
int open(const char *file, int oflag, ...)
|
||||
{
|
||||
int ret;
|
||||
OPEN(ret, open, file, oflag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int open64(const char *file, int oflag, ...)
|
||||
{
|
||||
int ret;
|
||||
OPEN(ret, open64, file, oflag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
int ret = read_orig(fd, buf, count);
|
||||
debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret);
|
||||
if(ret > 0)
|
||||
{
|
||||
zzuf_fuzz(fd, buf, ret);
|
||||
files[fd].pos += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
20
src/preload.h
Normal file
20
src/preload.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* zzuf - general purpose fuzzer
|
||||
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* preload.h: preloaded library functions
|
||||
*/
|
||||
|
||||
extern int zzuf_preload(void);
|
||||
|
||||
116
src/zzuf.c
116
src/zzuf.c
@ -29,9 +29,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "random.h"
|
||||
|
||||
static void set_ld_preload(char const *);
|
||||
static void version(void);
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
static void usage(void);
|
||||
@ -39,11 +41,10 @@ static void usage(void);
|
||||
|
||||
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;
|
||||
char buf[BUFSIZ];
|
||||
char **newargv;
|
||||
long int seed = 0;
|
||||
float percent = 0.04;
|
||||
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
for(;;)
|
||||
@ -54,31 +55,23 @@ int main(int argc, char *argv[])
|
||||
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",
|
||||
int c = getopt_long(argc, argv, "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");
|
||||
int c = getopt(argc, argv, "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;
|
||||
@ -102,69 +95,52 @@ int main(int argc, char *argv[])
|
||||
int optind = 1;
|
||||
#endif
|
||||
|
||||
/* Open the files */
|
||||
if(input)
|
||||
if(optind >= argc)
|
||||
{
|
||||
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);
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(percent == -1.0)
|
||||
{
|
||||
percent = 0.1;
|
||||
fprintf(stderr, "no percent specified, using %g\n", percent);
|
||||
}
|
||||
/* Create new argv */
|
||||
newargv = malloc((argc - optind + 1) * sizeof(char *));
|
||||
memcpy(newargv, argv + optind, (argc - optind) * sizeof(char *));
|
||||
newargv[argc - optind] = (char *)NULL;
|
||||
|
||||
/* 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);
|
||||
/* Preload libzzuf.so */
|
||||
set_ld_preload(argv[0]);
|
||||
|
||||
/* Randomise shit */
|
||||
zzuf_srand(seed);
|
||||
todo = percent * 0.01 * size;
|
||||
while(todo--)
|
||||
{
|
||||
i = zzuf_rand(size);
|
||||
data[i] ^= 1 << zzuf_rand(8);
|
||||
}
|
||||
/* Set environment */
|
||||
sprintf(buf, "%lu", (unsigned long int)seed);
|
||||
setenv("ZZUF_SEED", buf, 1);
|
||||
sprintf(buf, "%g", percent);
|
||||
setenv("ZZUF_PERCENT", buf, 1);
|
||||
|
||||
/* Write result */
|
||||
fwrite(data, size, 1, out);
|
||||
fclose(out);
|
||||
/* Call our process */
|
||||
execvp(newargv[0], newargv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_ld_preload(char const *progpath)
|
||||
{
|
||||
char *libpath, *tmp;
|
||||
int len = strlen(progpath);
|
||||
|
||||
libpath = malloc(len + strlen("/.libs/libzzuf.so") + 1);
|
||||
strcpy(libpath, progpath);
|
||||
tmp = strrchr(libpath, '/');
|
||||
strcpy(tmp ? tmp + 1 : libpath, ".libs/libzzuf.so");
|
||||
if(access(libpath, R_OK) == 0)
|
||||
{
|
||||
setenv("LD_PRELOAD", libpath, 1);
|
||||
return;
|
||||
}
|
||||
free(libpath);
|
||||
|
||||
/* FIXME: use real path */
|
||||
setenv("LD_PRELOAD", "/usr/lib/zzuf/libzzuf.so", 1);
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
{
|
||||
printf("zzuf %s by Sam Hocevar <sam@zoy.org>\n", VERSION);
|
||||
@ -173,8 +149,7 @@ static void version(void)
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Usage: zzuf [ -vh ] [ -i input ] [ -o output ]\n");
|
||||
printf(" [ -p percent ] [ -s seed ]\n");
|
||||
printf("Usage: zzuf [ -vh ] [ -p percent ] [ -s seed ] PROG ARGS...\n");
|
||||
# ifdef HAVE_GETOPT_LONG
|
||||
printf(" -h, --help display this help and exit\n");
|
||||
printf(" -v, --version output version information and exit\n");
|
||||
@ -185,4 +160,3 @@ static void usage(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user