#!/usr/bin/python # Copyright (c) 2010 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Makes sure that all EXE and DLL files in the provided directory were built correctly. Currently this tool will check that binaries were built with /NXCOMPAT and /DYNAMICBASE set. """ import os import optparse import sys # Find /third_party/pefile based on current directory and script path. sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'third_party', 'pefile')) import pefile PE_FILE_EXTENSIONS = ['.exe', '.dll'] DYNAMICBASE_FLAG = 0x0040 NXCOMPAT_FLAG = 0x0100 # Please do not add your file here without confirming that it indeed doesn't # require /NXCOMPAT and /DYNAMICBASE. Contact cpu@chromium.org or your local # Windows guru for advice. EXCLUDED_FILES = ['chrome_frame_mini_installer.exe', 'mini_installer.exe', 'wow_helper.exe'] def IsPEFile(path): return (os.path.isfile(path) and os.path.splitext(path)[1].lower() in PE_FILE_EXTENSIONS and os.path.basename(path) not in EXCLUDED_FILES) def main(options, args): directory = args[0] pe_total = 0 pe_passed = 0 for file in os.listdir(directory): path = os.path.abspath(os.path.join(directory, file)) if not IsPEFile(path): continue pe = pefile.PE(path, fast_load=True) pe_total = pe_total + 1 success = True # Check for /DYNAMICBASE. if pe.OPTIONAL_HEADER.DllCharacteristics & DYNAMICBASE_FLAG: if options.verbose: print "Checking %s for /DYNAMICBASE... PASS" % path else: success = False print "Checking %s for /DYNAMICBASE... FAIL" % path # Check for /NXCOMPAT. if pe.OPTIONAL_HEADER.DllCharacteristics & NXCOMPAT_FLAG: if options.verbose: print "Checking %s for /NXCOMPAT... PASS" % path else: success = False print "Checking %s for /NXCOMPAT... FAIL" % path # Update tally. if success: pe_passed = pe_passed + 1 print "Result: %d files found, %d files passed" % (pe_total, pe_passed) if pe_passed != pe_total: sys.exit(1) if __name__ == '__main__': usage = "Usage: %prog [options] DIRECTORY" option_parser = optparse.OptionParser(usage=usage) option_parser.add_option("-v", "--verbose", action="store_true", default=False, help="Print debug logging") options, args = option_parser.parse_args() if not args: option_parser.print_help() sys.exit(0) main(options, args)