@@ -61,6 +61,12 @@ def main():
61
61
print "afl-cov-" + __version__
62
62
return exit_success
63
63
64
+ if cargs .gcov_check or cargs .gcov_check_bin :
65
+ if is_gcov_enabled (cargs ):
66
+ return exit_success
67
+ else :
68
+ return exit_failure
69
+
64
70
if not check_requirements (cargs ):
65
71
return exit_failure
66
72
@@ -804,19 +810,22 @@ def init_tracking(cov_paths, cargs):
804
810
def is_exe (fpath ):
805
811
return os .path .isfile (fpath ) and os .access (fpath , os .X_OK )
806
812
807
- def is_gcov_enabled (binary , cargs ):
813
+ def is_bin_gcov_enabled (binary , cargs ):
808
814
809
815
rv = False
810
816
811
817
### run readelf against the binary to see if it contains gcov support
812
818
for line in run_cmd ("%s -a %s" % (cargs .readelf_path , binary ),
813
819
False , cargs , WANT_OUTPUT )[1 ]:
814
820
if ' __gcov' in line :
815
- if cargs .validate_args :
816
- print " Binary '%s' is compiled with code coverage support." % binary
821
+ if cargs .validate_args or cargs . gcov_check or cargs . gcov_check_bin :
822
+ print "[+] Binary '%s' is compiled with code coverage support." % binary
817
823
rv = True
818
824
break
819
825
826
+ if not rv and cargs .gcov_check_bin :
827
+ print "[*] Binary '%s' is not compiled with code coverage support." % binary
828
+
820
829
return rv
821
830
822
831
def which (prog ):
@@ -859,7 +868,11 @@ def check_requirements(cargs):
859
868
860
869
return False
861
870
862
- def validate_cargs (cargs ):
871
+ def is_gcov_enabled (cargs ):
872
+
873
+ if not is_exe (cargs .readelf_path ):
874
+ print "[*] Need a valid path to readelf, use --readelf-path"
875
+ return False
863
876
864
877
if cargs .coverage_cmd :
865
878
if 'AFL_FILE' not in cargs .coverage_cmd :
@@ -876,7 +889,7 @@ def validate_cargs(cargs):
876
889
continue
877
890
if (which (part )):
878
891
found_exec = True
879
- if is_exe ( cargs . readelf_path ) and is_gcov_enabled (part , cargs ):
892
+ if is_bin_gcov_enabled (part , cargs ):
880
893
found_code_cov_binary = True
881
894
break
882
895
@@ -885,11 +898,26 @@ def validate_cargs(cargs):
885
898
"--coverage-cmd '%s'" % cargs .coverage_cmd
886
899
return False
887
900
888
- if is_exe ( cargs . readelf_path ) and not found_code_cov_binary :
901
+ if not found_code_cov_binary :
889
902
print "[*] Could not find an executable binary with code " \
890
903
"coverage support ('-fprofile-arcs -ftest-coverage') " \
891
904
"in --coverage-cmd '%s'" % cargs .coverage_cmd
892
905
return False
906
+
907
+ elif cargs .gcov_check_bin :
908
+ if not is_bin_gcov_enabled (cargs .gcov_check_bin , cargs ):
909
+ return False
910
+ elif cargs .gcov_check :
911
+ print "[*] Either --coverage-cmd or --gcov-check-bin required in --gcov-check mode"
912
+ return False
913
+
914
+ return True
915
+
916
+ def validate_cargs (cargs ):
917
+
918
+ if cargs .coverage_cmd :
919
+ if not is_gcov_enabled (cargs ):
920
+ return False
893
921
else :
894
922
if not cargs .func_search and not cargs .line_search :
895
923
print "[*] Must set --coverage-cmd or --func-search/--line-search"
@@ -900,18 +928,10 @@ def validate_cargs(cargs):
900
928
print "[*] --code-dir path does not exist"
901
929
return False
902
930
903
- ### make sure the code has been compiled with code coverage support,
904
- ### so *.gcno files should exist
905
- found_code_coverage_support = False
906
- for root , dirs , files in os .walk (cargs .code_dir ):
907
- for filename in files :
908
- if filename [- 5 :] == '.gcno' :
909
- found_code_coverage_support = True
910
- if not found_code_coverage_support :
911
- print "[*] Could not find any *.gcno files in --code-dir " \
912
- "'%s', is code coverage ('-fprofile-arcs -ftest-coverage') " \
913
- "compiled in?" % cargs .code_dir
931
+ ### make sure code coverage support is compiled in
932
+ if not gcno_files_exist (cargs ):
914
933
return False
934
+
915
935
else :
916
936
if not cargs .func_search and not cargs .line_search :
917
937
print "[*] Must set --code-dir unless using --func-search " \
@@ -943,6 +963,23 @@ def validate_cargs(cargs):
943
963
944
964
return True
945
965
966
+
967
+ def gcno_files_exist (cargs ):
968
+
969
+ ### make sure the code has been compiled with code coverage support,
970
+ ### so *.gcno files should exist
971
+ found_code_coverage_support = False
972
+ for root , dirs , files in os .walk (cargs .code_dir ):
973
+ for filename in files :
974
+ if filename [- 5 :] == '.gcno' :
975
+ found_code_coverage_support = True
976
+ if not found_code_coverage_support :
977
+ print "[*] Could not find any *.gcno files in --code-dir " \
978
+ "'%s', is code coverage ('-fprofile-arcs -ftest-coverage') " \
979
+ "compiled in?" % cargs .code_dir
980
+ return False
981
+ return True
982
+
946
983
def is_afl_running (cargs ):
947
984
while not is_dir (cargs .afl_fuzzing_dir ):
948
985
if not cargs .background :
@@ -1096,6 +1133,12 @@ def parse_cmdline():
1096
1133
p .add_argument ("--sleep" , type = int ,
1097
1134
help = "In --live mode, # of seconds to sleep between checking for new queue files" ,
1098
1135
default = 60 )
1136
+ p .add_argument ("--gcov-check" , action = 'store_true' ,
1137
+ help = "Check to see if there is a binary in --coverage-cmd (or in --gcov-check-bin) has coverage support" ,
1138
+ default = False )
1139
+ p .add_argument ("--gcov-check-bin" , type = str ,
1140
+ help = "Test a specific binary for code coverage support" ,
1141
+ default = False )
1099
1142
p .add_argument ("--background" , action = 'store_true' ,
1100
1143
help = "Background mode - if also in --live mode, will exit when the alf-fuzz process is finished" ,
1101
1144
default = False )
0 commit comments