    def gather_file_info_win(self):
        """
        Gathers necessary PE header information to backdoor
        a file and returns a dict of file information called flItms.
        Takes a open file handle of self.binary
        """

        self.binary.seek(int('3C', 16))
        print "[*] Gathering file info"
        self.flItms['filename'] = self.FILE
        self.flItms['buffer'] = 0
        self.flItms['JMPtoCodeAddress'] = 0
        self.flItms['LocOfEntryinCode_Offset'] = self.DISK_OFFSET
        self.flItms['dis_frm_pehdrs_sectble'] = 248
        self.flItms['pe_header_location'] = struct.unpack('<i', self.binary.read(4))[0]
        # Start of COFF
        self.flItms['COFF_Start'] = self.flItms['pe_header_location'] + 4
        self.binary.seek(self.flItms['COFF_Start'])
        self.flItms['MachineType'] = struct.unpack('<H', self.binary.read(2))[0]
        if self.VERBOSE is True:
            for mactype, name in MachineTypes.iteritems():
                if int(mactype, 16) == self.flItms['MachineType']:
                        print 'MachineType is:', name
        self.binary.seek(self.flItms['COFF_Start'] + 2, 0)
        self.flItms['NumberOfSections'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['TimeDateStamp'] = struct.unpack('<I', self.binary.read(4))[0]
        self.binary.seek(self.flItms['COFF_Start'] + 16, 0)
        self.flItms['SizeOfOptionalHeader'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['Characteristics'] = struct.unpack('<H', self.binary.read(2))[0]
        #End of COFF
        self.flItms['OptionalHeader_start'] = self.flItms['COFF_Start'] + 20

        #if self.flItms['SizeOfOptionalHeader']:
            #Begin Standard Fields section of Optional Header
        self.binary.seek(self.flItms['OptionalHeader_start'])
        self.flItms['Magic'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['MajorLinkerVersion'] = struct.unpack("!B", self.binary.read(1))[0]
        self.flItms['MinorLinkerVersion'] = struct.unpack("!B", self.binary.read(1))[0]
        self.flItms['SizeOfCode'] = struct.unpack("<I", self.binary.read(4))[0]
        self.flItms['SizeOfInitializedData'] = struct.unpack("<I", self.binary.read(4))[0]
        self.flItms['SizeOfUninitializedData'] = struct.unpack("<I",
                                                               self.binary.read(4))[0]
        self.flItms['AddressOfEntryPoint'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['PatchLocation'] = self.flItms['AddressOfEntryPoint']
        self.flItms['BaseOfCode'] = struct.unpack('<I', self.binary.read(4))[0]
        if self.flItms['Magic'] != 0x20B:
            self.flItms['BaseOfData'] = struct.unpack('<I', self.binary.read(4))[0]
        # End Standard Fields section of Optional Header
        # Begin Windows-Specific Fields of Optional Header
        if self.flItms['Magic'] == 0x20B:
            self.flItms['ImageBase'] = struct.unpack('<Q', self.binary.read(8))[0]
        else:
            self.flItms['ImageBase'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['SectionAlignment'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['FileAlignment'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['MajorOperatingSystemVersion'] = struct.unpack('<H',
                                                                   self.binary.read(2))[0]
        self.flItms['MinorOperatingSystemVersion'] = struct.unpack('<H',
                                                                   self.binary.read(2))[0]
        self.flItms['MajorImageVersion'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['MinorImageVersion'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['MajorSubsystemVersion'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['MinorSubsystemVersion'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['Win32VersionValue'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['SizeOfImageLoc'] = self.binary.tell()
        self.flItms['SizeOfImage'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['SizeOfHeaders'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['CheckSum'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['Subsystem'] = struct.unpack('<H', self.binary.read(2))[0]
        self.flItms['DllCharacteristics'] = struct.unpack('<H', self.binary.read(2))[0]
        if self.flItms['Magic'] == 0x20B:
            self.flItms['SizeOfStackReserve'] = struct.unpack('<Q', self.binary.read(8))[0]
            self.flItms['SizeOfStackCommit'] = struct.unpack('<Q', self.binary.read(8))[0]
            self.flItms['SizeOfHeapReserve'] = struct.unpack('<Q', self.binary.read(8))[0]
            self.flItms['SizeOfHeapCommit'] = struct.unpack('<Q', self.binary.read(8))[0]

        else:
            self.flItms['SizeOfStackReserve'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['SizeOfStackCommit'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['SizeOfHeapReserve'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['SizeOfHeapCommit'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['LoaderFlags'] = struct.unpack('<I', self.binary.read(4))[0]  # zero
        self.flItms['NumberofRvaAndSizes'] = struct.unpack('<I', self.binary.read(4))[0]
        # End Windows-Specific Fields of Optional Header
        # Begin Data Directories of Optional Header
        self.flItms['ExportTableRVA'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['ExportTableSize'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['ImportTableLOCInPEOptHdrs'] = self.binary.tell()
        #ImportTable SIZE|LOC
        self.flItms['ImportTableRVA'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['ImportTableSize'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['ResourceTable'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['ExceptionTable'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['CertTableLOC'] = self.binary.tell()
        self.flItms['CertLOC'] = struct.unpack("<I", self.binary.read(4))[0]
        self.flItms['CertSize'] = struct.unpack("<I", self.binary.read(4))[0]
        self.flItms['BaseReLocationTable'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['Debug'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['Architecture'] = struct.unpack('<Q', self.binary.read(8))[0]  # zero
        self.flItms['GlobalPrt'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['TLS Table'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['LoadConfigTableRVA'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['LoadConfigTableSize'] = struct.unpack('<I', self.binary.read(4))[0]
        #self.flItms['LoadConfigTable'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['BoundImportLocation'] = self.binary.tell()
        self.flItms['BoundImport'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.binary.seek(self.flItms['BoundImportLocation'])
        self.flItms['BoundImportLOCinCode'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['BoundImportSize'] = struct.unpack('<I', self.binary.read(4))[0]
        self.flItms['IAT'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['DelayImportDesc'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['CLRRuntimeHeader'] = struct.unpack('<Q', self.binary.read(8))[0]
        self.flItms['Reserved'] = struct.unpack('<Q', self.binary.read(8))[0]  # zero
        self.flItms['BeginSections'] = self.binary.tell()

        # This could be fixed in the great refactor.
        if self.flItms['NumberOfSections'] is not 0 and 'Section' not in self.flItms:
            self.flItms['Sections'] = []
            for section in range(self.flItms['NumberOfSections']):
                sectionValues = []
                sectionValues.append(self.binary.read(8))
                # VirtualSize
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                # VirtualAddress
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                # SizeOfRawData
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                # PointerToRawData
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                # PointerToRelocations
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                # PointerToLinenumbers
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                # NumberOfRelocations
                sectionValues.append(struct.unpack('<H', self.binary.read(2))[0])
                # NumberOfLinenumbers
                sectionValues.append(struct.unpack('<H', self.binary.read(2))[0])
                # SectionFlags
                sectionValues.append(struct.unpack('<I', self.binary.read(4))[0])
                self.flItms['Sections'].append(sectionValues)
                if 'UPX1'.lower() in sectionValues[0].lower():
                    print "[*] UPX packed, continuing..."

                if ('.text\x00\x00\x00' == sectionValues[0] or
                    'AUTO\x00\x00\x00\x00' == sectionValues[0] or
                    'UPX1\x00\x00\x00\x00' == sectionValues[0] or
                    'CODE\x00\x00\x00\x00' == sectionValues[0]):
                    self.flItms['textSectionName'] = sectionValues[0]
                    self.flItms['textVirtualSize'] = sectionValues[1]
                    self.flItms['textVirtualAddress'] = sectionValues[2]
                    self.flItms['textSizeRawData'] = sectionValues[3]
                    self.flItms['textPointerToRawData'] = sectionValues[4]

                    self.flItms['LocOfEntryinCode'] = (self.flItms['AddressOfEntryPoint'] -
                                                       self.flItms['textVirtualAddress'] +
                                                       self.flItms['textPointerToRawData'] +
                                                       self.flItms['LocOfEntryinCode_Offset'])
                elif '.rsrc\x00\x00\x00' == sectionValues[0]:
                    self.flItms['rsrcSectionName'] = sectionValues[0]
                    self.flItms['rsrcVirtualSize'] = sectionValues[1]
                    self.flItms['rsrcVirtualAddress'] = sectionValues[2]
                    self.flItms['rsrcSizeRawData'] = sectionValues[3]
                    self.flItms['rsrcPointerToRawData'] = sectionValues[4]

            # I could add in checks here to support an out of order PE file;
            #  However if here were multiple sections that were RE, RWE, it would be
            #  difficult to get it right in a purposefully mangled binary.
            #  Perhaps if entrypoint is in RE section that is text section? But still.
            #  That could be spoofed and it returns to another RE section.
            if self.PATCH_METHOD != 'onionduke':
                if "textSectionName" not in self.flItms:
                    print "[!] Text section does not have a normal name, not guessing, exiting"
                    print "[!]\tFirst section, text section potential name:", str(self.flItms['Sections'][0][0])
                    return False
            else:
                self.flItms['LocOfEntryinCode'] = (self.flItms['AddressOfEntryPoint'] -
                                                   self.flItms['LocOfEntryinCode_Offset'])
            self.flItms['VirtualAddress'] = self.flItms['SizeOfImage']

        else:
            self.flItms['LocOfEntryinCode'] = (self.flItms['AddressOfEntryPoint'] -
                                               self.flItms['LocOfEntryinCode_Offset'])

        self.flItms['VrtStrtngPnt'] = (self.flItms['AddressOfEntryPoint'] +
                                       self.flItms['ImageBase'])
        self.binary.seek(self.flItms['BoundImportLOCinCode'])
        self.flItms['ImportTableALL'] = self.binary.read(self.flItms['BoundImportSize'])
        self.flItms['NewIATLoc'] = self.flItms['BoundImportLOCinCode'] + 40
        
        #ParseLoadConfigTable
        self.flItms['LoadConfigTablePresent'] = False
                
        for section in reversed(self.flItms['Sections']):
            if self.flItms['LoadConfigTableRVA'] >= section[2]:
                #go to exact export directory location
                self.flItms['LoadConfigTablePresent'] = True
                self.binary.seek((self.flItms['LoadConfigTableRVA'] - section[2]) + section[4])
                self.flItms['LoadConfigTable_OFFSET'] = - section[2] + section[4]
                break

        if self.flItms['LoadConfigTablePresent'] is True:
                
            # This is for 32bit... need x64
            self.flItms['LoadConfigDirectory_Size'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['LoadConfigDirectory_TimeDataStamp'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['LoadConfigDirectory_MajorVersion'] = struct.unpack('<H', self.binary.read(2))[0]
            self.flItms['LoadConfigDirectory_MinorVersion'] = struct.unpack('<H', self.binary.read(2))[0]
            self.flItms['LoadConfigDirectory_GFC'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['LoadConfigDirectory_GFS'] = struct.unpack('<I', self.binary.read(4))[0]
            self.flItms['LoadConfigDirectory_CSDT'] = struct.unpack('<I', self.binary.read(4))[0]
            
            if self.flItms['Magic'] == 0x20B:
                #  winx64
                self.flItms['LoadConfigDirectory_DFBT'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_DTFT'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_LPTV'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_MAS'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_VMT'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_PAM'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_PHF'] = struct.unpack('<I', self.binary.read(4))[0]
            else:
                #  winx86
                self.flItms['LoadConfigDirectory_DFBT'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_DTFT'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_LPTV'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_MAS'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_VMT'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_PHF'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_PAM'] = struct.unpack('<I', self.binary.read(4))[0]
            
            self.flItms['LoadConfigDirectory_CSDV'] = struct.unpack('<H', self.binary.read(2))[0]
            self.flItms['LoadConfigDirectory_Reserved'] = struct.unpack('<H', self.binary.read(2))[0]
            
            if self.flItms['Magic'] == 0x20B:
                self.flItms['LoadConfigDirectory_ELVA'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_SCVA'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_SEHTVA'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LoadConfigDirectory_SEHC'] = struct.unpack('<Q', self.binary.read(8))[0]
           
            else:
                self.flItms['LoadConfigDirectory_ELVA'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_SCVA'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_SEHTVA'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LoadConfigDirectory_SEHC'] = struct.unpack('<I', self.binary.read(4))[0]
            
            #grab CFG info
            if self.flItms['Magic'] == 0x20B and self.flItms['LoadConfigDirectory_Size'] > 0x70:
                self.flItms['LCD_CFG_address_CF_PTR_LOC'] = self.binary.tell()
                self.flItms['LCD_CFG_address_CF_PTR'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LCD_CFG_dispatch_fptr'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LCD_CFG_Func_Table'] = struct.unpack('<Q', self.binary.read(8))[0]
                self.flItms['LCD_CFG_Func_Count'] = struct.unpack('<Q', self.binary.read(8))[0]
                # Zero out LCD_CFG_Guard_Flags to disable CFG
                self.flItms['LCD_CFG_Guard_Flags'] = struct.unpack('<Q', self.binary.read(8))[0]
            elif self.flItms['Magic'] == 0x10B and self.flItms['LoadConfigDirectory_Size'] > 0x48:
                self.flItms['LCD_CFG_address_CF_PTR_LOC'] = self.binary.tell()
                self.flItms['LCD_CFG_address_CF_PTR'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LCD_CFG_dispatch_fptr'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LCD_CFG_Func_Table'] = struct.unpack('<I', self.binary.read(4))[0]
                self.flItms['LCD_CFG_Func_Count'] = struct.unpack('<I', self.binary.read(4))[0]
                # Zero out LCD_CFG_Guard_Flags to disable CFG
                self.flItms['LCD_CFG_Guard_Flags'] = struct.unpack('<I', self.binary.read(4))[0]

            #  Find CFG_PTR_LOC 
            if "LCD_CFG_dispatch_fptr" in self.flItms:
                if self.flItms['LCD_CFG_dispatch_fptr'] != 0:
                    self.flItms['LCD_CFG_dispatch_fptr_LOC'] = self.flItms['LCD_CFG_dispatch_fptr'] - self.flItms['ImageBase'] + self.flItms['LoadConfigTable_OFFSET']
                    self.binary.seek(self.flItms['LCD_CFG_dispatch_fptr_LOC'],0)
                    if self.flItms['Magic'] == 0x20B:
                        self.flItms['CFG_text_LOC'] = struct.unpack('<Q', self.binary.read(8))[0] 
                    else: 
                        self.flItms['CFG_text_LOC'] = struct.unpack('<I', self.binary.read(4))[0]
Gathers necessary PE header information to backdoor
a file and returns a dict of file information called flItms.
Takes a open file handle of self.binary
pebin.py