| |
1 #!/usr/bin/env python |
| |
2 |
| |
3 # This Source Code Form is subject to the terms of the Mozilla Public |
| |
4 # License, v. 2.0. If a copy of the MPL was not distributed with this |
| |
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| |
6 |
| |
7 # run Microsoft's Binscope tool (http://www.microsoft.com/download/en/details.aspx?id=11910) |
| |
8 # against a fresh Windows build. output a 'binscope.log' file with full details |
| |
9 # of the run and appropriate strings to integrate with the buildbots |
| |
10 |
| |
11 # from the docs : "The error code returned when running under the command line is equal |
| |
12 # to the number of failures the tool reported plus the number of errors. BinScope will return |
| |
13 # 0 only if there are no errors or failures." |
| |
14 |
| |
15 # the symbol dir should point to the symbol dir hierarchy created |
| |
16 # via running make buildsymbols in a windows build's objdir |
| |
17 |
| |
18 import sys |
| |
19 import subprocess |
| |
20 import os |
| |
21 |
| |
22 BINSCOPE_OUTPUT_LOGFILE = r".\binscope_xml_output.log" |
| |
23 |
| |
24 # usage |
| |
25 if len(sys.argv) < 3: |
| |
26 print """usage : autobinscope.by path_to_binary path_to_symbols [log_file_path]" |
| |
27 log_file_path is optional, log will be written to .\binscope_xml_output.log by default""" |
| |
28 sys.exit(0) |
| |
29 |
| |
30 binary_path = sys.argv[1] |
| |
31 symbol_path = sys.argv[2] |
| |
32 |
| |
33 if len(sys.argv) == 4: |
| |
34 log_file_path = sys.argv[3] |
| |
35 else: |
| |
36 log_file_path = BINSCOPE_OUTPUT_LOGFILE |
| |
37 |
| |
38 # execute binscope against the binary, using the BINSCOPE environment |
| |
39 # variable as the path to binscope.exe |
| |
40 try: |
| |
41 binscope_path = os.environ['BINSCOPE'] |
| |
42 except KeyError: |
| |
43 print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status." |
| |
44 sys.exit(0) |
| |
45 |
| |
46 try: |
| |
47 proc = subprocess.Popen([binscope_path, "/target", binary_path, |
| |
48 "/output", log_file_path, "/sympath", symbol_path, |
| |
49 "/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "FunctionPointersCheck", |
| |
50 "/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck", |
| |
51 "/c", "GSCheck", "/c", "GSFunctionSafeBuffersCheck", "/c", "GSFriendlyInitCheck", |
| |
52 "/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck", |
| |
53 "/c", "DBCheck"], stdout=subprocess.PIPE) |
| |
54 |
| |
55 except WindowsError, (errno, strerror): |
| |
56 if errno != 2 and errno != 3: |
| |
57 print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n" |
| |
58 sys.exit(0) |
| |
59 else: |
| |
60 print "Could not locate binscope at location : %s\n" % binscope_path |
| |
61 print "Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting..." |
| |
62 sys.exit(0) |
| |
63 |
| |
64 proc.wait() |
| |
65 |
| |
66 output = proc.communicate()[0] |
| |
67 |
| |
68 # is this a PASS or a FAIL ? |
| |
69 if proc.returncode != 0: |
| |
70 print "Error count: %d" % proc.returncode |
| |
71 print "TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path |
| |
72 logfile = open(log_file_path, "r") |
| |
73 for line in logfile: |
| |
74 print(line), |
| |
75 else: |
| |
76 print "TEST-PASS | autobinscope.py | %s succeeded" % binary_path |