Changeset 1470


Ignore:
Timestamp:
Dec 15, 2006, 1:26:01 AM (16 years ago)
Author:
Sam Hocevar
Message:
  • First somewhat working version.
Location:
zzuf/trunk
Files:
6 added
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/README

    r1463 r1470  
     1About Zzuf
     2==========
     3Zzuf is a transparent application input fuzzer. It works by intercepting
     4file operations and changing random bits in the program's input.
     5
  • zzuf/trunk/TODO

    r1463 r1470  
     1  * Only very basic support for [f]open/[f]read, no seek, no close, etc.
  • zzuf/trunk/src/Makefile.am

    r1466 r1470  
    11
    22bin_PROGRAMS = zzuf
    3 zzuf_SOURCES = zzuf.c random.c
     3zzuf_SOURCES = zzuf.c
    44
    55pkglib_LTLIBRARIES = libzzuf.la
    6 libzzuf_la_SOURCES = libzzuf.c
     6libzzuf_la_SOURCES = libzzuf.c libzzuf.h fuzz.c fuzz.h debug.c debug.h preload.c preload.h random.c random.h
    77libzzuf_la_LDFLAGS = -module
    88libzzuf_la_LIBADD = -ldl
  • zzuf/trunk/src/libzzuf.c

    r1467 r1470  
    2626#endif
    2727#include <stdio.h>
     28#include <unistd.h>
    2829#include <stdlib.h>
    2930#include <fcntl.h>
     31#include <errno.h>
    3032
    3133#include <stdarg.h>
    3234#include <dlfcn.h>
    3335
    34 #define STR(x) #x
    35 #define ORIG(x) x##_orig
    36 #define LOADSYM(x) \
    37     do { \
    38         ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \
    39         if(!ORIG(x)) \
    40         { \
    41             debug("could not load %s", STR(x)); \
    42             abort(); \
    43         } \
    44     } while(0)
     36#include "libzzuf.h"
     37#include "debug.h"
     38#include "preload.h"
    4539
    46 static int do_debug = 0;
    47 static void debug(const char *format, ...)
    48 {
    49     if(!do_debug)
    50         return;
     40/* Global variables */
     41int   _zzuf_debug   = 0;
     42int   _zzuf_seed    = 0;
     43float _zzuf_percent = 0.04f;
    5144
    52     va_list args;
    53     va_start(args, format);
    54     fprintf(stderr, "** zzuf debug ** ");
    55     vfprintf(stderr, format, args);
    56     fprintf(stderr, "\n");
    57     va_end(args);
    58 }
    59 
    60 /* Library functions that we divert */
    61 static FILE * (*fopen_orig)  (const char *path, const char *mode);
    62 static int    (*open_orig)   (const char *file, int oflag, ...);
    63 static int    (*open64_orig) (const char *file, int oflag, ...);
     45#define MAXFD 1024
     46struct zzuf files[MAXFD];
    6447
    6548/* Library initialisation shit */
    66 void zzufinit(void) __attribute__((constructor));
    67 void zzufinit(void)
     49void zzuf_init(void)
    6850{
    6951    char *tmp;
     52    int i;
    7053
    71     LOADSYM(fopen);
    72     LOADSYM(open);
    73     LOADSYM(open64);
     54    if(zzuf_preload())
     55        abort();
    7456
    7557    tmp = getenv("ZZUF_DEBUG");
    7658    if(tmp && *tmp)
    77         do_debug = 1;
     59        _zzuf_debug = 1;
     60
     61    tmp = getenv("ZZUF_SEED");
     62    if(tmp && *tmp)
     63        _zzuf_seed = atol(tmp);
     64
     65    tmp = getenv("ZZUF_PERCENT");
     66    if(tmp && *tmp)
     67        _zzuf_percent = atof(tmp);
     68    if(_zzuf_percent < 0.0f)
     69        _zzuf_percent = 0.0f;
     70    else if(_zzuf_percent > 1.0f)
     71        _zzuf_percent = 1.0f;
     72
     73    for(i = 0; i < MAXFD; i++)
     74        files[i].managed = 0;
    7875}
    7976
    80 /* Our function wrappers */
    81 FILE *fopen(const char *path, const char *mode)
     77/* Deinitialisation */
     78void zzuf_fini(void)
    8279{
    83     debug("fopen(\"%s\", \"%s\");", path, mode);
    84     return fopen_orig(path, mode);
     80    int i;
     81
     82    for(i = 0; i < MAXFD; i++)
     83    {
     84        if(!files[i].managed)
     85            continue;
     86
     87        /* TODO */
     88    }
    8589}
    8690
    87 #define OPEN(ret, fn, file, oflag) \
    88     do { if(oflag & O_CREAT) \
    89     { \
    90         int mode; \
    91         va_list va; \
    92         va_start(va, oflag); \
    93         mode = va_arg(va, int); \
    94         va_end(va); \
    95         debug(STR(fn) "(\"%s\", %i, %i);", file, oflag, mode); \
    96         ret = ORIG(fn)(file, oflag, mode); \
    97     } \
    98     else \
    99     { \
    100         debug(STR(fn) "(\"%s\", %i);", file, oflag); \
    101         ret = ORIG(fn)(file, oflag); \
    102     } } while(0)
    103 
    104 int open(const char *file, int oflag, ...)
    105 {
    106     int ret;
    107     OPEN(ret, open, file, oflag);
    108     return ret;
    109 }
    110 
    111 int open64(const char *file, int oflag, ...)
    112 {
    113     int ret;
    114     OPEN(ret, open64, file, oflag);
    115     return ret;
    116 }
    117 
  • zzuf/trunk/src/preload.c

    r1469 r1470  
    1414
    1515/*
    16  *  libzzuf.c: preloaded wrapper library
     16 *  preload.c: preloaded library functions
    1717 */
    1818
     
    2626#endif
    2727#include <stdio.h>
     28#include <unistd.h>
    2829#include <stdlib.h>
    2930#include <fcntl.h>
     31#include <errno.h>
    3032
    3133#include <stdarg.h>
    3234#include <dlfcn.h>
    3335
     36#include "libzzuf.h"
     37#include "debug.h"
     38#include "fuzz.h"
     39#include "preload.h"
     40
     41/* Library functions that we divert */
     42static FILE *  (*fopen_orig)  (const char *path, const char *mode);
     43static size_t  (*fread_orig)  (void *ptr, size_t size, size_t nmemb, FILE *stream);
     44static int     (*open_orig)   (const char *file, int oflag, ...);
     45static int     (*open64_orig) (const char *file, int oflag, ...);
     46static ssize_t (*read_orig)   (int fd, void *buf, size_t count);
     47
    3448#define STR(x) #x
    3549#define ORIG(x) x##_orig
     50
    3651#define LOADSYM(x) \
    3752    do { \
    3853        ORIG(x) = dlsym(RTLD_NEXT, STR(x)); \
    3954        if(!ORIG(x)) \
    40         { \
    41             debug("could not load %s", STR(x)); \
    42             abort(); \
    43         } \
     55            return -1; \
    4456    } while(0)
    4557
    46 static int do_debug = 0;
    47 static void debug(const char *format, ...)
     58int zzuf_preload(void)
    4859{
    49     if(!do_debug)
    50         return;
    51 
    52     va_list args;
    53     va_start(args, format);
    54     fprintf(stderr, "** zzuf debug ** ");
    55     vfprintf(stderr, format, args);
    56     fprintf(stderr, "\n");
    57     va_end(args);
    58 }
    59 
    60 /* Library functions that we divert */
    61 static FILE * (*fopen_orig)  (const char *path, const char *mode);
    62 static int    (*open_orig)   (const char *file, int oflag, ...);
    63 static int    (*open64_orig) (const char *file, int oflag, ...);
    64 
    65 /* Library initialisation shit */
    66 void zzufinit(void) __attribute__((constructor));
    67 void zzufinit(void)
    68 {
    69     char *tmp;
    70 
    7160    LOADSYM(fopen);
     61    LOADSYM(fread);
    7262    LOADSYM(open);
    7363    LOADSYM(open64);
     64    LOADSYM(read);
    7465
    75     tmp = getenv("ZZUF_DEBUG");
    76     if(tmp && *tmp)
    77         do_debug = 1;
     66    debug("libzzuf initialised");
     67
     68    return 0;
    7869}
    7970
     
    8172FILE *fopen(const char *path, const char *mode)
    8273{
    83     debug("fopen(\"%s\", \"%s\");", path, mode);
    84     return fopen_orig(path, mode);
     74    FILE *f;
     75
     76    f = fopen_orig(path, mode);
     77    debug("fopen(\"%s\", \"%s\") = %p", path, mode, f);
     78    if(!f)
     79        return NULL;
     80
     81    files[fileno(f)].managed = 1;
     82    files[fileno(f)].pos = 0;
     83
     84    return f;
     85}
     86
     87size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
     88{
     89    size_t ret = fread_orig(ptr, size, nmemb, stream);
     90    debug("fread(%p, %li, %li, \"%s\") = %li",
     91          ptr, (long int)size, (long int)nmemb, stream, (long int)ret);
     92    if(ret > 0)
     93    {
     94        zzuf_fuzz(fileno(stream), ptr, ret * size);
     95        files[fileno(stream)].pos += ret * size;
     96    }
     97    return ret;
    8598}
    8699
    87100#define OPEN(ret, fn, file, oflag) \
    88     do { if(oflag & O_CREAT) \
     101    do \
    89102    { \
    90         int mode; \
    91         va_list va; \
    92         va_start(va, oflag); \
    93         mode = va_arg(va, int); \
    94         va_end(va); \
    95         debug(STR(fn) "(\"%s\", %i, %i);", file, oflag, mode); \
    96         ret = ORIG(fn)(file, oflag, mode); \
    97     } \
    98     else \
    99     { \
    100         debug(STR(fn) "(\"%s\", %i);", file, oflag); \
    101         ret = ORIG(fn)(file, oflag); \
    102     } } while(0)
     103        if(oflag & O_CREAT) \
     104        { \
     105            int mode; \
     106            va_list va; \
     107            va_start(va, oflag); \
     108            mode = va_arg(va, int); \
     109            va_end(va); \
     110            ret = ORIG(fn)(file, oflag, mode); \
     111            debug(STR(fn) "(\"%s\", %i, %i) = %i", file, oflag, mode, ret); \
     112        } \
     113        else \
     114        { \
     115            ret = ORIG(fn)(file, oflag); \
     116            debug(STR(fn) "(\"%s\", %i) = %i", file, oflag, ret); \
     117        } \
     118        \
     119        if(ret >= 0) \
     120        { \
     121            if((oflag & (O_RDONLY | O_RDWR | O_WRONLY)) != O_WRONLY) \
     122            { \
     123                files[ret].managed = 1; \
     124                files[ret].pos = 0; \
     125            } \
     126        } \
     127    } while(0)
    103128
    104129int open(const char *file, int oflag, ...)
     
    116141}
    117142
     143ssize_t read(int fd, void *buf, size_t count)
     144{
     145    int ret = read_orig(fd, buf, count);
     146    debug("read(%i, %p, %li) = %i", fd, buf, (long int)count, ret);
     147    if(ret > 0)
     148    {
     149        zzuf_fuzz(fd, buf, ret);
     150        files[fd].pos += ret;
     151    }
     152    return ret;
     153}
     154
  • zzuf/trunk/src/zzuf.c

    r1465 r1470  
    3030#include <stdlib.h>
    3131#include <unistd.h>
     32#include <string.h>
    3233
    3334#include "random.h"
    3435
     36static void set_ld_preload(char const *);
    3537static void version(void);
    3638#if defined(HAVE_GETOPT_H)
     
    4042int main(int argc, char *argv[])
    4143{
    42     char *input = NULL, *output = NULL;
    43     FILE *in, *out;
    44     char *data;
    45     long int i, todo, size, seed = -1;
    46     float percent = -1.0;
     44    char buf[BUFSIZ];
     45    char **newargv;
     46    long int seed = 0;
     47    float percent = 0.04;
    4748
    4849#if defined(HAVE_GETOPT_H)
     
    5556            {
    5657                /* Long option, needs arg, flag, short option */
    57                 { "input", 1, NULL, 'i' },
    58                 { "output", 1, NULL, 'o' },
    5958                { "seed", 1, NULL, 's' },
    6059                { "percent", 1, NULL, 'p' },
     
    6362            };
    6463
    65         int c = getopt_long(argc, argv, "i:o:s:p:hv",
     64        int c = getopt_long(argc, argv, "s:p:hv",
    6665                            long_options, &option_index);
    6766#   else
    6867#       define MOREINFO "Try `%s -h' for more information.\n"
    69         int c = getopt(argc, argv, "i:o:s:p:hv");
     68        int c = getopt(argc, argv, "s:p:hv");
    7069#   endif
    7170        if(c == -1)
     
    7473        switch(c)
    7574        {
    76         case 'i': /* --input */
    77             input = optarg;
    78             break;
    79         case 'o': /* --output */
    80             output = optarg;
    81             break;
    8275        case 's': /* --seed */
    8376            seed = atol(optarg);
     
    10396#endif
    10497
    105     /* Open the files */
    106     if(input)
     98    if(optind >= argc)
    10799    {
    108         in = fopen(input, "rb");
    109         if(!in)
    110         {
    111             fprintf(stderr, "could not open `%s'\n", input);
    112             return 1;
    113         }
    114     }
    115     else
    116         in = stdin;
    117 
    118     if(output)
    119     {
    120         out = fopen(output, "wb");
    121         if(!out)
    122         {
    123             fprintf(stderr, "could not open `%s' for writing\n", output);
    124             return 1;
    125         }
    126     }
    127     else
    128         out = stdout;
    129 
    130     /* Checking parameters */
    131     if(seed == -1)
    132     {
    133         unsigned long int a = getpid();
    134         seed = (0x7931fea7 * a) ^ (0xb7390af7 + a);
    135         fprintf(stderr, "no seed specified, using %lu\n", seed);
     100        usage();
     101        return -1;
    136102    }
    137103
    138     if(percent == -1.0)
    139     {
    140         percent = 0.1;
    141         fprintf(stderr, "no percent specified, using %g\n", percent);
    142     }
     104    /* Create new argv */
     105    newargv = malloc((argc - optind + 1) * sizeof(char *));
     106    memcpy(newargv, argv + optind, (argc - optind) * sizeof(char *));
     107    newargv[argc - optind] = (char *)NULL;
    143108
    144     /* Read file contents */
    145     fseek(in, 0, SEEK_END);
    146     size = ftell(in);
    147     data = malloc(size);
    148     fseek(in, 0, SEEK_SET);
    149     fread(data, size, 1, in);
    150     fclose(in);
     109    /* Preload libzzuf.so */
     110    set_ld_preload(argv[0]);
    151111
    152     /* Randomise shit */
    153     zzuf_srand(seed);
    154     todo = percent * 0.01 * size;
    155     while(todo--)
    156     {
    157         i = zzuf_rand(size);
    158         data[i] ^= 1 << zzuf_rand(8);
    159     }
     112    /* Set environment */
     113    sprintf(buf, "%lu", (unsigned long int)seed);
     114    setenv("ZZUF_SEED", buf, 1);
     115    sprintf(buf, "%g", percent);
     116    setenv("ZZUF_PERCENT", buf, 1);
    160117
    161     /* Write result */
    162     fwrite(data, size, 1, out);
    163     fclose(out);
     118    /* Call our process */
     119    execvp(newargv[0], newargv);
    164120
    165121    return 0;   
     122}
     123
     124static void set_ld_preload(char const *progpath)
     125{
     126    char *libpath, *tmp;
     127    int len = strlen(progpath);
     128
     129    libpath = malloc(len + strlen("/.libs/libzzuf.so") + 1);
     130    strcpy(libpath, progpath);
     131    tmp = strrchr(libpath, '/');
     132    strcpy(tmp ? tmp + 1 : libpath, ".libs/libzzuf.so");
     133    if(access(libpath, R_OK) == 0)
     134    {
     135        setenv("LD_PRELOAD", libpath, 1);
     136        return;
     137    }
     138    free(libpath);
     139
     140    /* FIXME: use real path */
     141    setenv("LD_PRELOAD", "/usr/lib/zzuf/libzzuf.so", 1);
    166142}
    167143
     
    174150static void usage(void)
    175151{
    176     printf("Usage: zzuf [ -vh ] [ -i input ] [ -o output ]\n");
    177     printf("            [ -p percent ] [ -s seed ]\n");
     152    printf("Usage: zzuf [ -vh ] [ -p percent ] [ -s seed ] PROG ARGS...\n");
    178153#   ifdef HAVE_GETOPT_LONG
    179154    printf("  -h, --help          display this help and exit\n");
     
    186161#endif
    187162
    188 
Note: See TracChangeset for help on using the changeset viewer.