int main(int argc, char **argv) { FILE *logfile; char line[BUFSIZ]; char *result; long long total_syscalls=0; int random_seed; int max_sample_rate; if (argc<2) { logfile=stdin; // fprintf(stderr,"\nUsage: %s logfile\n\n", // argv[0]); // exit(1); } else { logfile=fopen(argv[1],"r"); if (logfile==NULL) { fprintf(stderr,"Error opening %s\n",argv[1]); exit(1); } } printf("/* log_to_code output from %s */\n",argv[1]); printf("/* by Vince Weaver <vincent.weaver _at_ maine.edu> */\n\n"); printf("#define _GNU_SOURCE 1\n"); printf("#include <stdio.h>\n"); printf("#include <unistd.h>\n"); printf("#include <fcntl.h>\n"); printf("#include <string.h>\n"); printf("#include <signal.h>\n"); printf("#include <sys/mman.h>\n"); printf("#include <sys/syscall.h>\n"); printf("#include <sys/ioctl.h>\n"); printf("#include <sys/prctl.h>\n"); printf("#include <sys/wait.h>\n"); printf("#include <poll.h>\n"); printf("#include <linux/hw_breakpoint.h>\n"); printf("#include <linux/perf_event.h>\n"); printf("\n"); printf("static int fd[%d];\n",NUM_VALUES); printf("static struct perf_event_attr pe[%d];\n",NUM_VALUES); printf("static char *mmap_result[%d];\n",NUM_VALUES); printf("#define MAX_READ_SIZE 65536\n"); printf("static long long data[MAX_READ_SIZE];\n"); printf("\n"); printf("#define MAX_POLL_FDS 128\n"); printf("static struct pollfd pollfds[MAX_POLL_FDS];\n"); printf("\n"); /* For ioctl(PERF_EVENT_IOC_ID); */ printf("static long long id;\n"); /* For ioctl(PERF_EVENT_IOC_PERIOD); */ printf("static long long period;\n"); printf("\n"); printf("static int status;\n"); printf("static int forked_pid;\n\n"); printf("static struct sigaction sa;\n"); printf("static int overflows=0;\n"); printf("static int sigios=0;\n\n"); printf("FILE *fff;\n"); printf("static int result;\n"); printf("static long long size;\n"); printf("static char buffer[2048];\n\n"); printf("static void our_handler(int signum, siginfo_t *info, void *uc) {\n"); printf("\tint fd = info->si_fd;\n"); printf("\tint ret;\n\n"); printf("\toverflows++;\n"); printf("\tioctl(fd,PERF_EVENT_IOC_DISABLE,0);\n"); printf("\tif (sigios) return;\n"); printf("\tret=ioctl(fd, PERF_EVENT_IOC_REFRESH,1);\n"); printf("}\n\n"); printf("int perf_event_open(struct perf_event_attr *hw_event_uptr,\n"); printf("\tpid_t pid, int cpu, int group_fd, unsigned long flags) {\n"); printf("\n"); printf("\treturn syscall(__NR_perf_event_open,hw_event_uptr, pid, cpu,\n"); printf("\t\tgroup_fd, flags);\n"); printf("}\n\n"); printf("int main(int argc, char **argv) {\n"); /* Match how replay_log implements things */ printf("\n\tint i;\n"); printf("\tfor(i=0;i<%d;i++) fd[i]=-1;\n\n",NUM_VALUES); while(1) { result=fgets(line,BUFSIZ,logfile); if (result==NULL) break; line_num++; printf("/* %lld */\n",line_num); //printf("printf(\"Line: %lld\\n\");\n",line_num); switch(line[0]) { case 'A': access_event(line); total_syscalls++; break; case 'C': close_event(line); total_syscalls++; break; case 'F': fork_event(line); total_syscalls++; break; case 'G': sscanf(line,"%*c %d",&original_pid); break; case 'I': ioctl_event(line); total_syscalls++; break; case 'M': mmap_event(line); total_syscalls++; break; case 'O': open_event(line); total_syscalls++; break; case 'o': setup_overflow(line); total_syscalls++; break; case 'P': prctl_event(line); total_syscalls++; break; case 'p': poll_event(line); total_syscalls++; break; case 'Q': trash_mmap_event(line); total_syscalls++; break; case 'R': read_event(line); total_syscalls++; break; case 'r': sscanf(line,"%*c %d",&max_sample_rate); printf("/* /proc/sys/kernel/perf_event_max_sample_rate was %d */\n",max_sample_rate); break; case 'S': sscanf(line,"%*c %d",&random_seed); printf("/* Random Seed was %d */\n",random_seed); break; case 'U': munmap_event(line); total_syscalls++; break; default: fprintf(stderr,"Unknown log type \'%c\'\n", line[0]); break; } if (error) break; } printf("\n\n\t/* Replayed %lld syscalls */\n",total_syscalls); printf("\treturn 0;\n"); printf("}\n"); return 0; }
int main(int argc, char **argv) { FILE *logfile,*fff; char *logfile_name=NULL; char *result; long long total_syscalls=0,replay_syscalls=0; long long skip_lines=0; long long stop_lines=0; struct sigaction sigio; int i,j,seed=0xdeadbeef; int replay_which=REPLAY_ALL; int sample_rate,old_sample_rate; /* init */ for(i=0;i<FD_REMAP_SIZE;i++) fd_remap[i]=-1; // if (argc<2) { // print_usage(argv[0]); // exit(1); // } i=1; while(1) { if (i>=argc) break; if (argv[i][0]=='-') { switch(argv[i][1]) { case 'h': print_usage(argv[0]); exit(1); break; case 'p': i++; if (i<argc) { stop_lines=atoll(argv[i]); printf("stopping after %lld lines\n",stop_lines); i++; } break; case 's': i++; if (i<argc) { skip_lines=atoll(argv[i]); printf("skipping %lld lines\n",skip_lines); i++; } break; case 'r': replay_which=0; i++; for(j=0;j<strlen(argv[i]);j++) { switch(argv[i][j]) { case 'O': replay_which|=REPLAY_OPEN; break; case 'o': replay_which|=REPLAY_OVERFLOW; break; case 'C': replay_which|=REPLAY_CLOSE; break; case 'I': replay_which|=REPLAY_IOCTL; break; case 'R': replay_which|=REPLAY_READ; break; case 'M': replay_which|=REPLAY_MMAP; break; case 'U': replay_which|=REPLAY_MUNMAP; break; case 'P': replay_which|=REPLAY_PRCTL; break; case 'F': replay_which|=REPLAY_FORK; break; case 'p': replay_which|=REPLAY_POLL; break; default: fprintf(stderr,"Unknown replay %c\n", argv[i][j]); } } i++; break; default: fprintf(stderr,"Unknown option -%c\n",argv[i][1]); exit(1); break; } } else { logfile_name=strdup(argv[i]); i++; } } if (logfile_name==NULL) { // fprintf(stderr,"Must specify logfile name\n"); // exit(1); logfile=stdin; } else { logfile=fopen(logfile_name,"r"); if (logfile==NULL) { fprintf(stderr,"Error opening %s\n",logfile_name); exit(1); } } printf("Replaying...\n"); /* Write fake seed to disk */ /* trying to make the syscall trace more similar to the actual fuzzer */ fff=fopen("fake.seed","w"); if (fff!=NULL) { fprintf(fff,"%d\n",seed); fclose(fff); } /* Save the content of /proc/sys/kernel/perf_event_max_sample_rate */ /* If it has been changed, a replay might not be perfect */ sample_rate=get_sample_rate(); /* Set up to match trinity setup, vaguely */ page_size=getpagesize(); syscall_perf_event_open.init(); shm=calloc(1,sizeof(struct shm_s)); page_rand = memalign(page_size, page_size * 2); if (!page_rand) { exit(EXIT_FAILURE); } memset(page_rand, 0x55, page_size); /* Set up SIGIO handler */ /* In theory we shouldn't get SIGIO as we set up SIGRT for overflow */ /* But if the RT queue overflows we will get a SIGIO */ memset(&sigio, 0, sizeof(struct sigaction)); sigio.sa_sigaction = sigio_handler; sigio.sa_flags = SA_SIGINFO; if (sigaction( SIGIO, &sigio, NULL) < 0) { printf("Error setting up SIGIO signal handler\n"); } while(1) { result=fgets(line,BUFSIZ,logfile); if (result==NULL) break; line_num++; if (debug) printf("%lld %s",line_num,line); /* don't want to skip the random seed, etc */ if ((line_num>2) && (line_num<skip_lines)) continue; switch(line[0]) { case 'A': if (replay_which & REPLAY_ACCESS) { access_event(line); replay_syscalls++; } break; case 'C': if (replay_which & REPLAY_CLOSE) { close_event(line); replay_syscalls++; } break; case 'F': if (replay_which & REPLAY_FORK) { fork_event(line); replay_syscalls++; } break; case 'G': sscanf(line,"%*c %d",&original_pid); printf("Original pid was %d\n",original_pid); break; case 'I': if (replay_which & REPLAY_IOCTL) { ioctl_event(line); replay_syscalls++; } break; case 'M': if (replay_which & REPLAY_MMAP) { mmap_event(line); replay_syscalls++; } break; case 'O': if (replay_which & REPLAY_OPEN) { open_event(line); replay_syscalls++; } break; case 'o': if (replay_which & REPLAY_OVERFLOW) { setup_overflow(line); replay_syscalls++; } break; case 'P': if (replay_which & REPLAY_PRCTL) { prctl_event(line); replay_syscalls++; } break; case 'p': if (replay_which & REPLAY_POLL) { poll_event(line); replay_syscalls++; } break; case 'Q': if (replay_which & REPLAY_TRASH_MMAP) { trash_mmap_event(line); replay_syscalls++; } break; case 'q': fprintf(stderr,"Quitting early\n"); exit(1); case 'R': if (replay_which & REPLAY_READ) { read_event(line); replay_syscalls++; } break; case 'r': sscanf(line,"r %d",&old_sample_rate); //sample_rate=get_sample_rate(); if (sample_rate!=old_sample_rate) { printf("Warning! The current max sample rate is %d\n",sample_rate); printf("\tThis log was recorded when it was %d\n",old_sample_rate); printf("\tFor proper replay you might want to (as root):\n\techo \"%d\" > /proc/sys/kernel/perf_event_max_sample_rate\n",old_sample_rate); } break; case 'S': if (replay_which & REPLAY_SEED) { /* don't need to do anything */ /* as we don't use rand */ } break; case 'U': if (replay_which & REPLAY_MUNMAP) { munmap_event(line); replay_syscalls++; } break; case '#': /* skip */ break; default: fprintf(stderr,"Line %lld Unknown log type \'%c\'\n", line_num,line[0]); break; } //if (error) break; total_syscalls++; if (total_syscalls%1000==0) { printf("%lld\n",total_syscalls); } if (stop_lines && (total_syscalls > stop_lines)) break; } /* Kill any lingering children */ if (forked_pid) { kill(forked_pid,SIGKILL); } printf("Replayed %lld of %lld syscalls\n", replay_syscalls,total_syscalls); return 0; }
int main(int argc, char **argv) { FILE *logfile; char *logfile_name=NULL; char line[BUFSIZ]; char *result; long long total_syscalls=0,replay_syscalls=0; long long skip_lines=0; int i; int replay_which=REPLAY_ALL; if (argc<2) { print_usage(argv[0]); exit(1); } i=1; while(1) { if (i>=argc) break; if (argv[i][0]=='-') { switch(argv[i][1]) { case 'h': print_usage(argv[0]); exit(1); break; default: fprintf(stderr,"Unknown option -%c\n",argv[i][1]); exit(1); break; } } else { logfile_name=strdup(argv[i]); i++; } } if (logfile_name==NULL) { fprintf(stderr,"Must specify logfile name\n"); exit(1); } logfile=fopen(logfile_name,"r"); if (logfile==NULL) { fprintf(stderr,"Error opening %s\n",logfile_name); exit(1); } /* Init structs */ for(i=0;i<MAX_EVENTS;i++) { event_info[i].opened=0; event_info[i].enabled=0; mmap_info[i].valid=0; } /* Main loop */ while(1) { result=fgets(line,BUFSIZ,logfile); if (result==NULL) break; line_num++; if (line_num<skip_lines) continue; switch(line[0]) { case 'C': if (replay_which & REPLAY_CLOSE) { close_event(line); replay_syscalls++; } break; case 'F': if (replay_which & REPLAY_FORK) { fork_event(line); replay_syscalls++; } break; case 'G': sscanf(line,"%*c %d",&original_pid); printf("Original pid was %d\n",original_pid); break; case 'I': if (replay_which & REPLAY_IOCTL) { ioctl_event(line); replay_syscalls++; } break; case 'M': if (replay_which & REPLAY_MMAP) { mmap_event(line); replay_syscalls++; } break; case 'O': if (replay_which & REPLAY_OPEN) { open_event(line); replay_syscalls++; } break; case 'o': if (replay_which & REPLAY_OVERFLOW) { setup_overflow(line); replay_syscalls++; } break; case 'P': if (replay_which & REPLAY_PRCTL) { prctl_event(line); replay_syscalls++; } break; case 'p': if (replay_which & REPLAY_POLL) { poll_event(line); replay_syscalls++; } break; case 'Q': if (replay_which & REPLAY_TRASH_MMAP) { trash_mmap_event(line); replay_syscalls++; } break; case 'q': fprintf(stderr,"Quitting early\n"); exit(1); case 'R': if (replay_which & REPLAY_READ) { read_event(line); replay_syscalls++; } break; case 'S': if (replay_which & REPLAY_SEED) { /* don't need to do anything */ /* as we don't use rand */ } break; case 'U': if (replay_which & REPLAY_MUNMAP) { munmap_event(line); replay_syscalls++; } break; default: fprintf(stderr,"Line %lld Unknown log type \'%c\'\n", line_num,line[0]); break; } //if (error) break; total_syscalls++; if (total_syscalls%1000==0) { printf("%lld\n",total_syscalls); } } printf("ACTIVE EVENT REPORT\n"); printf("~~~~~~~~~~~~~~~~~~~\n"); printf("\tReplayed %lld of %lld syscalls\n", replay_syscalls,total_syscalls); int total_active=0,total_opened=0; for(i=0;i<MAX_EVENTS;i++) { if (event_info[i].opened) total_opened++; if (event_info[i].enabled) total_active++; } printf("\t%d events open, %d events active\n", total_opened,total_active); printf("ENABLED EVENTS\n\n"); for(i=0;i<MAX_EVENTS;i++) { if (event_info[i].enabled) { perf_pretty_print_event(stdout, i,original_pid, &event_info[i].attr, event_info[i].pid, event_info[i].cpu, event_info[i].group_fd, event_info[i].flags); printf("\n\n"); } } printf("SHORT EVENT SUMMARY\n\n"); for(i=0;i<MAX_EVENTS;i++) { if (event_info[i].enabled) { perf_pretty_print_event_short(stdout, i,original_pid, &event_info[i].attr, event_info[i].pid, event_info[i].cpu, event_info[i].group_fd, event_info[i].flags); } } return 0; }