diff --git a/README b/README index 069b1d4..a7a3458 100644 --- a/README +++ b/README @@ -27,7 +27,7 @@ Fuzz the input of VLC, using file movie.avi as the original input, and generate fuzzy-movie.avi which is a file that can be fed to VLC to reproduce the behaviour without using zzuf: - # zzuf -s 87423 -r 0.01 vlc -- movie.avi + # zzuf -s 87423 -r 0.01 vlc movie.avi # zzuf -s 87423 -r 0.01 cp movie.avi fuzzy-movie.avi # vlc fuzzy-movie.avi diff --git a/src/Makefile.am b/src/Makefile.am index 35b91c1..ab5fbaa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,8 @@ zzuf_SOURCES = zzuf.c zzuf_CPPFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" pkglib_LTLIBRARIES = libzzuf.la -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_SOURCES = libzzuf.c libzzuf.h fuzz.c fuzz.h debug.c debug.h \ + load-fd.c load-stream.c load..h random.c random.h libzzuf_la_LDFLAGS = -module libzzuf_la_LIBADD = -ldl diff --git a/src/libzzuf.c b/src/libzzuf.c index 9219ac8..1794615 100644 --- a/src/libzzuf.c +++ b/src/libzzuf.c @@ -35,7 +35,7 @@ #include "libzzuf.h" #include "debug.h" -#include "preload.h" +#include "load.h" /* Global variables */ int _zzuf_ready = 0; @@ -87,7 +87,8 @@ void zzuf_init(void) for(i = 0; i < MAXFD; i++) files[i].managed = 0; - zzuf_preload_libc(); + zzuf_load_fd(); + zzuf_load_stream(); _zzuf_ready = 1; diff --git a/src/preload.c b/src/load-fd.c similarity index 58% rename from src/preload.c rename to src/load-fd.c index 8e535b9..f700167 100644 --- a/src/preload.c +++ b/src/load-fd.c @@ -13,7 +13,7 @@ */ /* - * preload.c: preloaded library functions + * load-fd.c: loaded file descriptor functions */ #include "config.h" @@ -28,29 +28,21 @@ #elif defined HAVE_INTTYPES_H # include #endif -#include +#include +#include +#include + #include #include -#include #include -#include - #include -#include #include "libzzuf.h" #include "debug.h" #include "fuzz.h" -#include "preload.h" +#include "load.h" /* Library functions that we divert */ -static FILE * (*fopen_orig) (const char *path, const char *mode); -static FILE * (*fopen64_orig) (const char *path, const char *mode); -static int (*fseek_orig) (FILE *stream, long offset, int whence); -static size_t (*fread_orig) (void *ptr, size_t size, size_t nmemb, - FILE *stream); -static int (*fclose_orig) (FILE *fp); - 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); @@ -58,24 +50,8 @@ static off_t (*lseek_orig) (int fd, off_t offset, int whence); static off64_t (*lseek64_orig) (int fd, off64_t offset, int whence); static int (*close_orig) (int fd); -#define STR(x) #x -#define ORIG(x) x##_orig - -#define LOADSYM(x) \ - do { \ - ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \ - if(!ORIG(x)) \ - abort(); \ - } while(0) - -void zzuf_preload_libc(void) +void zzuf_load_fd(void) { - LOADSYM(fopen); - LOADSYM(fopen64); - LOADSYM(fseek); - LOADSYM(fread); - LOADSYM(fclose); - LOADSYM(open); LOADSYM(open64); LOADSYM(read); @@ -84,115 +60,6 @@ void zzuf_preload_libc(void) LOADSYM(close); } -/* Our function wrappers */ -#define FOPEN(fn) \ - do \ - { \ - if(!_zzuf_ready) \ - LOADSYM(fn); \ - ret = ORIG(fn)(path, mode); \ - if(!_zzuf_ready) \ - return ret; \ - if(ret) \ - { \ - if(_zzuf_include && \ - regexec(_zzuf_include, path, 0, NULL, 0) == REG_NOMATCH) \ - /* not included: ignore */ ; \ - else if(_zzuf_exclude && \ - regexec(_zzuf_exclude, path, 0, NULL, 0) != REG_NOMATCH) \ - /* excluded: ignore */ ; \ - else \ - { \ - int fd = fileno(ret); \ - files[fd].managed = 1; \ - files[fd].pos = 0; \ - debug(STR(fn) "(\"%s\", \"%s\") = %p", path, mode, ret); \ - } \ - } \ - } while(0) - -FILE *fopen(const char *path, const char *mode) -{ - FILE *ret; FOPEN(fopen); return ret; -} - -FILE *fopen64(const char *path, const char *mode) -{ - FILE *ret; FOPEN(fopen64); return ret; -} - -int fseek(FILE *stream, long offset, int whence) -{ - int ret, fd; - - if(!_zzuf_ready) - LOADSYM(fseek); - ret = fseek_orig(stream, offset, whence); - if(!_zzuf_ready) - return ret; - - fd = fileno(stream); - if(!files[fd].managed) - return ret; - - debug("fseek(%p, %li, %i) = %i", stream, offset, whence, ret); - if(ret == 0) - { - switch(whence) - { - case SEEK_SET: files[fd].pos = offset; break; - case SEEK_CUR: files[fd].pos += offset; break; - case SEEK_END: files[fd].pos = ftell(stream); break; - } - } - return ret; -} - -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - size_t ret; - int fd; - - if(!_zzuf_ready) - LOADSYM(fread); - ret = fread_orig(ptr, size, nmemb, stream); - if(!_zzuf_ready) - return ret; - - fd = fileno(stream); - if(!files[fd].managed) - return ret; - - debug("fread(%p, %li, %li, %p) = %li", - ptr, (long int)size, (long int)nmemb, stream, (long int)ret); - if(ret > 0) - { - zzuf_fuzz(fd, ptr, ret * size); - files[fd].pos += ret * size; - } - return ret; -} - -int fclose(FILE *fp) -{ - int ret, fd; - - if(!_zzuf_ready) - LOADSYM(fclose); - fd = fileno(fp); - ret = fclose_orig(fp); - if(!_zzuf_ready) - return ret; - - if(!files[fd].managed) - return ret; - - debug("fclose(%p) = %i", fp, ret); - files[fd].managed = 0; - - return ret; -} - #define OPEN(fn) \ do \ { \ diff --git a/src/load-stream.c b/src/load-stream.c new file mode 100644 index 0000000..3690dc3 --- /dev/null +++ b/src/load-stream.c @@ -0,0 +1,165 @@ +/* + * 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. + */ + +/* + * load-stream.c: loaded stream functions + */ + +#include "config.h" + +/* Can't remember what that's for */ +#define _GNU_SOURCE + +#if defined HAVE_STDINT_H +# include +#elif defined HAVE_INTTYPES_H +# include +#endif +#include +#include +#include + +#include + +#include "libzzuf.h" +#include "debug.h" +#include "fuzz.h" +#include "load.h" + +/* Library functions that we divert */ +static FILE * (*fopen_orig) (const char *path, const char *mode); +static FILE * (*fopen64_orig) (const char *path, const char *mode); +static int (*fseek_orig) (FILE *stream, long offset, int whence); +static size_t (*fread_orig) (void *ptr, size_t size, size_t nmemb, + FILE *stream); +static int (*fclose_orig) (FILE *fp); + +void zzuf_load_stream(void) +{ + LOADSYM(fopen); + LOADSYM(fopen64); + LOADSYM(fseek); + LOADSYM(fread); + LOADSYM(fclose); +} + +/* Our function wrappers */ +#define FOPEN(fn) \ + do \ + { \ + if(!_zzuf_ready) \ + LOADSYM(fn); \ + ret = ORIG(fn)(path, mode); \ + if(!_zzuf_ready) \ + return ret; \ + if(ret) \ + { \ + if(_zzuf_include && \ + regexec(_zzuf_include, path, 0, NULL, 0) == REG_NOMATCH) \ + /* not included: ignore */ ; \ + else if(_zzuf_exclude && \ + regexec(_zzuf_exclude, path, 0, NULL, 0) != REG_NOMATCH) \ + /* excluded: ignore */ ; \ + else \ + { \ + int fd = fileno(ret); \ + files[fd].managed = 1; \ + files[fd].pos = 0; \ + debug(STR(fn) "(\"%s\", \"%s\") = %p", path, mode, ret); \ + } \ + } \ + } while(0) + +FILE *fopen(const char *path, const char *mode) +{ + FILE *ret; FOPEN(fopen); return ret; +} + +FILE *fopen64(const char *path, const char *mode) +{ + FILE *ret; FOPEN(fopen64); return ret; +} + +int fseek(FILE *stream, long offset, int whence) +{ + int ret, fd; + + if(!_zzuf_ready) + LOADSYM(fseek); + ret = fseek_orig(stream, offset, whence); + if(!_zzuf_ready) + return ret; + + fd = fileno(stream); + if(!files[fd].managed) + return ret; + + debug("fseek(%p, %li, %i) = %i", stream, offset, whence, ret); + if(ret == 0) + { + switch(whence) + { + case SEEK_SET: files[fd].pos = offset; break; + case SEEK_CUR: files[fd].pos += offset; break; + case SEEK_END: files[fd].pos = ftell(stream); break; + } + } + return ret; +} + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t ret; + int fd; + + if(!_zzuf_ready) + LOADSYM(fread); + ret = fread_orig(ptr, size, nmemb, stream); + if(!_zzuf_ready) + return ret; + + fd = fileno(stream); + if(!files[fd].managed) + return ret; + + debug("fread(%p, %li, %li, %p) = %li", + ptr, (long int)size, (long int)nmemb, stream, (long int)ret); + if(ret > 0) + { + zzuf_fuzz(fd, ptr, ret * size); + files[fd].pos += ret * size; + } + return ret; +} + +int fclose(FILE *fp) +{ + int ret, fd; + + if(!_zzuf_ready) + LOADSYM(fclose); + fd = fileno(fp); + ret = fclose_orig(fp); + if(!_zzuf_ready) + return ret; + + if(!files[fd].managed) + return ret; + + debug("fclose(%p) = %i", fp, ret); + files[fd].managed = 0; + + return ret; +} + diff --git a/src/preload.h b/src/load.h similarity index 67% rename from src/preload.h rename to src/load.h index 8b0aa8d..c666e35 100644 --- a/src/preload.h +++ b/src/load.h @@ -16,5 +16,16 @@ * preload.h: preloaded library functions */ -extern void zzuf_preload_libc(void); +#define STR(x) #x +#define ORIG(x) x##_orig + +#define LOADSYM(x) \ + do { \ + ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \ + if(!ORIG(x)) \ + abort(); \ + } while(0) + +extern void zzuf_load_fd(void); +extern void zzuf_load_stream(void);