Changeset 4393
- Timestamp:
- Apr 19, 2010, 10:51:58 PM (13 years ago)
- Location:
- zzuf/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
zzuf/trunk/doc/zzuf.1.in
r4388 r4393 11 11 [\fB\-b\fR \fIranges\fR] [\fB\-p\fR \fIports\fR] [\fB\-P\fR \fIprotect\fR] 12 12 [\fB\-R\fR \fIrefuse\fR] [\fB\-l\fR \fIlist\fR] [\fB\-I\fR \fIinclude\fR] 13 [\fB\-E\fR \fIexclude\fR] [\fIPROGRAM\fR [\fIARGS\fR]...] 13 [\fB\-E\fR \fIexclude\fR] [\fB\-O\fR \fIopmode\fR] 14 [\fIPROGRAM\fR [\fIARGS\fR]...] 14 15 .br 15 16 \fBzzuf \-h\fR | \fB\-\-help\fR … … 194 195 Only INET (IPv4) and INET6 (IPv6) connections are fuzzed. Other protocol 195 196 families are not yet supported. 197 .TP 198 \fB\-O\fR, \fB\-\-opmode\fR=\fImode\fR 199 Use operating mode \fImode\fR. Valid values for \fImode\fR are: 200 .RS 201 .TP 202 \fBpreload\fR 203 override functions by preloading libzzuf into the executable using the 204 system's dynamic linker 205 .TP 206 \fBcopy\fR 207 temporarily copy files that need to be fuzzed 208 .RE 209 .IP 210 The default value for \fImode\fR is \fBpreload\fR. \fBcopy\fR is useful on 211 platforms that do not support dynamic linker injection, for instance when 212 fuzzing a Cocoa application on Mac OS X. 196 213 .TP 197 214 \fB\-p\fR, \fB\-\-ports\fR=\fIranges\fR -
zzuf/trunk/src/myfork.c
r4291 r4393 70 70 #endif 71 71 72 static int run_process(struct opts *, int[][2]);72 static int run_process(struct child *child, struct opts *, int[][2]); 73 73 74 74 #if defined HAVE_WINDOWS_H … … 101 101 } 102 102 103 pid = run_process( opts, pipes);103 pid = run_process(child, opts, pipes); 104 104 if(pid < 0) 105 105 { 106 106 /* FIXME: close pipes */ 107 fprintf(stderr, "error launching `%s'\n", opts->newargv[0]);107 fprintf(stderr, "error launching `%s'\n", child->newargv[0]); 108 108 return -1; 109 109 } … … 133 133 #endif 134 134 135 static int run_process(struct opts *opts, int pipes[][2])135 static int run_process(struct child *child, struct opts *opts, int pipes[][2]) 136 136 { 137 137 char buf[64]; … … 242 242 } 243 243 244 setenv(PRELOAD, libpath, 1); 244 /* Only preload the library in preload mode */ 245 if (opts->opmode == OPMODE_PRELOAD) 246 setenv(PRELOAD, libpath, 1); 245 247 free(libpath); 246 248 247 if(execvp( opts->newargv[0], opts->newargv))248 { 249 perror( opts->newargv[0]);249 if(execvp(child->newargv[0], child->newargv)) 250 { 251 perror(child->newargv[0]); 250 252 exit(EXIT_FAILURE); 251 253 } … … 266 268 &sinfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); 267 269 sinfo.dwFlags = STARTF_USESTDHANDLES; 268 ret = CreateProcess(NULL, opts->newargv[0], NULL, NULL, FALSE,270 ret = CreateProcess(NULL, child->newargv[0], NULL, NULL, FALSE, 269 271 CREATE_SUSPENDED, NULL, NULL, &sinfo, &pinfo); 270 272 if(!ret) … … 272 274 273 275 /* Get the child process's entry point address */ 274 epaddr = (void *)get_entry_point( opts->newargv[0],276 epaddr = (void *)get_entry_point(child->newargv[0], 275 277 pinfo.dwProcessId); 276 278 if(!epaddr) -
zzuf/trunk/src/opts.c
r4264 r4393 33 33 void _zz_opts_init(struct opts *opts) 34 34 { 35 opts->opmode = OPMODE_PRELOAD; 35 36 opts->fuzzing = opts->bytes = opts->list = opts->ports = NULL; 36 37 opts->allow = NULL; … … 52 53 opts->lastlaunch = 0; 53 54 54 opts->newargv = NULL;55 55 opts->maxchild = 1; 56 56 opts->nchild = 0; … … 62 62 void _zz_opts_fini(struct opts *opts) 63 63 { 64 int i; 65 64 66 if(opts->child) 67 { 68 for(i = 0; i < opts->maxchild; i++) 69 if (opts->child[i].newargv) 70 free(opts->child[i].newargv); 65 71 free(opts->child); 66 if(opts->newargv) 67 free(opts->newargv); 72 } 68 73 } 69 74 -
zzuf/trunk/src/opts.h
r4264 r4393 17 17 struct opts 18 18 { 19 enum opmode 20 { 21 OPMODE_PRELOAD, 22 OPMODE_COPY, 23 } opmode; 19 24 char **oldargv; 20 char **newargv;25 int oldargc; 21 26 char *fuzzing, *bytes, *list, *ports, *protect, *refuse, *allow; 22 27 uint32_t seed; … … 55 60 int64_t date; 56 61 struct md5 *ctx; 62 char **newargv; 57 63 } *child; 58 64 }; -
zzuf/trunk/src/zzuf.c
r4308 r4393 154 154 #endif 155 155 #define OPTSTR "+" OPTSTR_REGEX OPTSTR_RLIMIT_MEM OPTSTR_RLIMIT_CPU \ 156 "a:Ab:B:C:dD:e:f:F:ij:l:mn p:P:qr:R:s:St:U:vxhV"156 "a:Ab:B:C:dD:e:f:F:ij:l:mnO:p:P:qr:R:s:St:U:vxhV" 157 157 #define MOREINFO "Try `%s --help' for more information.\n" 158 158 int option_index = 0; … … 183 183 { "max-memory", 1, NULL, 'M' }, 184 184 { "network", 0, NULL, 'n' }, 185 { "opmode", 1, NULL, 'O' }, 185 186 { "ports", 1, NULL, 'p' }, 186 187 { "protect", 1, NULL, 'P' }, … … 257 258 case 'F': 258 259 fprintf(stderr, "%s: `-F' is deprecated, use `-j'\n", argv[0]); 260 _zz_opts_fini(opts); 259 261 return EXIT_FAILURE; 260 262 case 'i': /* --stdin */ … … 294 296 setenv("ZZUF_NETWORK", "1", 1); 295 297 network = 1; 298 break; 299 case 'O': /* --opmode */ 300 if(myoptarg[0] == '=') 301 myoptarg++; 302 if (!strcmp(myoptarg, "preload")) 303 opts->opmode = OPMODE_PRELOAD; 304 else if (!strcmp(myoptarg, "copy")) 305 opts->opmode = OPMODE_COPY; 306 else 307 { 308 fprintf(stderr, "%s: invalid operating mode -- `%s'\n", 309 argv[0], myoptarg); 310 _zz_opts_fini(opts); 311 return EXIT_FAILURE; 312 } 296 313 break; 297 314 case 'p': /* --ports */ … … 386 403 _zz_setseed(opts->seed); 387 404 388 /* If asked to read from the standard input */389 if(myoptind >= argc)390 {391 if(opts->verbose)392 {393 finfo(stderr, opts, opts->seed);394 fprintf(stderr, "reading from stdin\n");395 }396 397 if(opts->endseed != opts->seed + 1)398 {399 fprintf(stderr, "%s: seed ranges are incompatible with "400 "stdin fuzzing\n", argv[0]);401 printf(MOREINFO, argv[0]);402 _zz_opts_fini(opts);403 return EXIT_FAILURE;404 }405 406 loop_stdin(opts);407 408 _zz_opts_fini(opts);409 return EXIT_SUCCESS;410 }411 412 /* If asked to launch programs */413 #if defined HAVE_REGEX_H414 if(cmdline)415 {416 int dashdash = 0;417 418 for(i = myoptind + 1; i < argc; i++)419 {420 if(dashdash)421 include = merge_file(include, argv[i]);422 else if(!strcmp("--", argv[i]))423 dashdash = 1;424 else if(argv[i][0] != '-')425 include = merge_file(include, argv[i]);426 }427 }428 429 if(include)430 setenv("ZZUF_INCLUDE", include, 1);431 if(exclude)432 setenv("ZZUF_EXCLUDE", exclude, 1);433 #endif434 435 setenv("ZZUF_DEBUG", debug ? debug > 1 ? "2" : "1" : "0", 1);436 setenv("ZZUF_DEBUGFD", DEBUG_FILENO_STR, 1);437 438 if(opts->fuzzing)439 setenv("ZZUF_FUZZING", opts->fuzzing, 1);440 if(opts->bytes)441 setenv("ZZUF_BYTES", opts->bytes, 1);442 if(opts->list)443 setenv("ZZUF_LIST", opts->list, 1);444 if(opts->ports)445 setenv("ZZUF_PORTS", opts->ports, 1);446 if(opts->allow && opts->allow[0] == '!')447 setenv("ZZUF_DENY", opts->allow, 1);448 else if(opts->allow)449 setenv("ZZUF_ALLOW", opts->allow, 1);450 if(opts->protect)451 setenv("ZZUF_PROTECT", opts->protect, 1);452 if(opts->refuse)453 setenv("ZZUF_REFUSE", opts->refuse, 1);454 #if defined HAVE_SETRLIMIT && defined ZZUF_RLIMIT_MEM455 if(opts->maxmem >= 0)456 {457 char buf[32];458 snprintf(buf, 32, "%i", opts->maxmem);459 setenv("ZZUF_MEMORY", buf, 1);460 }461 #endif462 463 /* Allocate memory for children handling */464 opts->child = malloc(opts->maxchild * sizeof(struct child));465 for(i = 0; i < opts->maxchild; i++)466 opts->child[i].status = STATUS_FREE;467 opts->nchild = 0;468 469 /* Create new argv */470 opts->oldargv = argv;471 opts->newargv = malloc((argc - myoptind + 1) * sizeof(char *));472 memcpy(opts->newargv, argv + myoptind, (argc - myoptind) * sizeof(char *));473 opts->newargv[argc - myoptind] = (char *)NULL;474 475 /* Main loop */476 while(opts->nchild || opts->seed < opts->endseed)477 {478 /* Spawn new children, if necessary */479 spawn_children(opts);480 481 /* Cleanup dead or dying children */482 clean_children(opts);483 484 /* Read data from children */485 read_children(opts);486 487 if(opts->maxcrashes && opts->crashes >= opts->maxcrashes488 && opts->nchild == 0)489 {490 if(opts->verbose)491 fprintf(stderr,492 "zzuf: maximum crash count reached, exiting\n");493 break;494 }495 496 if(opts->maxtime && _zz_time() - opts->starttime >= opts->maxtime497 && opts->nchild == 0)498 {499 if(opts->verbose)500 fprintf(stderr,501 "zzuf: maximum running time reached, exiting\n");502 break;503 }504 }505 506 /* Clean up */507 _zz_opts_fini(opts);508 509 return opts->crashes ? EXIT_FAILURE : EXIT_SUCCESS;510 }511 512 static void loop_stdin(struct opts *opts)513 {514 uint8_t md5sum[16];515 struct md5 *ctx = NULL;516 int total = 0;517 518 if(opts->md5)519 ctx = _zz_md5_init();520 521 405 if(opts->fuzzing) 522 406 _zz_fuzzing(opts->fuzzing); … … 530 414 _zz_refuse(opts->refuse); 531 415 416 /* Needed for stdin mode and for copy opmode. */ 532 417 _zz_fd_init(); 418 419 /* 420 * Mode 1: asked to read from the standard input 421 */ 422 if(myoptind >= argc) 423 { 424 if(opts->verbose) 425 { 426 finfo(stderr, opts, opts->seed); 427 fprintf(stderr, "reading from stdin\n"); 428 } 429 430 if(opts->endseed != opts->seed + 1) 431 { 432 fprintf(stderr, "%s: seed ranges are incompatible with " 433 "stdin fuzzing\n", argv[0]); 434 printf(MOREINFO, argv[0]); 435 _zz_opts_fini(opts); 436 return EXIT_FAILURE; 437 } 438 439 loop_stdin(opts); 440 } 441 /* 442 * Mode 2: asked to launch programs 443 */ 444 else 445 { 446 #if defined HAVE_REGEX_H 447 if(cmdline) 448 { 449 int dashdash = 0; 450 451 for(i = myoptind + 1; i < argc; i++) 452 { 453 if(dashdash) 454 include = merge_file(include, argv[i]); 455 else if(!strcmp("--", argv[i])) 456 dashdash = 1; 457 else if(argv[i][0] != '-') 458 include = merge_file(include, argv[i]); 459 } 460 } 461 462 if(include) 463 setenv("ZZUF_INCLUDE", include, 1); 464 if(exclude) 465 setenv("ZZUF_EXCLUDE", exclude, 1); 466 #endif 467 468 setenv("ZZUF_DEBUG", debug ? debug > 1 ? "2" : "1" : "0", 1); 469 setenv("ZZUF_DEBUGFD", DEBUG_FILENO_STR, 1); 470 471 if(opts->fuzzing) 472 setenv("ZZUF_FUZZING", opts->fuzzing, 1); 473 if(opts->bytes) 474 setenv("ZZUF_BYTES", opts->bytes, 1); 475 if(opts->list) 476 setenv("ZZUF_LIST", opts->list, 1); 477 if(opts->ports) 478 setenv("ZZUF_PORTS", opts->ports, 1); 479 if(opts->allow && opts->allow[0] == '!') 480 setenv("ZZUF_DENY", opts->allow, 1); 481 else if(opts->allow) 482 setenv("ZZUF_ALLOW", opts->allow, 1); 483 if(opts->protect) 484 setenv("ZZUF_PROTECT", opts->protect, 1); 485 if(opts->refuse) 486 setenv("ZZUF_REFUSE", opts->refuse, 1); 487 #if defined HAVE_SETRLIMIT && defined ZZUF_RLIMIT_MEM 488 if(opts->maxmem >= 0) 489 { 490 char buf[32]; 491 snprintf(buf, 32, "%i", opts->maxmem); 492 setenv("ZZUF_MEMORY", buf, 1); 493 } 494 #endif 495 496 /* Allocate memory for children handling */ 497 opts->child = malloc(opts->maxchild * sizeof(struct child)); 498 for(i = 0; i < opts->maxchild; i++) 499 opts->child[i].status = STATUS_FREE; 500 opts->nchild = 0; 501 502 /* Create new argv */ 503 opts->oldargc = argc; 504 opts->oldargv = argv; 505 for(i = 0; i < opts->maxchild; i++) 506 { 507 int len = argc - myoptind; 508 opts->child[i].newargv = malloc((len + 1) * sizeof(char *)); 509 memcpy(opts->child[i].newargv, argv + myoptind, 510 len * sizeof(char *)); 511 opts->child[i].newargv[len] = (char *)NULL; 512 } 513 514 /* Main loop */ 515 while(opts->nchild || opts->seed < opts->endseed) 516 { 517 /* Spawn new children, if necessary */ 518 spawn_children(opts); 519 520 /* Cleanup dead or dying children */ 521 clean_children(opts); 522 523 /* Read data from children */ 524 read_children(opts); 525 526 if(opts->maxcrashes && opts->crashes >= opts->maxcrashes 527 && opts->nchild == 0) 528 { 529 if(opts->verbose) 530 fprintf(stderr, 531 "zzuf: maximum crash count reached, exiting\n"); 532 break; 533 } 534 535 if(opts->maxtime && _zz_time() - opts->starttime >= opts->maxtime 536 && opts->nchild == 0) 537 { 538 if(opts->verbose) 539 fprintf(stderr, 540 "zzuf: maximum running time reached, exiting\n"); 541 break; 542 } 543 } 544 } 545 546 /* Clean up */ 547 _zz_fd_fini(); 548 _zz_opts_fini(opts); 549 550 return opts->crashes ? EXIT_FAILURE : EXIT_SUCCESS; 551 } 552 553 static void loop_stdin(struct opts *opts) 554 { 555 uint8_t md5sum[16]; 556 struct md5 *ctx = NULL; 557 int total = 0; 558 559 if(opts->md5) 560 ctx = _zz_md5_init(); 561 533 562 _zz_register(0); 534 563 … … 579 608 580 609 _zz_unregister(0); 581 _zz_fd_fini();582 610 } 583 611 … … 666 694 break; 667 695 696 /* Prepare required files, if necessary */ 697 if (opts->opmode == OPMODE_COPY) 698 { 699 char tmpname[4096]; 700 char *tmpdir; 701 FILE *fpin; 702 int j, k = 0, fdout; 703 704 tmpdir = getenv("TEMP"); 705 if (!tmpdir || !*tmpdir) 706 tmpdir = "/tmp"; 707 708 for (j = optind + 1; j < opts->oldargc; j++) 709 { 710 fpin = fopen(opts->oldargv[j], "r"); 711 if (!fpin) 712 continue; 713 714 sprintf(tmpname, "%s/zzuf.%i.XXXXXX", tmpdir, (int)getpid()); 715 fdout = mkstemp(tmpname); 716 if (fdout < 0) 717 { 718 fclose(fpin); 719 continue; 720 } 721 722 opts->child[i].newargv[j - optind] = strdup(tmpname); 723 724 _zz_register(k); 725 while(!feof(fpin)) 726 { 727 uint8_t buf[BUFSIZ]; 728 size_t n = fread(buf, 1, BUFSIZ, fpin); 729 if (n <= 0) 730 break; 731 _zz_fuzz(k, buf, n); 732 _zz_addpos(k, n); 733 write(fdout, buf, n); 734 } 735 _zz_unregister(k); 736 737 fclose(fpin); 738 close(fdout); 739 740 k++; 741 } 742 } 743 744 /* Launch process */ 668 745 if (myfork(&opts->child[i], opts) < 0) 669 746 { 670 fprintf(stderr, "error launching `%s'\n", opts-> newargv[0]);747 fprintf(stderr, "error launching `%s'\n", opts->child[i].newargv[0]); 671 748 opts->seed++; 749 /* FIXME: clean up OPMODE_COPY files here */ 672 750 return; 673 751 } … … 685 763 { 686 764 finfo(stderr, opts, opts->child[i].seed); 687 fprintf(stderr, "launched `%s'\n", opts-> newargv[0]);765 fprintf(stderr, "launched `%s'\n", opts->child[i].newargv[0]); 688 766 } 689 767 … … 814 892 if(opts->child[i].fd[j] >= 0) 815 893 close(opts->child[i].fd[j]); 894 895 if (opts->opmode == OPMODE_COPY) 896 { 897 for (j = optind + 1; j < opts->oldargc; j++) 898 { 899 if (opts->child[i].newargv[j - optind] != opts->oldargv[j]) 900 { 901 unlink(opts->child[i].newargv[j - optind]); 902 free(opts->child[i].newargv[j - optind]); 903 opts->child[i].newargv[j - optind] = opts->oldargv[j]; 904 } 905 } 906 } 816 907 817 908 if(opts->md5) … … 976 1067 printf( " [-I include] [-E exclude]"); 977 1068 #endif 1069 printf(" [-O mode]\n"); 978 1070 printf("\n"); 979 1071 printf(" [PROGRAM [--] [ARGS]...]\n"); … … 1009 1101 #endif 1010 1102 printf(" -n, --network fuzz network input\n"); 1103 printf(" -O, --opmode <mode> use operating mode <mode> ([preload] copy)\n"); 1011 1104 printf(" -p, --ports <list> only fuzz network destination ports in <list>\n"); 1012 1105 printf(" -P, --protect <list> protect bytes and characters in <list>\n");
Note: See TracChangeset
for help on using the changeset viewer.