| OLD | NEW |
| 1 /* | 1 /* |
| 2 american fuzzy lop - test case minimizer | 2 american fuzzy lop - test case minimizer |
| 3 ---------------------------------------- | 3 ---------------------------------------- |
| 4 | 4 |
| 5 Written and maintained by Michal Zalewski <lcamtuf@google.com> | 5 Written and maintained by Michal Zalewski <lcamtuf@google.com> |
| 6 | 6 |
| 7 Copyright 2015, 2016 Google Inc. All rights reserved. | 7 Copyright 2015, 2016 Google Inc. All rights reserved. |
| 8 | 8 |
| 9 Licensed under the Apache License, Version 2.0 (the "License"); | 9 Licensed under the Apache License, Version 2.0 (the "License"); |
| 10 you may not use this file except in compliance with the License. | 10 you may not use this file except in compliance with the License. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 | 39 |
| 40 #include <sys/wait.h> | 40 #include <sys/wait.h> |
| 41 #include <sys/time.h> | 41 #include <sys/time.h> |
| 42 #include <sys/shm.h> | 42 #include <sys/shm.h> |
| 43 #include <sys/stat.h> | 43 #include <sys/stat.h> |
| 44 #include <sys/types.h> | 44 #include <sys/types.h> |
| 45 #include <sys/resource.h> | 45 #include <sys/resource.h> |
| 46 | 46 |
| 47 static s32 child_pid; /* PID of the tested program */ | 47 static s32 child_pid; /* PID of the tested program */ |
| 48 | 48 |
| 49 static u8* trace_bits; /* SHM with instrumentation bitmap */ | 49 static u8 *trace_bits, /* SHM with instrumentation bitmap */ |
| 50 *mask_bitmap; /* Mask for trace bits (-B) */ |
| 50 | 51 |
| 51 static u8 *in_file, /* Minimizer input test case */ | 52 static u8 *in_file, /* Minimizer input test case */ |
| 52 *out_file, /* Minimizer output file */ | 53 *out_file, /* Minimizer output file */ |
| 53 *prog_in, /* Targeted program input file */ | 54 *prog_in, /* Targeted program input file */ |
| 54 *target_path, /* Path to target binary */ | 55 *target_path, /* Path to target binary */ |
| 55 *doc_path; /* Path to docs */ | 56 *doc_path; /* Path to docs */ |
| 56 | 57 |
| 57 static u8* in_data; /* Input data for trimming */ | 58 static u8* in_data; /* Input data for trimming */ |
| 58 | 59 |
| 59 static u32 in_len, /* Input data length */ | 60 static u32 in_len, /* Input data length */ |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 while (i--) { | 112 while (i--) { |
| 112 *mem = count_class_lookup[*mem]; | 113 *mem = count_class_lookup[*mem]; |
| 113 mem++; | 114 mem++; |
| 114 } | 115 } |
| 115 | 116 |
| 116 } | 117 } |
| 117 | 118 |
| 118 } | 119 } |
| 119 | 120 |
| 120 | 121 |
| 122 /* Apply mask to classified bitmap (if set). */ |
| 123 |
| 124 static void apply_mask(u32* mem, u32* mask) { |
| 125 |
| 126 u32 i = (MAP_SIZE >> 2); |
| 127 |
| 128 if (!mask) return; |
| 129 |
| 130 while (i--) { |
| 131 |
| 132 *mem &= ~*mask; |
| 133 mem++; |
| 134 mask++; |
| 135 |
| 136 } |
| 137 |
| 138 } |
| 139 |
| 140 |
| 121 /* See if any bytes are set in the bitmap. */ | 141 /* See if any bytes are set in the bitmap. */ |
| 122 | 142 |
| 123 static inline u8 anything_set(void) { | 143 static inline u8 anything_set(void) { |
| 124 | 144 |
| 125 u32* ptr = (u32*)trace_bits; | 145 u32* ptr = (u32*)trace_bits; |
| 126 u32 i = (MAP_SIZE >> 2); | 146 u32 i = (MAP_SIZE >> 2); |
| 127 | 147 |
| 128 while (i--) if (*(ptr++)) return 1; | 148 while (i--) if (*(ptr++)) return 1; |
| 129 | 149 |
| 130 return 0; | 150 return 0; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 setitimer(ITIMER_REAL, &it, NULL); | 327 setitimer(ITIMER_REAL, &it, NULL); |
| 308 | 328 |
| 309 MEM_BARRIER(); | 329 MEM_BARRIER(); |
| 310 | 330 |
| 311 /* Clean up bitmap, analyze exit condition, etc. */ | 331 /* Clean up bitmap, analyze exit condition, etc. */ |
| 312 | 332 |
| 313 if (*(u32*)trace_bits == EXEC_FAIL_SIG) | 333 if (*(u32*)trace_bits == EXEC_FAIL_SIG) |
| 314 FATAL("Unable to execute '%s'", argv[0]); | 334 FATAL("Unable to execute '%s'", argv[0]); |
| 315 | 335 |
| 316 classify_counts(trace_bits); | 336 classify_counts(trace_bits); |
| 337 apply_mask((u32*)trace_bits, (u32*)mask_bitmap); |
| 317 total_execs++; | 338 total_execs++; |
| 318 | 339 |
| 319 if (stop_soon) { | 340 if (stop_soon) { |
| 320 SAYF(cRST cLRD "\n+++ Minimization aborted by user +++\n" cRST); | 341 SAYF(cRST cLRD "\n+++ Minimization aborted by user +++\n" cRST); |
| 321 exit(1); | 342 exit(1); |
| 322 } | 343 } |
| 323 | 344 |
| 324 /* Always discard inputs that time out. */ | 345 /* Always discard inputs that time out. */ |
| 325 | 346 |
| 326 if (child_timed_out) { | 347 if (child_timed_out) { |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 target_path = new_argv[0] = BIN_PATH "/afl-qemu-trace"; | 933 target_path = new_argv[0] = BIN_PATH "/afl-qemu-trace"; |
| 913 return new_argv; | 934 return new_argv; |
| 914 | 935 |
| 915 } | 936 } |
| 916 | 937 |
| 917 FATAL("Unable to find 'afl-qemu-trace'."); | 938 FATAL("Unable to find 'afl-qemu-trace'."); |
| 918 | 939 |
| 919 } | 940 } |
| 920 | 941 |
| 921 | 942 |
| 943 /* Read mask bitmap from file. This is for the -B option. */ |
| 944 |
| 945 static void read_bitmap(u8* fname) { |
| 946 |
| 947 s32 fd = open(fname, O_RDONLY); |
| 948 |
| 949 if (fd < 0) PFATAL("Unable to open '%s'", fname); |
| 950 |
| 951 ck_read(fd, mask_bitmap, MAP_SIZE, fname); |
| 952 |
| 953 close(fd); |
| 954 |
| 955 } |
| 956 |
| 957 |
| 958 |
| 922 /* Main entry point */ | 959 /* Main entry point */ |
| 923 | 960 |
| 924 int main(int argc, char** argv) { | 961 int main(int argc, char** argv) { |
| 925 | 962 |
| 926 s32 opt; | 963 s32 opt; |
| 927 u8 mem_limit_given = 0, timeout_given = 0, qemu_mode = 0; | 964 u8 mem_limit_given = 0, timeout_given = 0, qemu_mode = 0; |
| 928 char** use_argv; | 965 char** use_argv; |
| 929 | 966 |
| 930 doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; | 967 doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; |
| 931 | 968 |
| 932 SAYF(cCYA "afl-tmin " cBRI VERSION cRST " by <lcamtuf@google.com>\n"); | 969 SAYF(cCYA "afl-tmin " cBRI VERSION cRST " by <lcamtuf@google.com>\n"); |
| 933 | 970 |
| 934 while ((opt = getopt(argc,argv,"+i:o:f:m:t:xeQ")) > 0) | 971 while ((opt = getopt(argc,argv,"+i:o:f:m:t:B:xeQ")) > 0) |
| 935 | 972 |
| 936 switch (opt) { | 973 switch (opt) { |
| 937 | 974 |
| 938 case 'i': | 975 case 'i': |
| 939 | 976 |
| 940 if (in_file) FATAL("Multiple -i options not supported"); | 977 if (in_file) FATAL("Multiple -i options not supported"); |
| 941 in_file = optarg; | 978 in_file = optarg; |
| 942 break; | 979 break; |
| 943 | 980 |
| 944 case 'o': | 981 case 'o': |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 break; | 1053 break; |
| 1017 | 1054 |
| 1018 case 'Q': | 1055 case 'Q': |
| 1019 | 1056 |
| 1020 if (qemu_mode) FATAL("Multiple -Q options not supported"); | 1057 if (qemu_mode) FATAL("Multiple -Q options not supported"); |
| 1021 if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU; | 1058 if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU; |
| 1022 | 1059 |
| 1023 qemu_mode = 1; | 1060 qemu_mode = 1; |
| 1024 break; | 1061 break; |
| 1025 | 1062 |
| 1063 case 'B': /* load bitmap */ |
| 1064 |
| 1065 /* This is a secret undocumented option! It is speculated to be useful |
| 1066 if you have a baseline "boring" input file and another "interesting" |
| 1067 file you want to minimize. |
| 1068 |
| 1069 You can dump a binary bitmap for the boring file using |
| 1070 afl-showmap -b, and then load it into afl-tmin via -B. The minimizer |
| 1071 will then minimize to preserve only the edges that are unique to |
| 1072 the interesting input file, but ignoring everything from the |
| 1073 original map. |
| 1074 |
| 1075 The option may be extended and made more official if it proves |
| 1076 to be useful. */ |
| 1077 |
| 1078 if (mask_bitmap) FATAL("Multiple -B options not supported"); |
| 1079 mask_bitmap = ck_alloc(MAP_SIZE); |
| 1080 read_bitmap(optarg); |
| 1081 break; |
| 1082 |
| 1026 default: | 1083 default: |
| 1027 | 1084 |
| 1028 usage(argv[0]); | 1085 usage(argv[0]); |
| 1029 | 1086 |
| 1030 } | 1087 } |
| 1031 | 1088 |
| 1032 if (optind == argc || !in_file || !out_file) usage(argv[0]); | 1089 if (optind == argc || !in_file || !out_file) usage(argv[0]); |
| 1033 | 1090 |
| 1034 setup_shm(); | 1091 setup_shm(); |
| 1035 setup_signal_handlers(); | 1092 setup_signal_handlers(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 ACTF("Writing output to '%s'...", out_file); | 1132 ACTF("Writing output to '%s'...", out_file); |
| 1076 | 1133 |
| 1077 close(write_to_file(out_file, in_data, in_len)); | 1134 close(write_to_file(out_file, in_data, in_len)); |
| 1078 | 1135 |
| 1079 OKF("We're done here. Have a nice day!\n"); | 1136 OKF("We're done here. Have a nice day!\n"); |
| 1080 | 1137 |
| 1081 exit(0); | 1138 exit(0); |
| 1082 | 1139 |
| 1083 } | 1140 } |
| 1084 | 1141 |
| OLD | NEW |