Changeset 4115 for zzuf/trunk/src
- Timestamp:
- Dec 12, 2009, 11:20:11 PM (11 years ago)
- Location:
- zzuf/trunk/src
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
zzuf/trunk/src/Makefile.am
r4112 r4115 5 5 6 6 ZZUF = \ 7 zzuf.c opts.c opts.h md5.c md5.h timer.c timer.h 7 zzuf.c opts.c opts.h md5.c md5.h timer.c timer.h myfork.c myfork.h 8 8 9 9 LIBZZUF = \ … … 26 26 27 27 zzuf_SOURCES = $(ZZUF) $(COMMON) $(GETOPT) 28 zzuf_CFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" -I common/28 zzuf_CFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" -I$(srcdir)/common 29 29 zzuf_LDFLAGS = $(MATH_LIBS) $(WINSOCK2_LIBS) 30 30 zzuf_DEPENDENCIES = libzzuf.la 31 31 32 32 libzzuf_la_SOURCES = $(LIBZZUF) $(COMMON) 33 libzzuf_la_CFLAGS = -DLIBZZUF -I libzzuf/ -Icommon/33 libzzuf_la_CFLAGS = -DLIBZZUF -I$(srcdir)/libzzuf -I$(srcdir)/common 34 34 libzzuf_la_LDFLAGS = -avoid-version -no-undefined $(DLL_LDFLAGS) 35 35 libzzuf_la_LIBADD = $(GETOPT_LIBS) $(DL_LIBS) $(MATH_LIBS) $(WINSOCK2_LIBS) -
zzuf/trunk/src/common/common.h
r4112 r4115 36 36 #define DEFAULT_MEM 1024 37 37 38 /* We use file descriptor 17 as the debug channel */ 39 #define DEBUG_FILENO 17 40 #define DEBUG_FILENO_STR "17" 41 38 42 struct fuzz 39 43 { -
zzuf/trunk/src/zzuf.c
r4112 r4115 19 19 #include "config.h" 20 20 21 /* Needed for STDERR_FILENO on HP-UX */ 22 #define _INCLUDE_POSIX_SOURCE 21 #define _INCLUDE_POSIX_SOURCE /* for STDERR_FILENO on HP-UX */ 23 22 24 23 #if defined HAVE_STDINT_H … … 35 34 #include <stdlib.h> 36 35 #if defined HAVE_UNISTD_H 37 # include <unistd.h> 36 # include <unistd.h> /* for read(), write(), close() */ 38 37 #endif 39 38 #if defined HAVE_REGEX_H … … 41 40 #endif 42 41 #if defined HAVE_WINSOCK2_H 43 # include <winsock2.h> 44 #endif 45 #if defined HAVE_WINDOWS_H 46 # include <windows.h> 47 # include <imagehlp.h> 48 # include <tlhelp32.h> 42 # include <winsock2.h> /* for fd_set */ 49 43 #endif 50 44 #if defined HAVE_IO_H … … 52 46 #endif 53 47 #include <string.h> 54 #include <fcntl.h>55 48 #include <errno.h> 56 49 #include <signal.h> … … 70 63 #include "fd.h" 71 64 #include "fuzz.h" 65 #include "myfork.h" 72 66 #include "md5.h" 73 67 #include "timer.h" … … 105 99 #endif 106 100 107 /* We use file descriptor 17 as the debug channel */108 #define DEBUG_FILENO 17109 #define DEBUG_FILENO_STR "17"110 111 101 static void loop_stdin(struct opts *); 112 static int run_process(struct opts *, int[][2]);113 102 114 103 static void spawn_children(struct opts *); … … 122 111 static char const *sig2name(int); 123 112 #endif 124 #if defined HAVE_WINDOWS_H125 static int dll_inject(void *, void *);126 static intptr_t get_base_address(DWORD);127 static intptr_t get_entry_point_offset(char const *);128 #endif129 113 static void finfo(FILE *, struct opts *, uint32_t); 130 114 #if defined HAVE_REGEX_H … … 134 118 static void version(void); 135 119 static void usage(void); 136 137 #if defined HAVE_WINDOWS_H138 static inline void addcpy(void *buf, void *x)139 {140 memcpy(buf, &x, 4);141 }142 #endif143 120 144 121 #define ZZUF_FD_SET(fd, p_fdset, maxfd) \ … … 659 636 static void spawn_children(struct opts *opts) 660 637 { 661 int pipes[3][2];662 638 int64_t now = _zz_time(); 663 pid_t pid; 664 int i, j; 639 int i; 665 640 666 641 if(opts->nchild == opts->maxchild) … … 681 656 break; 682 657 683 /* Prepare communication pipe */ 684 for(j = 0; j < 3; j++) 685 { 686 int ret; 687 #if defined HAVE_PIPE 688 ret = pipe(pipes[j]); 689 #elif defined HAVE__PIPE 690 ret = _pipe(pipes[j], 512, _O_BINARY | O_NOINHERIT); 691 #endif 692 if(ret < 0) 693 { 694 perror("pipe"); 695 opts->seed++; 696 return; 697 } 698 } 699 700 pid = run_process(opts, pipes); 701 if(pid < 0) 658 if (myfork(&opts->child[i], opts) < 0) 702 659 { 703 660 fprintf(stderr, "error launching `%s'\n", opts->newargv[0]); … … 708 665 /* We’re the parent, acknowledge spawn */ 709 666 opts->child[i].date = now; 710 opts->child[i].pid = pid;711 for(j = 0; j < 3; j++)712 {713 close(pipes[j][1]);714 opts->child[i].fd[j] = pipes[j][0];715 }716 667 opts->child[i].bytes = 0; 717 668 opts->child[i].seed = opts->seed; … … 968 919 969 920 return ""; 970 }971 #endif972 973 static int run_process(struct opts *opts, int pipes[][2])974 {975 char buf[64];976 #if defined HAVE_FORK977 static int const files[] = { DEBUG_FILENO, STDERR_FILENO, STDOUT_FILENO };978 char *libpath, *tmp;979 int pid, j, len = strlen(opts->oldargv[0]);980 # if defined __APPLE__981 # define EXTRAINFO ""982 # define PRELOAD "DYLD_INSERT_LIBRARIES"983 setenv("DYLD_FORCE_FLAT_NAMESPACE", "1", 1);984 # elif defined __osf__985 # define EXTRAINFO ":DEFAULT"986 # define PRELOAD "_RLD_LIST"987 # else988 # define EXTRAINFO ""989 # define PRELOAD "LD_PRELOAD"990 # endif991 #elif HAVE_WINDOWS_H992 PROCESS_INFORMATION pinfo;993 STARTUPINFO sinfo;994 HANDLE pid;995 void *epaddr;996 int ret;997 #endif998 999 #if defined HAVE_FORK1000 /* Fork and launch child */1001 pid = fork();1002 if(pid < -1)1003 perror("fork");1004 if(pid != 0)1005 return pid;1006 1007 /* We loop in reverse order so that files[0] is done last,1008 * just in case one of the other dup2()ed fds had the value */1009 for(j = 3; j--; )1010 {1011 close(pipes[j][0]);1012 if(pipes[j][1] != files[j])1013 {1014 dup2(pipes[j][1], files[j]);1015 close(pipes[j][1]);1016 }1017 }1018 #endif1019 1020 #if defined HAVE_SETRLIMIT && defined ZZUF_RLIMIT_MEM1021 if(opts->maxmem >= 0)1022 {1023 struct rlimit rlim;1024 rlim.rlim_cur = opts->maxmem * 1000000;1025 rlim.rlim_max = opts->maxmem * 1000000;1026 setrlimit(ZZUF_RLIMIT_MEM, &rlim);1027 }1028 #endif1029 1030 #if defined HAVE_SETRLIMIT && defined ZZUF_RLIMIT_CPU1031 if(opts->maxcpu >= 0)1032 {1033 struct rlimit rlim;1034 rlim.rlim_cur = opts->maxcpu;1035 rlim.rlim_max = opts->maxcpu + 5;1036 setrlimit(ZZUF_RLIMIT_CPU, &rlim);1037 }1038 #endif1039 1040 /* Set environment variables */1041 sprintf(buf, "%i", opts->seed);1042 setenv("ZZUF_SEED", buf, 1);1043 sprintf(buf, "%g", opts->minratio);1044 setenv("ZZUF_MINRATIO", buf, 1);1045 sprintf(buf, "%g", opts->maxratio);1046 setenv("ZZUF_MAXRATIO", buf, 1);1047 1048 #if defined HAVE_FORK1049 /* Make sure there is space for everything we might do. */1050 libpath = malloc(len + strlen(LIBDIR "/" LT_OBJDIR SONAME EXTRAINFO) + 1);1051 strcpy(libpath, opts->oldargv[0]);1052 1053 /* If the binary name contains a '/', we look for a libzzuf in the1054 * same directory. Otherwise, we only look into the system directory1055 * to avoid shared library attacks. Write the result in libpath. */1056 tmp = strrchr(libpath, '/');1057 if(tmp)1058 {1059 strcpy(tmp + 1, LT_OBJDIR SONAME);1060 if(access(libpath, R_OK) < 0)1061 strcpy(libpath, LIBDIR "/" SONAME);1062 }1063 else1064 strcpy(libpath, LIBDIR "/" SONAME);1065 1066 /* OSF1 only */1067 strcat(libpath, EXTRAINFO);1068 1069 /* Do not clobber previous LD_PRELOAD values */1070 tmp = getenv(PRELOAD);1071 if(tmp && *tmp)1072 {1073 char *bigbuf = malloc(strlen(tmp) + strlen(libpath) + 2);1074 sprintf(bigbuf, "%s:%s", tmp, libpath);1075 free(libpath);1076 libpath = bigbuf;1077 }1078 1079 setenv(PRELOAD, libpath, 1);1080 free(libpath);1081 1082 if(execvp(opts->newargv[0], opts->newargv))1083 {1084 perror(opts->newargv[0]);1085 exit(EXIT_FAILURE);1086 }1087 1088 exit(EXIT_SUCCESS);1089 /* no return */1090 return 0;1091 #elif HAVE_WINDOWS_H1092 pid = GetCurrentProcess();1093 1094 memset(&sinfo, 0, sizeof(sinfo));1095 sinfo.cb = sizeof(sinfo);1096 DuplicateHandle(pid, (HANDLE)_get_osfhandle(pipes[0][1]), pid,1097 /* FIXME */ &sinfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);1098 DuplicateHandle(pid, (HANDLE)_get_osfhandle(pipes[1][1]), pid,1099 &sinfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS);1100 DuplicateHandle(pid, (HANDLE)_get_osfhandle(pipes[2][1]), pid,1101 &sinfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);1102 sinfo.dwFlags = STARTF_USESTDHANDLES;1103 ret = CreateProcess(NULL, opts->newargv[0], NULL, NULL, FALSE,1104 CREATE_SUSPENDED, NULL, NULL, &sinfo, &pinfo);1105 if(!ret)1106 return -1;1107 1108 /* Get the child process's entry point address */1109 epaddr = (void *)(get_base_address(pinfo.dwProcessId)1110 + get_entry_point_offset(opts->newargv[0]));1111 if(!epaddr)1112 return -1;1113 1114 /* Insert the replacement code */1115 ret = dll_inject(pinfo.hProcess, epaddr);1116 if(ret < 0)1117 {1118 TerminateProcess(pinfo.hProcess, -1);1119 return -1;1120 }1121 1122 ret = ResumeThread(pinfo.hThread);1123 if(ret < 0)1124 {1125 TerminateProcess(pinfo.hProcess, -1);1126 return -1;1127 }1128 1129 return (long int)pinfo.hProcess;1130 #endif1131 }1132 1133 #if defined HAVE_WINDOWS_H1134 static int dll_inject(void *process, void *epaddr)1135 {1136 uint8_t code1[] = /* LIBZZUF: */1137 "libzzuf.dll\0"1138 /* OLDEP: */1139 "_______"1140 /* START: */1141 "\xb8____" /* mov eax,<libzzuf.dll> */1142 "\x50" /* push eax */1143 "\xb8____" /* mov eax,<LoadLibraryA> */1144 "\xff\xd0" /* call eax */1145 "\xb8\0\0\0\0" /* mov eax,0 */1146 "\x50" /* push eax */1147 "\xb8\x07\0\0\0" /* mov eax,7 */1148 "\x50" /* push eax */1149 "\xb8____" /* mov eax,<OLDEP> */1150 "\x50" /* push eax */1151 "\xb8____" /* mov eax,<NEWEP> */1152 "\x50" /* push eax */1153 "\xb8____" /* mov eax,<GetCurrentProcess> */1154 "\xff\xd0" /* call eax */1155 "\x50" /* push eax */1156 "\xb8____" /* mov eax,<WriteProcessMemory> */1157 "\xff\xd0" /* call eax */1158 "\xb8____" /* mov eax,<NEWEP> */1159 "\xff\xe0"; /* jmp eax */1160 uint8_t code2[] = /* NEWEP: */1161 "\xb8____" /* mov eax,<START> */1162 "\xff\xe0"; /* jmp eax */1163 void *lib;1164 uint8_t *loaderaddr;1165 DWORD tmp;1166 1167 /* Backup the old entry-point code */1168 ReadProcessMemory(process, epaddr, code1 + 0x0c, 7, &tmp);1169 if(tmp != 7)1170 return -1;1171 1172 /* Copy the first shell code to a freshly allocated memory area. */1173 loaderaddr = VirtualAllocEx(process, NULL, sizeof(code1), MEM_COMMIT,1174 PAGE_EXECUTE_READWRITE);1175 if(!loaderaddr)1176 return -1;1177 1178 lib = LoadLibrary("kernel32.dll");1179 if(!lib)1180 return -1;1181 1182 addcpy(code1 + 0x14, loaderaddr + 0x00); /* offset for dll string */1183 addcpy(code1 + 0x1a, GetProcAddress(lib, "LoadLibraryA"));1184 addcpy(code1 + 0x2d, loaderaddr + 0x0c);1185 addcpy(code1 + 0x33, epaddr);1186 addcpy(code1 + 0x39, GetProcAddress(lib, "GetCurrentProcess"));1187 addcpy(code1 + 0x41, GetProcAddress(lib, "WriteProcessMemory"));1188 addcpy(code1 + 0x48, epaddr);1189 FreeLibrary(lib);1190 1191 WriteProcessMemory(process, loaderaddr, code1, sizeof(code1), &tmp);1192 if(tmp != sizeof(code1))1193 return -1;1194 1195 /* Copy the second shell code where the old entry point was. */1196 addcpy(code2 + 0x01, loaderaddr + 12 + 7);1197 WriteProcessMemory(process, epaddr, code2, 7, &tmp);1198 if(tmp != 7)1199 return -1;1200 1201 return 0;1202 }1203 1204 /* Find the process's base address once it is loaded in memory (the header1205 * information is unreliable because of Vista's ASLR). */1206 static intptr_t get_base_address(DWORD pid)1207 {1208 MODULEENTRY32 entry;1209 intptr_t ret = 0;1210 void *list;1211 int k;1212 1213 list = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);1214 entry.dwSize = sizeof(entry);1215 for(k = Module32First(list, &entry); k; k = Module32Next(list, &entry))1216 {1217 /* FIXME: how do we select the correct module? */1218 ret = (intptr_t)entry.modBaseAddr;1219 }1220 CloseHandle(list);1221 1222 return ret;1223 }1224 1225 /* Find the process's entry point address offset. The information is in1226 * the file's PE header. */1227 static intptr_t get_entry_point_offset(char const *name)1228 {1229 PIMAGE_DOS_HEADER dos;1230 PIMAGE_NT_HEADERS nt;1231 intptr_t ret = 0;1232 void *file, *map, *base;1233 1234 file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,1235 NULL, OPEN_EXISTING, 0, NULL);1236 if(file == INVALID_HANDLE_VALUE)1237 return ret;1238 1239 map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);1240 if(!map)1241 {1242 CloseHandle(file);1243 return ret;1244 }1245 1246 base = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);1247 if(!base)1248 {1249 CloseHandle(map);1250 CloseHandle(file);1251 return ret;1252 }1253 1254 /* Sanity checks */1255 dos = (PIMAGE_DOS_HEADER)base;1256 nt = (PIMAGE_NT_HEADERS)((char *)base + dos->e_lfanew);1257 if(dos->e_magic == IMAGE_DOS_SIGNATURE /* 0x5A4D */1258 && nt->Signature == IMAGE_NT_SIGNATURE /* 0x00004550 */1259 && nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I3861260 && nt->OptionalHeader.Magic == 0x10b /* IMAGE_NT_OPTIONAL_HDR32_MAGIC */)1261 {1262 ret = (intptr_t)nt->OptionalHeader.AddressOfEntryPoint;1263 }1264 1265 UnmapViewOfFile(base);1266 CloseHandle(map);1267 CloseHandle(file);1268 1269 return ret;1270 921 } 1271 922 #endif
Note: See TracChangeset
for help on using the changeset viewer.