Changeset 1702


Ignore:
Timestamp:
01/24/07 16:06:17 (6 years ago)
Author:
sam
Message:
  • Added DLL injection to the Win32 port attempt.
Location:
zzuf/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/build-win32

    r1701 r1702  
    1919cd "${BUILDDIR}" 
    2020# Build for win32 
    21 "${SRCDIR}/configure" --host=i586-mingw32msvc --program-suffix=.exe --prefix=/ --bindir=/bin --libdir=/lib 
     21"${SRCDIR}/configure" --host=i586-mingw32msvc --prefix=/ --bindir=/bin --libdir=/lib 
    2222 
    2323make pkglibdir=/lib pkgdatadir=/data bindir=/bin 
    2424 
    2525make install DESTDIR="${INSTALLDIR}" pkglibdir=/lib/ pkgdatadir=/ bindir=/bin/ 
    26 (cd "${SRCDIR}" && rm -Rf "${BUILDDIR}") 
     26rm -Rf "${BUILDDIR}" 
    2727 
    2828# Pack the directory 
     29cd "${SRCDIR}" 
    2930zip "${DIRNAME}.zip" `find "${DIRNAME}"` 
    3031rm -Rf "${INSTALLDIR}" 
  • zzuf/trunk/configure.ac

    r1701 r1702  
    1717case "${host_os}" in 
    1818  *mingw32*) 
    19     WIN32DLL_LDFLAGS="-Wl,-l,imagehlp" 
     19    DLL_LDFLAGS="-Wl,-l,imagehlp" # Trick libtool here 
     20    WINSOCK2_LIBS="-lws2_32" 
    2021    ac_cv_func_recv=yes 
    2122    ac_cv_func_recvfrom=yes 
     
    2425    ;; 
    2526esac 
    26 AC_SUBST(WIN32DLL_LDFLAGS) 
     27AC_SUBST(WINSOCK2_LIBS) 
     28AC_SUBST(DLL_LDFLAGS) 
    2729 
    28 AC_CHECK_HEADERS(windows.h winsock2.h inttypes.h stdint.h getopt.h libc.h malloc.h dlfcn.h regex.h sys/socket.h sys/uio.h aio.h sys/mman.h sys/wait.h sys/resource.h) 
     30AC_CHECK_HEADERS(windows.h winsock2.h io.h inttypes.h stdint.h getopt.h libc.h malloc.h dlfcn.h regex.h sys/socket.h sys/uio.h aio.h sys/mman.h sys/wait.h sys/resource.h) 
    2931 
     32AC_CHECK_FUNCS(setenv waitpid setrlimit gettimeofday fork kill pipe _pipe) 
    3033AC_CHECK_FUNCS(open64 lseek64 mmap64 fopen64 fseeko _IO_getc getline getdelim __getdelim fgetln __srefill map_fd memalign posix_memalign aio_read accept socket readv pread recv recvfrom recvmsg mmap valloc sigaction) 
    3134 
  • zzuf/trunk/src/Makefile.am

    r1701 r1702  
    66zzuf_SOURCES = zzuf.c $(COMMON) opts.c opts.h md5.c md5.h timer.c timer.h 
    77zzuf_CFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" 
    8 zzuf_LDFLAGS = $(MATH_LIBS) 
     8zzuf_LDFLAGS = $(MATH_LIBS) $(WINSOCK2_LIBS) 
    99 
    1010pkglib_LTLIBRARIES = libzzuf.la 
    1111libzzuf_la_SOURCES = libzzuf.c libzzuf.h $(COMMON) debug.c debug.h sys.c sys.h \ 
    1212                     lib-fd.c lib-mem.c lib-signal.c lib-stream.c lib-load.h 
    13 libzzuf_la_LDFLAGS = -avoid-version -no-undefined $(WIN32DLL_LDFLAGS) 
     13libzzuf_la_LDFLAGS = -avoid-version -no-undefined $(DLL_LDFLAGS) 
    1414libzzuf_la_LIBADD = $(GETOPT_LIBS) $(DL_LIBS) $(MATH_LIBS) 
    1515 
  • zzuf/trunk/src/opts.h

    r1692 r1702  
    1919struct opts 
    2020{ 
    21     char **newargv; 
     21    char const **newargv; 
    2222    char *protect, *refuse; 
    2323    uint32_t seed; 
  • zzuf/trunk/src/timer.c

    r1657 r1702  
    2424#   include <inttypes.h> 
    2525#endif 
     26#if defined HAVE_WINDOWS_H 
     27#   include <windows.h> 
     28#endif 
    2629#include <stdio.h> 
    2730#include <sys/time.h> 
     
    3235int64_t _zz_time(void) 
    3336{ 
     37#if defined HAVE_GETTIMEOFDAY 
    3438    struct timeval tv; 
    3539    gettimeofday(&tv, NULL); 
    3640    return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; 
     41#else 
     42    static CRITICAL_SECTION cs; 
     43    static unsigned long int prev; 
     44    static int64_t tv_base = 0; 
     45    unsigned long int tv_msec; 
     46 
     47    if(tv_base == 0) 
     48    { 
     49        tv_base = 1; 
     50        prev = 0; 
     51        InitializeCriticalSection(&cs); 
     52    } 
     53 
     54    EnterCriticalSection(&cs); 
     55    tv_msec = GetTickCount(); 
     56    if(tv_msec < prev) 
     57        tv_base += 0x100000000LL; /* We wrapped */ 
     58    prev = tv_msec; 
     59    LeaveCriticalSection(&cs); 
     60 
     61    return (tv_base + tv_msec) * 1000; 
     62#endif 
    3763} 
    3864 
  • zzuf/trunk/src/zzuf.c

    r1701 r1702  
    3838#if defined HAVE_WINSOCK2_H 
    3939#   include <winsock2.h> 
     40#endif 
     41#if defined HAVE_IO_H 
    4042#   include <io.h> 
    4143#endif 
    4244#include <string.h> 
     45#include <fcntl.h> 
    4346#include <errno.h> 
    4447#include <signal.h> 
     
    6366#endif 
    6467 
    65 static void loop_stdin(struct opts *opts); 
    66  
    67 static void spawn_children(struct opts *opts); 
    68 static void clean_children(struct opts *opts); 
    69 static void read_children(struct opts *opts); 
    70  
     68static void loop_stdin(struct opts *); 
     69static int run_process(char const *[]); 
     70 
     71static void spawn_children(struct opts *); 
     72static void clean_children(struct opts *); 
     73static void read_children(struct opts *); 
     74 
     75#if !defined HAVE_GETENV 
     76static void setenv(char const *, char const *, int); 
     77#endif 
     78#if defined HAVE_WAITPID 
    7179static char const *sig2str(int); 
     80#endif 
     81#if defined HAVE_WINDOWS_H 
     82static int dll_inject(void *, void *); 
     83static void *get_entry(char const *); 
     84#endif 
    7285#if defined HAVE_REGEX_H 
    7386static char *merge_regex(char *, char *); 
    7487static char *merge_file(char *, char *); 
    7588#endif 
    76 static void set_environment(char const *); 
    7789static void version(void); 
    7890#if defined HAVE_GETOPT_H 
     
    8092#endif 
    8193 
     94#if defined HAVE_WINDOWS_H 
     95static inline void addcpy(void *buf, void *x) 
     96{ 
     97    memcpy(buf, &x, 4); 
     98} 
     99#endif 
     100 
    82101#define ZZUF_FD_SET(fd, p_fdset, maxfd) \ 
    83102    if(fd >= 0) \ 
    84103    { \ 
    85         FD_SET(fd, p_fdset); \ 
     104        FD_SET((unsigned int)fd, p_fdset); \ 
    86105        if(fd > maxfd) \ 
    87106            maxfd = fd; \ 
     
    212231            opts->md5 = 1; 
    213232            break; 
     233#if defined HAVE_SETRLIMIT 
    214234        case 'M': /* --max-memory */ 
    215235            setenv("ZZUF_MEMORY", "1", 1); 
    216236            opts->maxmem = atoi(optarg); 
    217237            break; 
     238#endif 
    218239        case 'n': /* --network */ 
    219240            setenv("ZZUF_NETWORK", "1", 1); 
     
    325346    opts->nchild = 0; 
    326347 
    327     /* Preload libzzuf.so */ 
    328     set_environment(argv[0]); 
    329  
    330348    /* Create new argv */ 
    331349    opts->newargv = malloc((argc - optind + 1) * sizeof(char *)); 
     
    489507    /* Prepare communication pipe */ 
    490508    for(j = 0; j < 3; j++) 
    491         if(pipe(fd[j]) == -1) 
     509    { 
     510        int ret; 
     511#if defined HAVE_PIPE 
     512        ret = pipe(fd[j]); 
     513#elif defined HAVE__PIPE 
     514        ret = _pipe(fd[j], 256, _O_BINARY); 
     515#endif 
     516        if(ret < 0) 
    492517        { 
    493518            perror("pipe"); 
    494519            return; 
    495520        } 
    496  
     521    } 
     522 
     523#if defined HAVE_FORK 
    497524    /* Fork and launch child */ 
    498525    pid = fork(); 
    499     switch(pid) 
    500     { 
    501         case -1: 
    502             perror("fork"); 
     526    if(pid < -1) 
     527    { 
     528        perror("fork"); 
     529        return; 
     530    } 
     531#else 
     532    pid = 0; 
     533#endif 
     534 
     535    if(pid == 0) 
     536    { 
     537#if defined HAVE_SETRLIMIT 
     538        if(opts->maxmem >= 0) 
     539        { 
     540            struct rlimit rlim; 
     541            rlim.rlim_cur = opts->maxmem * 1000000; 
     542            rlim.rlim_max = opts->maxmem * 1000000; 
     543            setrlimit(RLIMIT_AS, &rlim); 
     544        } 
     545#endif 
     546 
     547#if defined HAVE_FORK 
     548        /* We loop in reverse order so that files[0] is done last, 
     549         * just in case one of the other dup2()ed fds had the value */ 
     550        for(j = 3; j--; ) 
     551        { 
     552            close(fd[j][0]); 
     553            if(fd[j][1] != files[j]) 
     554            { 
     555                dup2(fd[j][1], files[j]); 
     556                close(fd[j][1]); 
     557            } 
     558        } 
     559#endif 
     560 
     561        /* Set environment variables */ 
     562        sprintf(buf, "%i", opts->seed); 
     563        setenv("ZZUF_SEED", buf, 1); 
     564        sprintf(buf, "%g", opts->minratio); 
     565        setenv("ZZUF_MINRATIO", buf, 1); 
     566        sprintf(buf, "%g", opts->maxratio); 
     567        setenv("ZZUF_MAXRATIO", buf, 1); 
     568 
     569#if defined HAVE_FORK 
     570        if(run_process(opts->newargv) < 0) 
     571            exit(EXIT_FAILURE); 
     572        exit(EXIT_SUCCESS); 
     573#else 
     574        if(run_process(opts->newargv) < 0) 
    503575            return; 
    504         case 0: 
    505             /* We’re the child */ 
    506             if(opts->maxmem >= 0) 
    507             { 
    508                 struct rlimit rlim; 
    509                 rlim.rlim_cur = opts->maxmem * 1000000; 
    510                 rlim.rlim_max = opts->maxmem * 1000000; 
    511                 setrlimit(RLIMIT_AS, &rlim); 
    512             } 
    513  
    514             /* We loop in reverse order so that files[0] is done last, 
    515              * just in case one of the other dup2()ed fds had the value */ 
    516             for(j = 3; j--; ) 
    517             { 
    518                 close(fd[j][0]); 
    519                 if(fd[j][1] != files[j]) 
    520                 { 
    521                     dup2(fd[j][1], files[j]); 
    522                     close(fd[j][1]); 
    523                 } 
    524             } 
    525  
    526             /* Set environment variables */ 
    527             sprintf(buf, "%i", opts->seed); 
    528             setenv("ZZUF_SEED", buf, 1); 
    529             sprintf(buf, "%g", opts->minratio); 
    530             setenv("ZZUF_MINRATIO", buf, 1); 
    531             sprintf(buf, "%g", opts->maxratio); 
    532             setenv("ZZUF_MAXRATIO", buf, 1); 
    533  
    534             /* Run our process */ 
    535             if(execvp(opts->newargv[0], opts->newargv)) 
    536             { 
    537                 perror(opts->newargv[0]); 
    538                 exit(EXIT_FAILURE); 
    539             } 
    540             return; 
     576#endif 
    541577    } 
    542578 
     
    570606static void clean_children(struct opts *opts) 
    571607{ 
     608#if defined HAVE_KILL 
    572609    int64_t now = _zz_time(); 
     610#endif 
    573611    int i, j; 
    574612 
     613#if defined HAVE_KILL 
    575614    /* Terminate children if necessary */ 
    576615    for(i = 0; i < opts->maxchild; i++) 
     
    617656        } 
    618657    } 
     658#endif 
    619659 
    620660    /* Collect dead children */ 
     
    622662    { 
    623663        uint8_t md5sum[16]; 
     664#if defined HAVE_WAITPID 
    624665        int status; 
    625666        pid_t pid; 
     667#endif 
    626668 
    627669        if(opts->child[i].status != STATUS_SIGKILL 
     
    630672            continue; 
    631673 
     674#if defined HAVE_WAITPID 
    632675        pid = waitpid(opts->child[i].pid, &status, WNOHANG); 
    633676        if(pid <= 0) 
     
    652695            opts->crashes++; 
    653696        } 
     697#endif 
    654698 
    655699        for(j = 0; j < 3; j++) 
     
    694738 
    695739    ret = select(maxfd + 1, &fdset, NULL, NULL, &tv); 
    696     if(ret < 0) 
     740    if(ret < 0 && errno) 
    697741        perror("select"); 
    698742    if(ret <= 0) 
     
    736780} 
    737781 
     782#if !defined HAVE_GETENV 
     783static void setenv(char const *name, char const *value, int overwrite) 
     784{ 
     785    char *str; 
     786 
     787    if(!overwrite && getenv(name)) 
     788        return; 
     789 
     790    str = malloc(strlen(name) + 1 + strlen(value) + 1); 
     791    sprintf(str, "%s=%s", name, value); 
     792    putenv(str); 
     793} 
     794#endif 
     795 
     796#if defined HAVE_WAITPID 
    738797static char const *sig2str(int signum) 
    739798{ 
     
    743802        case SIGFPE:   return " (SIGFPE)"; 
    744803        case SIGILL:   return " (SIGILL)"; 
     804#ifdef SIGQUIT 
    745805        case SIGQUIT:  return " (SIGQUIT)"; 
     806#endif 
    746807        case SIGSEGV:  return " (SIGSEGV)"; 
     808#ifdef SIGTRAP 
    747809        case SIGTRAP:  return " (SIGTRAP)"; 
     810#endif 
    748811#ifdef SIGSYS 
    749812        case SIGSYS:   return " (SIGSYS)"; 
     
    765828    return ""; 
    766829} 
    767  
    768 static void set_environment(char const *progpath) 
    769 { 
     830#endif 
     831 
     832static int run_process(char const *argv[]) 
     833{ 
     834#if defined HAVE_FORK 
    770835    char *libpath, *tmp; 
    771     int ret, len = strlen(progpath); 
    772 #if defined __APPLE__ 
    773 #   define FILENAME "libzzuf.dylib" 
    774 #   define EXTRAINFO "" 
    775 #   define PRELOAD "DYLD_INSERT_LIBRARIES" 
     836    int ret, len = strlen(argv[0]); 
     837#   if defined __APPLE__ 
     838#       define FILENAME "libzzuf.dylib" 
     839#       define EXTRAINFO "" 
     840#       define PRELOAD "DYLD_INSERT_LIBRARIES" 
    776841    setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1); 
    777 #elif defined __osf__ 
    778 #   define FILENAME "libzzuf.so" 
    779 #   define EXTRAINFO ":DEFAULT" 
    780 #   define PRELOAD "_RLD_LIST" 
    781 #else 
    782 #   define FILENAME "libzzuf.so" 
    783 #   define EXTRAINFO "" 
    784 #   define PRELOAD "LD_PRELOAD" 
    785 #endif 
     842#   elif defined __osf__ 
     843#       define FILENAME "libzzuf.so" 
     844#       define EXTRAINFO ":DEFAULT" 
     845#       define PRELOAD "_RLD_LIST" 
     846#   else 
     847#       define FILENAME "libzzuf.so" 
     848#       define EXTRAINFO "" 
     849#       define PRELOAD "LD_PRELOAD" 
     850#   endif 
    786851 
    787852    libpath = malloc(len + strlen("/.libs/" FILENAME EXTRAINFO) + 1); 
    788     strcpy(libpath, progpath); 
     853    strcpy(libpath, argv[0]); 
    789854 
    790855    tmp = strrchr(libpath, '/'); 
     
    798863        setenv(PRELOAD, LIBDIR "/" FILENAME EXTRAINFO, 1); 
    799864    free(libpath); 
    800 } 
     865 
     866    if(execvp(argv[0], argv)) 
     867    { 
     868        perror(argv[0]); 
     869        return -1; 
     870    } 
     871 
     872    return 0; 
     873#elif HAVE_WINDOWS_H 
     874    PROCESS_INFORMATION pinfo; 
     875    STARTUPINFO sinfo; 
     876    void *epaddr; 
     877    int ret; 
     878 
     879    /* Get entry point */ 
     880    epaddr = get_entry(argv[0]); 
     881    if(!epaddr) 
     882        return -1; 
     883     
     884    memset(&sinfo, 0, sizeof(sinfo)); 
     885    sinfo.cb = sizeof(sinfo); 
     886    ret = CreateProcess(NULL, argv[0], NULL, NULL, FALSE, 
     887                        CREATE_SUSPENDED, NULL, NULL, &sinfo, &pinfo); 
     888    if(!ret) 
     889        return -1; 
     890 
     891    /* Insert the replacement code */ 
     892    ret = dll_inject(pinfo.hProcess, epaddr); 
     893    if(ret < 0) 
     894    { 
     895        TerminateProcess(pinfo.hProcess, -1); 
     896        return -1; 
     897    } 
     898 
     899    ret = ResumeThread(pinfo.hThread); 
     900    if(ret < 0) 
     901    { 
     902        TerminateProcess(pinfo.hProcess, -1); 
     903        return -1; 
     904    } 
     905 
     906    return 0; 
     907#else 
     908    return -1; 
     909#endif 
     910} 
     911 
     912#if defined HAVE_WINDOWS_H 
     913static int dll_inject(void *process, void *epaddr) 
     914{ 
     915    uint8_t old_ep[7]; 
     916    uint8_t new_ep[] = "\xb8<01>\xff\xe0"; 
     917    uint8_t loader[] = "libzzuf.dll\0<0000c>\xb8<14>\x50\xb8<1a>\xff\xd0" 
     918                       "\xb8\0\0\0\0\x50\xb8\x07\x00\x00\x00\x50\xb8<2d>" 
     919                       "\x50\xb8<33>\x50\xb8<39>\xff\xd0\x50\xb8<41>\xff" 
     920                       "\xd0\xb8<48>\xff\xe0"; 
     921    void *lib; 
     922    uint8_t *loaderaddr; 
     923    DWORD tmp; 
     924 
     925    /* Save the old entry-point code */ 
     926    ReadProcessMemory(process, epaddr, old_ep, 7, &tmp); 
     927    if(tmp != 7) 
     928        return -1; 
     929 
     930    loaderaddr = VirtualAllocEx(process, NULL, 78, MEM_COMMIT, 
     931                                PAGE_EXECUTE_READWRITE); 
     932    if(!loaderaddr) 
     933        return -1; 
     934 
     935    addcpy(new_ep + 0x01, loaderaddr + 0x0c + 7); 
     936    WriteProcessMemory(process, epaddr, new_ep, 7, &tmp); 
     937    if(tmp != 7) 
     938        return -1; 
     939 
     940    lib = LoadLibrary("kernel32.dll"); 
     941    if(!lib) 
     942        return -1; 
     943 
     944    memcpy(loader + 0x0c, old_ep, 7); 
     945    addcpy(loader + 0x14, loaderaddr + 0x00); /* offset for dll string */ 
     946    addcpy(loader + 0x1a, GetProcAddress(lib, "LoadLibraryA")); 
     947    addcpy(loader + 0x2d, loaderaddr + 0x0c); 
     948    addcpy(loader + 0x33, epaddr); 
     949    addcpy(loader + 0x39, GetProcAddress(lib, "GetCurrentProcess")); 
     950    addcpy(loader + 0x41, GetProcAddress(lib, "WriteProcessMemory")); 
     951    addcpy(loader + 0x48, epaddr); 
     952    FreeLibrary(lib); 
     953 
     954    WriteProcessMemory(process, loaderaddr, loader, 78, &tmp); 
     955    if(tmp != 78) 
     956        return -1; 
     957 
     958    return 0; 
     959} 
     960 
     961static void *get_entry(char const *name) 
     962{ 
     963    PIMAGE_DOS_HEADER dos; 
     964    PIMAGE_NT_HEADERS nt; 
     965    void *file, *map, *base; 
     966 
     967    file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, 
     968                      NULL, OPEN_EXISTING, 0, NULL); 
     969    if(file == INVALID_HANDLE_VALUE) 
     970        return NULL; 
     971 
     972    map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL); 
     973    if(!map) 
     974    { 
     975        CloseHandle(file); 
     976        return NULL; 
     977    } 
     978 
     979    base = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0); 
     980    if(!base) 
     981    { 
     982        CloseHandle(map); 
     983        CloseHandle(file); 
     984        return NULL; 
     985    } 
     986 
     987    /* Sanity checks */ 
     988    dos = (PIMAGE_DOS_HEADER)base; 
     989    nt = (PIMAGE_NT_HEADERS)((char *)base + dos->e_lfanew); 
     990    if(dos->e_magic != IMAGE_DOS_SIGNATURE 
     991      || nt->Signature != IMAGE_NT_SIGNATURE 
     992      || nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 
     993      || nt->OptionalHeader.Magic != 0x10b /* IMAGE_NT_OPTIONAL_HDR32_MAGIC */) 
     994    { 
     995        UnmapViewOfFile(base); 
     996        CloseHandle(map); 
     997        CloseHandle(file); 
     998        return NULL; 
     999    } 
     1000 
     1001    return (char *)nt->OptionalHeader.ImageBase + 
     1002                           nt->OptionalHeader.AddressOfEntryPoint; 
     1003} 
     1004#endif 
    8011005 
    8021006static void version(void) 
     
    8541058#endif 
    8551059    printf("  -m, --md5                 compute the output's MD5 hash\n"); 
     1060#if defined HAVE_SETRLIMIT 
    8561061    printf("  -M, --max-memory <n>      maximum child virtual memory size in MB\n"); 
     1062#endif 
    8571063    printf("  -n, --network             fuzz network input\n"); 
    8581064    printf("  -P, --protect <list>      protect bytes and characters in <list>\n"); 
     
    8871093#endif 
    8881094    printf("  -m               compute the output's MD5 hash\n"); 
     1095#if defined HAVE_SETRLIMIT 
    8891096    printf("  -M               maximum child virtual memory size in MB\n"); 
     1097#endif 
    8901098    printf("  -n               fuzz network input\n"); 
    8911099    printf("  -P <list>        protect bytes and characters in <list>\n"); 
Note: See TracChangeset for help on using the changeset viewer.