Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: tools/checkbins/checkbins.py

Issue 8584009: Add a check for /SAFESEH in checkbins.py. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« tools/checkbins/checkbins.bat ('K') | « tools/checkbins/checkbins.bat ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
M-A Ruel 2011/11/21 19:58:34 #!/usr/bin/env python
scherkus (not reviewing) 2011/11/21 20:33:58 Done.
2 # Copyright (c) 2010 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 Currently this tool will check that binaries were built with /NXCOMPAT and 9 In essense it runs a subset of BinScope tests ensuring that binaries have
10 /DYNAMICBASE set. 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 26
26 # Please do not add your file here without confirming that it indeed doesn't 27 # Please do not add your file here without confirming that it indeed doesn't
27 # require /NXCOMPAT and /DYNAMICBASE. Contact cpu@chromium.org or your local 28 # require /NXCOMPAT and /DYNAMICBASE. Contact cpu@chromium.org or your local
28 # Windows guru for advice. 29 # Windows guru for advice.
29 EXCLUDED_FILES = ['chrome_frame_mini_installer.exe', 30 EXCLUDED_FILES = ['chrome_frame_mini_installer.exe',
30 'mini_installer.exe', 31 'mini_installer.exe',
31 'wow_helper.exe'] 32 'wow_helper.exe']
32 33
33 def IsPEFile(path): 34 def IsPEFile(path):
34 return (os.path.isfile(path) and 35 return (os.path.isfile(path) and
35 os.path.splitext(path)[1].lower() in PE_FILE_EXTENSIONS and 36 os.path.splitext(path)[1].lower() in PE_FILE_EXTENSIONS and
36 os.path.basename(path) not in EXCLUDED_FILES) 37 os.path.basename(path) not in EXCLUDED_FILES)
37 38
38 def main(options, args): 39 def main(options, args):
39 directory = args[0] 40 directory = args[0]
40 pe_total = 0 41 pe_total = 0
41 pe_passed = 0 42 pe_passed = 0
42 43
43 for file in os.listdir(directory): 44 for file in os.listdir(directory):
44 path = os.path.abspath(os.path.join(directory, file)) 45 path = os.path.abspath(os.path.join(directory, file))
45 if not IsPEFile(path): 46 if not IsPEFile(path):
46 continue 47 continue
47 pe = pefile.PE(path, fast_load=True) 48 pe = pefile.PE(path, fast_load=True)
49 pe.parse_data_directories(directories=[
50 pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG']])
48 pe_total = pe_total + 1 51 pe_total = pe_total + 1
49 success = True 52 success = True
50 53
51 # Check for /DYNAMICBASE. 54 # Check for /DYNAMICBASE.
52 if pe.OPTIONAL_HEADER.DllCharacteristics & DYNAMICBASE_FLAG: 55 if pe.OPTIONAL_HEADER.DllCharacteristics & DYNAMICBASE_FLAG:
53 if options.verbose: 56 if options.verbose:
54 print "Checking %s for /DYNAMICBASE... PASS" % path 57 print "Checking %s for /DYNAMICBASE... PASS" % path
55 else: 58 else:
56 success = False 59 success = False
57 print "Checking %s for /DYNAMICBASE... FAIL" % path 60 print "Checking %s for /DYNAMICBASE... FAIL" % path
58 61
59 # Check for /NXCOMPAT. 62 # Check for /NXCOMPAT.
60 if pe.OPTIONAL_HEADER.DllCharacteristics & NXCOMPAT_FLAG: 63 if pe.OPTIONAL_HEADER.DllCharacteristics & NXCOMPAT_FLAG:
61 if options.verbose: 64 if options.verbose:
62 print "Checking %s for /NXCOMPAT... PASS" % path 65 print "Checking %s for /NXCOMPAT... PASS" % path
63 else: 66 else:
64 success = False 67 success = False
65 print "Checking %s for /NXCOMPAT... FAIL" % path 68 print "Checking %s for /NXCOMPAT... FAIL" % path
66 69
70 # Check for /SAFESEH. Binaries should either have no SEH table
71 # (in which case a bit is set in the DLL characteristics section)
72 # or there should be a LOAD_CONFIG section present containing
73 # the SEH table.
74 if (pe.OPTIONAL_HEADER.DllCharacteristics & NO_SEH_FLAG or
75 hasattr(pe, "DIRECTORY_ENTRY_LOAD_CONFIG")):
Sigurður Ásgeirsson 2011/11/21 20:27:32 The load config, if present, also needs to have a
scherkus (not reviewing) 2011/11/21 20:33:58 Done.
76 if options.verbose:
77 print "Checking %s for /SAFESEH... PASS" % path
78 else:
79 # TODO(scherkus): uncomment this code after we're confident that we
80 # won't cause unintentional failures on the build bots.
81 #success = False
82 print "Checking %s for /SAFESEH... FAIL" % path
83
67 # Update tally. 84 # Update tally.
68 if success: 85 if success:
69 pe_passed = pe_passed + 1 86 pe_passed = pe_passed + 1
70 87
71 print "Result: %d files found, %d files passed" % (pe_total, pe_passed) 88 print "Result: %d files found, %d files passed" % (pe_total, pe_passed)
72 if pe_passed != pe_total: 89 if pe_passed != pe_total:
73 sys.exit(1) 90 sys.exit(1)
74 91
75 if __name__ == '__main__': 92 if __name__ == '__main__':
76 usage = "Usage: %prog [options] DIRECTORY" 93 usage = "Usage: %prog [options] DIRECTORY"
77 option_parser = optparse.OptionParser(usage=usage) 94 option_parser = optparse.OptionParser(usage=usage)
78 option_parser.add_option("-v", "--verbose", action="store_true", 95 option_parser.add_option("-v", "--verbose", action="store_true",
79 default=False, help="Print debug logging") 96 default=False, help="Print debug logging")
80 options, args = option_parser.parse_args() 97 options, args = option_parser.parse_args()
81 if not args: 98 if not args:
82 option_parser.print_help() 99 option_parser.print_help()
83 sys.exit(0) 100 sys.exit(0)
84 main(options, args) 101 main(options, args)
OLDNEW
« tools/checkbins/checkbins.bat ('K') | « tools/checkbins/checkbins.bat ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698