If the file is a PE/COFF file, computes authenticode hashes on it.

    This checks if the input file is a valid PE/COFF image file (e.g. a
    Windows binary, driver, or DLL) and if yes, sets up a 'finger' for
    fingerprinting in Authenticode style.
    If available, the 'SignedData' section of the image file is retrieved,
    and parsed into its constituent parts. An array of tuples of these
    parts is added to results by HashIt()

    Args:
      hashers: An iterable of hash classes (e.g. out of hashlib) which will
               be instantiated for use. If 'None' is provided, a default set
               of hashers is used. To select no hash function (e.g. to only
               extract metadata), use an empty iterable.

    Returns:
      True if the file is detected as a valid PE/COFF image file,
      False otherwise.

def EvalPecoff(self, hashers=None):
    """If the file is a PE/COFF file, computes authenticode hashes on it.

    This checks if the input file is a valid PE/COFF image file (e.g. a
    Windows binary, driver, or DLL) and if yes, sets up a 'finger' for
    fingerprinting in Authenticode style.
    If available, the 'SignedData' section of the image file is retrieved,
    and parsed into its constituent parts. An array of tuples of these
    parts is added to results by HashIt()

    Args:
      hashers: An iterable of hash classes (e.g. out of hashlib) which will
               be instantiated for use. If 'None' is provided, a default set
               of hashers is used. To select no hash function (e.g. to only
               extract metadata), use an empty iterable.

    Returns:
      True if the file is detected as a valid PE/COFF image file,
      False otherwise.
    """
    try:
      extents = self._PecoffHeaderParser()
    except struct.error:
      # Parsing the header failed. Just ignore this, and claim
      # that the file is not a valid PE/COFF image file.
      extents = None
    if extents is None:
      return False

    signed_data = None
    ranges = []
    start = 0
    # Ordering of these conditions matches expected order in file.
    # If a condition holds true, the matching range is skipped for hashing.
    if 'CheckSum' in extents:
      ranges.append(Range(start, end=extents['CheckSum'].start))
      start = sum(extents['CheckSum'])
      # New start now points past CheckSum area.
    if 'CertTable' in extents:
      ranges.append(Range(start, end=extents['CertTable'].start))
      start = sum(extents['CertTable'])
      # New start now points past CertTable area.
    if 'SignedData' in extents:
      # Exclude the range even if the blob itself can't be parsed correctly.
      ranges.append(Range(start, end=extents['SignedData'].start))
      start = sum(extents['SignedData'])
      # New start now points past SignedData area.
      signed_data = self._CollectSignedData(extents['SignedData'])
    ranges.append(Range(start, end=self.filelength))

    if hashers is None:
      hashers = Fingerprinter.AUTHENTICODE_HASH_CLASSES
    hashfuncs = [x() for x in hashers]
    metadata = {'name': 'pecoff'}
    if signed_data:
      metadata['SignedData'] = signed_data
    finger = Finger(hashfuncs, ranges, metadata)
    self.fingers.append(finger)
    return True