OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Makes sure that all EXE and DLL files in the provided directory were built | 6 """Makes sure that all EXE and DLL files in the provided directory were built |
7 correctly. | 7 correctly. |
8 | 8 |
9 In essense it runs a subset of BinScope tests ensuring that binaries have | 9 In essense it runs a subset of BinScope tests ensuring that binaries have |
10 /NXCOMPAT, /DYNAMICBASE and /SAFESEH. | 10 /NXCOMPAT, /DYNAMICBASE and /SAFESEH. |
11 """ | 11 """ |
12 | 12 |
13 import os | 13 import os |
14 import optparse | 14 import optparse |
15 import sys | 15 import sys |
16 | 16 |
17 # Find /third_party/pefile based on current directory and script path. | 17 # Find /third_party/pefile based on current directory and script path. |
18 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', | 18 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', |
19 'third_party', 'pefile')) | 19 'third_party', 'pefile')) |
20 import pefile | 20 import pefile |
21 | 21 |
22 PE_FILE_EXTENSIONS = ['.exe', '.dll'] | 22 PE_FILE_EXTENSIONS = ['.exe', '.dll'] |
23 DYNAMICBASE_FLAG = 0x0040 | 23 DYNAMICBASE_FLAG = 0x0040 |
24 NXCOMPAT_FLAG = 0x0100 | 24 NXCOMPAT_FLAG = 0x0100 |
25 NO_SEH_FLAG = 0x0400 | 25 NO_SEH_FLAG = 0x0400 |
| 26 MACHINE_TYPE_AMD64 = 0x8664 |
26 | 27 |
27 # Please do not add your file here without confirming that it indeed doesn't | 28 # Please do not add your file here without confirming that it indeed doesn't |
28 # require /NXCOMPAT and /DYNAMICBASE. Contact cpu@chromium.org or your local | 29 # require /NXCOMPAT and /DYNAMICBASE. Contact cpu@chromium.org or your local |
29 # Windows guru for advice. | 30 # Windows guru for advice. |
30 EXCLUDED_FILES = ['chrome_frame_mini_installer.exe', | 31 EXCLUDED_FILES = ['chrome_frame_mini_installer.exe', |
31 'mini_installer.exe', | 32 'mini_installer.exe', |
32 'wow_helper.exe'] | 33 'wow_helper.exe'] |
33 | 34 |
34 def IsPEFile(path): | 35 def IsPEFile(path): |
35 return (os.path.isfile(path) and | 36 return (os.path.isfile(path) and |
(...skipping 24 matching lines...) Expand all Loading... |
60 print "Checking %s for /DYNAMICBASE... FAIL" % path | 61 print "Checking %s for /DYNAMICBASE... FAIL" % path |
61 | 62 |
62 # Check for /NXCOMPAT. | 63 # Check for /NXCOMPAT. |
63 if pe.OPTIONAL_HEADER.DllCharacteristics & NXCOMPAT_FLAG: | 64 if pe.OPTIONAL_HEADER.DllCharacteristics & NXCOMPAT_FLAG: |
64 if options.verbose: | 65 if options.verbose: |
65 print "Checking %s for /NXCOMPAT... PASS" % path | 66 print "Checking %s for /NXCOMPAT... PASS" % path |
66 else: | 67 else: |
67 success = False | 68 success = False |
68 print "Checking %s for /NXCOMPAT... FAIL" % path | 69 print "Checking %s for /NXCOMPAT... FAIL" % path |
69 | 70 |
70 # Check for /SAFESEH. Binaries should either have no SEH table | 71 # Check for /SAFESEH. Binaries should meet one of the following |
71 # (in which case a bit is set in the DLL characteristics section) | 72 # criteria: |
72 # or there should be a LOAD_CONFIG section present containing | 73 # 1) Have no SEH table as indicated by the DLL characteristics |
73 # a valid SEH table. | 74 # 2) Have a LOAD_CONFIG section containing a valid SEH table |
| 75 # 3) Be a 64-bit binary, in which case /SAFESEH isn't required |
| 76 # |
| 77 # Refer to the following MSDN article for more information: |
| 78 # http://msdn.microsoft.com/en-us/library/9a89h429.aspx |
74 if (pe.OPTIONAL_HEADER.DllCharacteristics & NO_SEH_FLAG or | 79 if (pe.OPTIONAL_HEADER.DllCharacteristics & NO_SEH_FLAG or |
75 (hasattr(pe, "DIRECTORY_ENTRY_LOAD_CONFIG") and | 80 (hasattr(pe, "DIRECTORY_ENTRY_LOAD_CONFIG") and |
76 pe.DIRECTORY_ENTRY_LOAD_CONFIG.struct.SEHandlerCount > 0 and | 81 pe.DIRECTORY_ENTRY_LOAD_CONFIG.struct.SEHandlerCount > 0 and |
77 pe.DIRECTORY_ENTRY_LOAD_CONFIG.struct.SEHandlerTable != 0)): | 82 pe.DIRECTORY_ENTRY_LOAD_CONFIG.struct.SEHandlerTable != 0) or |
| 83 pe.FILE_HEADER.Machine == MACHINE_TYPE_AMD64): |
78 if options.verbose: | 84 if options.verbose: |
79 print "Checking %s for /SAFESEH... PASS" % path | 85 print "Checking %s for /SAFESEH... PASS" % path |
80 else: | 86 else: |
81 # TODO(scherkus): uncomment this code after we're confident that we | 87 # TODO(scherkus): uncomment this code after we're confident that we |
82 # won't cause unintentional failures on the build bots. | 88 # won't cause unintentional failures on the build bots. |
83 #success = False | 89 #success = False |
84 print "Checking %s for /SAFESEH... FAIL" % path | 90 print "Checking %s for /SAFESEH... FAIL" % path |
85 | 91 |
86 # Update tally. | 92 # Update tally. |
87 if success: | 93 if success: |
88 pe_passed = pe_passed + 1 | 94 pe_passed = pe_passed + 1 |
89 | 95 |
90 print "Result: %d files found, %d files passed" % (pe_total, pe_passed) | 96 print "Result: %d files found, %d files passed" % (pe_total, pe_passed) |
91 if pe_passed != pe_total: | 97 if pe_passed != pe_total: |
92 sys.exit(1) | 98 sys.exit(1) |
93 | 99 |
94 if __name__ == '__main__': | 100 if __name__ == '__main__': |
95 usage = "Usage: %prog [options] DIRECTORY" | 101 usage = "Usage: %prog [options] DIRECTORY" |
96 option_parser = optparse.OptionParser(usage=usage) | 102 option_parser = optparse.OptionParser(usage=usage) |
97 option_parser.add_option("-v", "--verbose", action="store_true", | 103 option_parser.add_option("-v", "--verbose", action="store_true", |
98 default=False, help="Print debug logging") | 104 default=False, help="Print debug logging") |
99 options, args = option_parser.parse_args() | 105 options, args = option_parser.parse_args() |
100 if not args: | 106 if not args: |
101 option_parser.print_help() | 107 option_parser.print_help() |
102 sys.exit(0) | 108 sys.exit(0) |
103 main(options, args) | 109 main(options, args) |
OLD | NEW |