From 760befa4640b007f8c8f7c34942e9b33b4cce98d Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Tue, 23 Jan 2007 15:38:18 +0000 Subject: [PATCH] * Added DLL initialisation code for Win32. --- build-win32 | 31 +++++++++++++ configure.ac | 15 ++++++- src/Makefile.am | 8 ++-- src/lib-load.h | 13 ++---- src/libzzuf.c | 31 +++++++++++++ src/libzzuf.h | 4 -- src/sys.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ src/sys.h | 20 +++++++++ src/zzuf.c | 4 ++ 9 files changed, 222 insertions(+), 18 deletions(-) create mode 100755 build-win32 create mode 100644 src/sys.c create mode 100644 src/sys.h diff --git a/build-win32 b/build-win32 new file mode 100755 index 0000000..d09f398 --- /dev/null +++ b/build-win32 @@ -0,0 +1,31 @@ +#! /bin/sh + +## Win32 cross-compilation for zzuf -- Sam Hocevar +## $Id$ + +set -x +set -e + +# Clean up our working directory +SRCDIR="`pwd`" +DIRNAME="zzuf-win32-`sed -ne 's/^AM_INIT_AUTOMAKE(.*, \(.*\)).*/\1/p' configure.ac`" +INSTALLDIR="`pwd`/${DIRNAME}" +BUILDDIR="${INSTALLDIR}/build" +rm -Rf "${INSTALLDIR}" +rm -f "${INSTALLDIR}.zip" +mkdir "${INSTALLDIR}" +mkdir "${BUILDDIR}" + +cd "${BUILDDIR}" +# Build for win32 +"${SRCDIR}/configure" --host=i586-mingw32msvc --program-suffix=.exe --prefix=/ --bindir=/bin --libdir=/lib + +make pkglibdir=/lib pkgdatadir=/data bindir=/bin + +make install DESTDIR="${INSTALLDIR}" pkglibdir=/lib/ pkgdatadir=/ bindir=/bin/ +(cd "${SRCDIR}" && rm -Rf "${BUILDDIR}") + +# Pack the directory +zip "${DIRNAME}.zip" `find "${DIRNAME}"` +rm -Rf "${INSTALLDIR}" + diff --git a/configure.ac b/configure.ac index 59ef70f..1bb00fa 100644 --- a/configure.ac +++ b/configure.ac @@ -14,8 +14,21 @@ AM_PROG_CC_C_O AC_PROG_CPP AC_PROG_LIBTOOL -AC_CHECK_HEADERS(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) +case "${host_os}" in + *mingw32*) + WIN32DLL_LDFLAGS="-Wl,-l,imagehlp" + ac_cv_func_recv=yes + ac_cv_func_recvfrom=yes + ac_cv_func_socket=yes + ac_cv_func_accept=yes + ;; +esac +AC_SUBST(WIN32DLL_LDFLAGS) + +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) + AC_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) + AC_CHECK_TYPES(sighandler_t, [], [], [#define _GNU_SOURCE #include ]) diff --git a/src/Makefile.am b/src/Makefile.am index 94e293d..eb8d702 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,11 +5,11 @@ COMMON = random.c random.h fd.c fd.h fuzz.c fuzz.h bin_PROGRAMS = zzuf zzuf_SOURCES = zzuf.c $(COMMON) opts.c opts.h md5.c md5.h timer.c timer.h zzuf_CFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" -zzuf_LDFLAGS = @MATH_LIBS@ +zzuf_LDFLAGS = $(MATH_LIBS) pkglib_LTLIBRARIES = libzzuf.la -libzzuf_la_SOURCES = libzzuf.c libzzuf.h $(COMMON) debug.c debug.h \ +libzzuf_la_SOURCES = libzzuf.c libzzuf.h $(COMMON) debug.c debug.h sys.c sys.h \ lib-fd.c lib-mem.c lib-signal.c lib-stream.c lib-load.h -libzzuf_la_LDFLAGS = -avoid-version -no-undefined -libzzuf_la_LIBADD = @GETOPT_LIBS@ @DL_LIBS@ @MATH_LIBS@ +libzzuf_la_LDFLAGS = -avoid-version -no-undefined $(WIN32DLL_LDFLAGS) +libzzuf_la_LIBADD = $(GETOPT_LIBS) $(DL_LIBS) $(MATH_LIBS) diff --git a/src/lib-load.h b/src/lib-load.h index 2847235..201bd48 100644 --- a/src/lib-load.h +++ b/src/lib-load.h @@ -13,7 +13,7 @@ */ /* - * lib-load.h: preloaded library functions + * lib-load.h: preload library functions */ /* The __func__ macro to get the current function name */ @@ -28,15 +28,10 @@ /* Symbol loading stuff */ #define STR(x) #x #define ORIG(x) x##_orig -#ifdef HAVE_DLFCN_H -# define NEW(x) x -#else -# define NEW(x) x##_new -#endif -/* TODO: do the Win32 part */ #ifdef HAVE_DLFCN_H # include +# define NEW(x) x # define LOADSYM(x) \ do { \ if(!ORIG(x)) \ @@ -45,10 +40,10 @@ abort(); \ } while(0) #else +# define NEW(x) x##_new # define LOADSYM(x) \ do { \ - if(!ORIG(x)) \ - abort(); \ + /* Nothing to do */ \ } while(0) #endif diff --git a/src/libzzuf.c b/src/libzzuf.c index 057713a..0419f88 100644 --- a/src/libzzuf.c +++ b/src/libzzuf.c @@ -24,6 +24,9 @@ #elif defined HAVE_INTTYPES_H # include #endif +#if defined HAVE_WINDOWS_H +# include +#endif #include #include #include @@ -36,8 +39,16 @@ #include "libzzuf.h" #include "debug.h" #include "fd.h" +#include "sys.h" #include "fuzz.h" +/* Library initialisation shit */ +void _zz_init(void) __attribute__((constructor)); +void _zz_fini(void) __attribute__((destructor)); +#if defined HAVE_WINDOWS_H +BOOL WINAPI DllMain(HINSTANCE, DWORD, PVOID); +#endif + /* Global variables */ int _zz_ready = 0; int _zz_hasdebug = 0; @@ -96,6 +107,7 @@ void _zz_init(void) _zz_network = 1; _zz_fd_init(); + _zz_sys_init(); tmp = getenv("ZZUF_STDIN"); if(tmp && *tmp == '1') @@ -112,3 +124,22 @@ void _zz_fini(void) _zz_fd_fini(); } +#if defined HAVE_WINDOWS_H +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, PVOID impLoad) +{ + (void)hinst; /* unused */ + (void)impLoad; /* unused */ + + switch(reason) + { + case DLL_PROCESS_ATTACH: + _zz_init(); + break; + case DLL_PROCESS_DETACH: + _zz_fini(); + break; + } + + return TRUE; +} +#endif diff --git a/src/libzzuf.h b/src/libzzuf.h index 83c93c7..8dc6a80 100644 --- a/src/libzzuf.h +++ b/src/libzzuf.h @@ -53,7 +53,3 @@ extern int _zz_memory; extern int _zz_network; extern int _zz_autoinc; -/* Library initialisation shit */ -extern void _zz_init(void) __attribute__((constructor)); -extern void _zz_fini(void) __attribute__((destructor)); - diff --git a/src/sys.c b/src/sys.c new file mode 100644 index 0000000..8601213 --- /dev/null +++ b/src/sys.c @@ -0,0 +1,114 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2006,2007 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. + */ + +/* + * sys.c: system-dependent initialisation + */ + +#include "config.h" + +#if defined HAVE_STDINT_H +# include +#elif defined HAVE_INTTYPES_H +# include +#endif + +#if defined HAVE_WINDOWS_H +# include +# include +# include +# define import_t PIMAGE_IMPORT_DESCRIPTOR +# define thunk_t PIMAGE_THUNK_DATA +#endif + +#include + +#include "sys.h" + +#if defined HAVE_WINDOWS_H +static void insert_func(void *, void *, void *); + +/* TODO: get rid of this later */ +HINSTANCE (*LoadLibraryA_orig)(LPCSTR); +HINSTANCE __stdcall LoadLibraryA_new(LPCSTR path) +{ + void *ret = LoadLibraryA_orig(path); + fprintf(stderr, "If you see this message, DLL preloading worked\n"); + return ret; +} +#endif + +void _zz_sys_init(void) +{ +#if defined HAVE_WINDOWS_H + MEMORY_BASIC_INFORMATION mbi; + MODULEENTRY32 entry; + void *list, *kernel32; + int k; + + kernel32 = GetModuleHandleA("kernel32.dll"); + LoadLibraryA_orig = (void *)GetProcAddress(kernel32, "LoadLibraryA"); + + VirtualQuery(_zz_sys_init, &mbi, sizeof(mbi)); + list = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); + entry.dwSize = sizeof(entry); + for(k = Module32First(list, &entry); k; k = Module32Next(list, &entry)) + { + if(entry.hModule == mbi.AllocationBase) + continue; /* Don't replace our own functions */ + + insert_func(entry.hModule, LoadLibraryA_orig, LoadLibraryA_new); + } + CloseHandle(list); +#else + /* Nothing to do on our platform */ +#endif +} + +#if defined HAVE_WINDOWS_H +static void insert_func(void *module, void *old, void *new) +{ + unsigned long dummy; + import_t import; + thunk_t thunk; + int j, i; + + import = (import_t) + ImageDirectoryEntryToData(module, TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, &dummy); + if(!import) + return; + + for(j = 0; import[j].Name; j++) + { + char *name = (char *)module + import[j].Name; + if(lstrcmpiA(name, "kernel32.dll") != 0) + continue; + + thunk = (thunk_t)((char *)module + import->FirstThunk); + for(i = 0; thunk[i].u1.Function; i++) + { + void **func = (void **)&thunk[i].u1.Function; + if(*func != old) + continue; + + VirtualProtect(func, sizeof(func), PAGE_EXECUTE_READWRITE, &dummy); + WriteProcessMemory(GetCurrentProcess(), func, &new, + sizeof(new), NULL); + return; + } + } +} +#endif + diff --git a/src/sys.h b/src/sys.h new file mode 100644 index 0000000..7348382 --- /dev/null +++ b/src/sys.h @@ -0,0 +1,20 @@ +/* + * zzuf - general purpose fuzzer + * Copyright (c) 2006,2007 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. + */ + +/* + * sys.h: system-dependent initialisation + */ + +extern void _zz_sys_init(void); + diff --git a/src/zzuf.c b/src/zzuf.c index b00d676..7aed63b 100644 --- a/src/zzuf.c +++ b/src/zzuf.c @@ -32,8 +32,12 @@ #if defined HAVE_REGEX_H # include #endif +#if defined HAVE_WINDOWS_H +# include +#endif #if defined HAVE_WINSOCK2_H # include +# include #endif #include #include