'Parses PECOFF headers.
Reads header magic and some data structures in a file to determine if
it is a valid PECOFF header, and figure out the offsets at which
relevant data is stored.
While this code contains multiple seeks and small reads, that is
compensated by the underlying libc buffering mechanism.
Returns:
None if the parsed file is not PECOFF.
A dict with offsets and lengths for CheckSum, CertTable, and SignedData
fields in the PECOFF binary, for those that are present.'

def _PecoffHeaderParser(self):

    extents = {}
    self.file.seek(0, os.SEEK_SET)
    buf = self.file.read(2)
    if (buf != 'MZ'):
        return None
    self.file.seek(60, os.SEEK_SET)
    buf = self.file.read(4)
    pecoff_sig_offset = struct.unpack('<I', buf)[0]
    if (pecoff_sig_offset >= self.filelength):
        return None
    self.file.seek(pecoff_sig_offset, os.SEEK_SET)
    buf = self.file.read(4)
    if (buf != 'PE\x00\x00'):
        return None
    self.file.seek((pecoff_sig_offset + 20), os.SEEK_SET)
    buf = self.file.read(2)
    optional_header_size = struct.unpack('<H', buf)[0]
    optional_header_offset = ((pecoff_sig_offset + 4) + 20)
    if ((optional_header_size + optional_header_offset) > self.filelength):
        return None
    if (optional_header_size < 68):
        return None
    self.file.seek(optional_header_offset, os.SEEK_SET)
    buf = self.file.read(2)
    image_magic = struct.unpack('<H', buf)[0]
    if (image_magic == 267):
        rva_base = (optional_header_offset + 92)
        cert_base = (optional_header_offset + 128)
    elif (image_magic == 523):
        rva_base = (optional_header_offset + 108)
        cert_base = (optional_header_offset + 144)
    else:
        return None
    extents['CheckSum'] = RelRange((optional_header_offset + 64), 4)
    self.file.seek(rva_base, os.SEEK_SET)
    buf = self.file.read(4)
    number_of_rva = struct.unpack('<I', buf)[0]
    if ((number_of_rva < 5) or ((optional_header_offset + optional_header_size) < (cert_base + 8))):
        return extents
    extents['CertTable'] = RelRange(cert_base, 8)
    self.file.seek(cert_base, os.SEEK_SET)
    buf = self.file.read(8)
    (start, length) = struct.unpack('<II', buf)
    if ((length == 0) or (start < (optional_header_offset + optional_header_size)) or ((start + length) > self.filelength)):
        return extents
    extents['SignedData'] = RelRange(start, length)
    return extents
