Exemplo n.º 1
0
    def _dump_section_headers(pe):
        """
              Small internal function to dump the section headers in a table. 
              Returns a string to do so.
        """
        section_string = ''
        section_flags = pefile.retrieve_flags(pefile.SECTION_CHARACTERISTICS,
                                              'IMAGE_SCN_')
        section_string += '\nNumber of Sections: %d\n' % pe.FILE_HEADER.NumberOfSections
        section_string += '{0:15} {1:8} {2:40}\n'.format(
            'Section Name', 'Entropy', 'Flags')
        section_string += '-' * 65 + '\n'
        for section in pe.sections:
            # thanks to the pefile example code for this
            flags = []
            for flag in section_flags:
                if getattr(section, flag[0]):
                    flags.append(flag[0])

            # the following line was taken from Didier Steven's pecheck.py code
            section_string += '{0:15} {1:<8.5} {2:40}\n'.format(''.join(filter(lambda c:c != '\0', str(section.Name))), \
                                                                                                        section.get_entropy(),
                                                                                                        ', '.join(flags))
        section_string += '\n'
        return section_string
Exemplo n.º 2
0
    def __repr__(self):
        fobj = "\n\n"
        fobj += "---- File Summary ----\n"
        fobj += "\n"
        fobj += ' General\n'
        fobj += ' {:4}{:<16} {}\n'.format('', "Filename", self.filename)
        fobj += ' {:4}{:<16} {}\n'.format('', "Magic Type", self.magic_type(self.filename))
        fobj += ' {:4}{:<16} {}\n'.format('', "Size", self.filesize)
        fobj += ' {:4}{:<16} {}\n\n'.format('', "First Bytes", self.getbytestring(0, 16))
        fobj += ' Hashes\n'
        fobj += ' {:4}{:<16} {}\n'.format('', "MD5", self.gethash('md5'))
        fobj += ' {:4}{:<16} {}\n'.format('', "SHA1", self.gethash('sha1'))
        fobj += ' {:4}{:<16} {}\n'.format('', "SHA256", self.gethash('sha256'))
        fobj += ' {:4}{:<16} {}\n'.format('', "Import Hash", self.getimphash())
        fobj += ' {:4}{:<16} {}\n\n'.format('', "ssdeep", self.getfuzzyhash())
        fobj += ' Headers\n'

        if self.pe is not None:
            for str_key in self.metadata:
                fobj += ' {:4}{:<16} {}\n'.format('', str_key, self.metadata[str_key])

            fobj += ' {:4}{:<16} {}\n'.format('', "PDB Path", self.get_pdb_path())
            iflags = pefile.retrieve_flags(pefile.IMAGE_CHARACTERISTICS, 'IMAGE_FILE_')

            fobj += ' {:4}{:<16} \n'.format('', "Characteristics")
            for flag in iflags:
                if getattr(self.pe.FILE_HEADER, flag[0]):
                    fobj += " {:20s} {:<20s}\n".format('', str(flag[0]))

        return fobj
Exemplo n.º 3
0
 def get_image_flags(self, imageflags='IMAGE_FILE_'):
     iflags = pefile.retrieve_flags(pefile.IMAGE_CHARACTERISTICS, imageflags)
     flags = []
     for flag in iflags:
         if getattr(self.pe.FILE_HEADER, flag[0]):
             flags.append(flag[0])
     return flags
Exemplo n.º 4
0
def _main():
    if len(sys.argv) != 2:
        usage()

    fn = sys.argv[1]

    # Retrieve code section(s') contents
    code = list()
    pe = pefile.PE(fn)
    for section in pe.sections:
        section_flags = pefile.retrieve_flags(pefile.SECTION_CHARACTERISTICS,
                                              'IMAGE_SCN_')

        isCode = False

        for flag, value in section_flags:
            if section.__dict__[flag] is True:
                if flag == 'IMAGE_SCN_CNT_CODE' or flag == 'IMAGE_SCN_MEM_EXECUTE':
                    isCode = True
                    break

        if isCode:
            offset = section.PointerToRawData
            end = offset + section.SizeOfRawData
            code.extend(pe.__data__[offset:end])

    # Print out code seciton bytes
    #print(code)
    for sec in code:
        print(str(hex(sec))[1:], end="")
Exemplo n.º 5
0
def dump_sections():
    print('\n---------- sections ----------')
    if pe.sections:
        print('{:<10}{:<16}{:<16}{:<16}{:<16}{:<16}'.format(
            'name', 'virtual addr', 'virtual size', 'raw size', 'entropy',
            'flags'))
        section_flags = pefile.retrieve_flags(pefile.SECTION_CHARACTERISTICS,
                                              'IMAGE_SCN_')
        for section in pe.sections:
            s_name = section.Name.rstrip(b'\x00').decode()
            s_vaddr = hex(section.VirtualAddress)
            s_vsize = hex(section.Misc_VirtualSize)
            s_rsize = hex(section.SizeOfRawData)
            s_entropy = section.get_entropy()
            flags = []
            for flag in sorted(section_flags):
                if getattr(section, flag[0]):
                    flags.append(flag[0][10:])
            s_flags = ', '.join(flags)
            print('{:<10}{:<16}{:<16}{:<16}{:<16f}{:<}'.format(
                s_name, s_vaddr, s_vsize, s_rsize, s_entropy, s_flags))
Exemplo n.º 6
0
    def _dump_section_headers(pe):
        """
              Small internal function to dump the section headers in a table. 
              Returns a string to do so.
        """
        section_string = ''
        section_flags = pefile.retrieve_flags(pefile.SECTION_CHARACTERISTICS, 'IMAGE_SCN_')
        section_string += '\nNumber of Sections: %d\n' % pe.FILE_HEADER.NumberOfSections
        section_string += '{0:15} {1:8} {2:40}\n'.format('Section Name', 'Entropy', 'Flags')
        section_string += '-'*65 + '\n'
        for section in pe.sections:
            # thanks to the pefile example code for this
            flags = []
            for flag in section_flags:
                if getattr(section, flag[0]):
                    flags.append(flag[0])

            # the following line was taken from Didier Steven's pecheck.py code
            section_string += '{0:15} {1:<8.5} {2:40}\n'.format(''.join(filter(lambda c:c != '\0', str(section.Name))), \
                                                                                                        section.get_entropy(),
                                                                                                        ', '.join(flags))
        section_string += '\n'
        return section_string        
Exemplo n.º 7
0
    def getSampleFeatures(self):
        try:
            self.pe = pefile.PE(self.exePath)
        except OSError as e:
            print(e)
        except pefile.PEFormatError as e:
            print("---PEFormatError: %s---" % e.value)
        try:
            self.peSignature = hex(
                self.pe.NT_HEADERS.Signature)  #get signature
        except:
            print('No Signature')
        self.peNumberOfSections = self.pe.FILE_HEADER.NumberOfSections  #get number of sections
        self.peEntryAddress = hex(
            self.pe.OPTIONAL_HEADER.AddressOfEntryPoint)  #get address of entry
        self.peImageBase = hex(
            self.pe.OPTIONAL_HEADER.ImageBase)  #get Image Base

        #pe section data
        '''fix for issue where object data would be kept even after the object was deleted'''
        self.peSectionDict.clear()
        self.peSectionArray = []

        sectionPermissions = pefile.retrieve_flags(
            pefile.SECTION_CHARACTERISTICS, 'IMAGE_SCN_'
        )  #returns list of section flags from dict defined in pefile.py
        for section in self.pe.sections:  #loop through all sections
            try:
                self.stringHolder = section.Name.decode(
                    'utf-8')  #name data is in utf-8 format
                self.peSectionName = self.stringHolder.replace(
                    '\x00', '')  #remove extra zero hex values from name
            except:
                self.peSectionName = section.Name

            self.peSectionVirtualAddress = hex(
                section.VirtualAddress)  #get VA of section

            #check if section is at entry point, this is a heuristic explained in (1)
            if self.peSectionVirtualAddress == (self.peEntryAddress +
                                                self.peImageBase):
                self.peSectionIsEntryPoint = True

            self.peSectionVirtualSize = hex(
                section.Misc_VirtualSize)  #get virtual size of section
            self.peSectionRawSize = hex(
                section.SizeOfRawData)  #get size of raw data

            #Add descriptions for section names if known, check for common packer names and non-packer names. This is a heuristic explained in (1)
            if self.peSectionName in self.packerSections:
                self.peSectionNameDescription = self.packerSections[
                    self.peSectionName]
                self.packerSectionName = True
            elif self.peSectionName in self.commonSections:
                self.peSectionNameDescription = self.commonSections[
                    self.peSectionName]
            else:
                self.peSectionNameDescription = 'unknown'
                self.unknownSectionName = True
                self.numberOfUnknownSections += 1
            '''adds permissions to list for each section but not used as a feature in ES document, object flags are set accordingly and used as features'''
            permissions = []
            for permission in sorted(sectionPermissions):
                if getattr(section, permission[0]):
                    permissions.append(permission[0])
                    if (permission[0] == 'IMAGE_SCN_MEM_READ'):
                        self.peSectionRead = True
                    else:
                        self.peSectionRead = False
                    if (permission[0] == 'IMAGE_SCN_MEM_WRITE'):
                        self.peSectionWrite = True
                    else:
                        self.peSectionWrite = False
                    if (permission[0] == 'IMAGE_SCN_MEM_EXECUTE'):
                        self.peSectionExecute = True
                    else:
                        self.peSectionExecute = False
                    if (permission[0] == 'IMAGE_SCN_CNT_CODE'):
                        self.peSectionContainsCode = True
                    else:
                        self.peSectionContainsCode = False
                    if (permission[0] == 'IMAGE_SCN_CNT_INITIALIZED_DATA'):
                        self.peSectionContainsInitData = True
                    else:
                        self.peSectionContainsInitData = False
            '''If a section contains code but is not executable, this is a sign of packing.  This is a heuristic explained in (1)'''
            if (self.peSectionContainsCode == True & self.peSectionExecute ==
                    False):
                self.nonExecutableCodeSection = True
            elif self.nonExecutableCodeSection == False:
                self.nonExecutableCodeSection = False
            '''If a section contains initialized data and is executable, this is a sign of packing.  This is a heuristic explained in (1)'''
            if (self.peSectionContainsInitData == True & self.peSectionExecute
                    == True):
                self.executableDataSection = True
            elif self.executableDataSection == False:
                self.executableDataSection = False

            self.peSectionEntropy = section.get_entropy()  #get entropy (0-8)

            #check for the code section, this is a heuristic explained in (1)
            if self.peSectionName == 'CODE':
                self.containsNamedCodeSection = True
            elif self.containsNamedCodeSection == False:
                self.containsNamedCodeSection = False

            #create dict and add that to an array
            self.peSectionDict = {
                'sectionName': self.peSectionName,
                'sectionVirtualAddress': self.peSectionVirtualAddress,
                'sectionVirtualSize': self.peSectionVirtualSize,
                'sectionRawSize': self.peSectionRawSize,
                'sectionIsEntryPoint': self.peSectionIsEntryPoint,
                'sectionDescription': self.peSectionNameDescription,
                'sectionEntropy': self.peSectionEntropy,
                'sectionRead': self.peSectionRead,
                'sectionWrite': self.peSectionWrite,
                'sectionExecute': self.peSectionExecute,
                'sectionContainsCode': self.peSectionContainsCode,
                'sectionContainsData': self.peSectionContainsInitData
            }
            self.peSectionArray.append(dict(self.peSectionDict))

        try:
            #import data
            self.peNumberOfImports = 0
            for entry in self.pe.DIRECTORY_ENTRY_IMPORT:
                self.stringHolder = entry.dll.decode(
                    'utf-8')  #name data is in utf-8 format
                self.peLibraryName = self.stringHolder.replace(
                    '\x00', '')  #remove extra zero hex values from name

                for func in entry.imports:  #loop through all imports
                    self.stringHolder = func.name.decode(
                        'utf-8')  #name data is in utf-8 format
                    self.peFunctionName = self.stringHolder.replace(
                        '\x00', '')  #remove extra zero hex values from name
                    #self.peFunctionAddress = hex(func.address)#get address
                    self.peImportDict = {
                        'libraryName': self.peLibraryName,
                        'functionName': self.peFunctionName
                    }
                    self.peImportArray.append(dict(self.peImportDict))
                    self.peNumberOfImports += 1
        except:
            print('No Import Data')
            self.peNumberOfImports = 0

        try:
            #export data
            self.peNumberOfExports = 0
            for exp in self.pe.DIRECTORY_ENTRY_EXPORT.symbols:  #loop through exports
                self.stringHolder = exp.name.decode(
                    'utf-8')  #name data is in utf-8 format
                self.peExportName = self.stringHolder.replace(
                    '\x00', '')  #remove extra zero hex values from name
                #self.peExportAddress = hex(self.pe.OPTIONAL_HEADER.ImageBase + exp.address)#get export address
                self.peExportDict = {'exportName': self.peExportName}
                self.peExportArray.append(dict(self.peExportDict))
                self.peNumberOfExports += 1

        except:
            print('No Export Data')
            self.peNumberOfExports = 0

        #build features for the body of ES document
        self.features = {
            'ID': self.sampleIDCounter,
            'fileName': self.fileName,
            'md5': self.md5,
            'numberOfSections': self.peNumberOfSections,
            'addressOfEntry': self.peEntryAddress,
            'imageBase': self.peImageBase
        }
        self.features.update(
            {'sectionData': self.peSectionArray}
        )  #sectionData is a nested object, peSectionArray is an array of dictionary entries
        self.features.update({'packerSectionName': self.packerSectionName})
        self.features.update({'unknownSectionName': self.unknownSectionName})
        self.features.update(
            {'containsNamedCodeSection': self.containsNamedCodeSection})
        self.features.update(
            {'nonExecutableCodeSection': self.nonExecutableCodeSection})
        self.features.update(
            {'executableDataSection': self.executableDataSection})
        self.features.update({'importData':
                              self.peImportArray})  #nested object
        self.features.update({'numberOfImports': self.peNumberOfImports})
        self.features.update({'exportData':
                              self.peExportArray})  #nested object
        self.features.update({'numberOfExports': self.peNumberOfExports})
        #print (self.features)
        self.es.create(index='samples',
                       doc_type='sample',
                       id=self.sampleIDCounter,
                       body=self.features
                       )  #create document with attributes pulled from sample
def dump_info(self):
	"""This is a simplified version of PE.dumpinfo(self)"""
	
	dump = pefile.Dump()
	warnings = self.get_warnings()
	if warnings:
		dump.add_header('Parsing Warnings')
		for warning in warnings:
			dump.add_line(warning)
			
	dump.add_header('PE Sections')
	
	section_flags = pefile.retrieve_flags(pefile.SECTION_CHARACTERISTICS, 'IMAGE_SCN_')
	
	for section in self.sections:
		dump.add_lines(section.dump())
		dump.add('Flags: ')
		flags = []
		for flag in section_flags:
			if getattr(section, flag[0]):
				flags.append(flag[0])
		dump.add_line(', '.join(flags))
		dump.add_line('Entropy: %f (Min=0.0, Max=8.0)' % section.get_entropy() )
		if pefile.md5 is not None:
			dump.add_line('MD5     hash: %s' % section.get_hash_md5() )
		dump.add_newline()
			
	if hasattr(self, 'DIRECTORY_ENTRY_IMPORT'):
		dump.add_header('Imported symbols')
		for module in self.DIRECTORY_ENTRY_IMPORT:
			for symbol in module.imports:
				if symbol.import_by_ordinal is True:
					dump.add('%s Ordinal[%s] (Imported by Ordinal)' % (
						module.dll, str(symbol.ordinal)))
				else:
					dump.add('%s.%s Hint[%s]' % (
						module.dll, symbol.name, str(symbol.hint)))
				
				if symbol.bound:
					dump.add_line(' Bound: 0x%08X' % (symbol.bound))
				else:
					dump.add_newline()
			dump.add_newline()
        
        
	if hasattr(self, 'DIRECTORY_ENTRY_BOUND_IMPORT'):
		dump.add_header('Bound imports')
		for bound_imp_desc in self.DIRECTORY_ENTRY_BOUND_IMPORT:
			dump.add_line('DLL: %s' % bound_imp_desc.name)
			dump.add_newline()
			
			for bound_imp_ref in bound_imp_desc.entries:
				dump.add_lines(bound_imp_ref.struct.dump(), 4)
				dump.add_line('DLL: %s' % bound_imp_ref.name, 4)
				dump.add_newline()

	
	if hasattr(self, 'DIRECTORY_ENTRY_DELAY_IMPORT'):
		dump.add_header('Delay Imported symbols')
		for module in self.DIRECTORY_ENTRY_DELAY_IMPORT:
			for symbol in module.imports:
				if symbol.import_by_ordinal is True:
					dump.add('%s Ordinal[%s] (Imported by Ordinal)' % (
						module.dll, str(symbol.ordinal)))
				else:
					dump.add('%s.%s Hint[%s]' % (
						module.dll, symbol.name, str(symbol.hint)))
				
				if symbol.bound:
					dump.add_line(' Bound: 0x%08X' % (symbol.bound))
				else:
					dump.add_newline()
			dump.add_newline()
	
	return dump.get_text()
Exemplo n.º 9
0
def print_sections(target, dumprva=None):

    try:
        dump_address = dumprva[0]
    except:
        dump_address = 0

    # Get overlay start
    overlay = target.detect_overlay()
    if not target.verbose:

        sdata = "\n ---- Section Overview (use -v for detailed section info)  ----  \n\n"
        sdata += " {:12}{:12}{:18}{:20}{:20}{:20}{:20}\n".format(
            "Name", "Raw Size", "Raw Data Pointer", "Virtual Address",
            "Virtual Size", "Entropy", "Hash")

        for section in target.pe.sections:
            sdata += " {:12}".format(section.Name.strip('\0'))
            sdata += "{:12}".format("{0:#0{1}x}".format(
                section.SizeOfRawData, 10))
            sdata += "{:18}".format("{0:#0{1}x}".format(
                section.PointerToRawData, 10))
            sdata += "{:20}".format("{0:#0{1}x}".format(
                section.VirtualAddress, 10))
            sdata += "{:20}".format("{0:#0{1}x}".format(
                section.Misc_VirtualSize, 10))
            sdata += "{:<20}".format(section.get_entropy())
            sdata += "{:<20}".format(
                hashlib.md5(section.get_data()).hexdigest())
            if dump_address == 'ALL' or dump_address == '{0:#0{1}x}'.format(
                    section.VirtualAddress, 10):
                sdata += "  [Exported]"
                with open(
                        'exported-%s-%s' %
                    (section.Name.strip('\0'), '{0:#0{1}x}'.format(
                        section.VirtualAddress, 10)), 'wb') as out:
                    out.write(section.get_data())
            sdata += "\n"

        # Check for overlay
        if overlay > 0:
            overlay_size = target.filesize - overlay
            sdata += " {:12}".format('.overlay')
            sdata += "{:12}".format("{0:#0{1}x}".format(overlay_size, 10))
            sdata += "{:18}".format(hex(overlay))
            sdata += "{:20}".format('0x00000000')
            sdata += "{:20}".format('0x00000000')
            sdata += "{:<20}".format('0')
            sdata += "{:<20}".format('N/A')
            sdata += "\n"

    else:
        cflags = pefile.retrieve_flags(pefile.SECTION_CHARACTERISTICS,
                                       'IMAGE_SCN_')

        sdata = '\n ---- Detailed Section Info ----  \n\n'
        for section in target.pe.sections:
            sdata += " {:10}\n".format(section.Name.strip('\0'))
            sdata += "  {:24} {:>10}\n".format("|-Entropy:",
                                               section.get_entropy())
            sdata += "  {:24} {:>10}\n".format(
                "|-MD5 Hash:",
                hashlib.md5(section.get_data()).hexdigest())
            sdata += "  {:24} {:>10} ({:})\n".format(
                "|-Raw Data Size:",
                "{0:#0{1}x}".format(section.SizeOfRawData,
                                    10), section.SizeOfRawData)
            sdata += "  {:24} {:>10}\n".format(
                "|-Raw Data Pointer:",
                "{0:#0{1}x}".format(section.PointerToRawData, 10))
            sdata += "  {:24} {:>10}\n".format(
                "|-Virtual Address:",
                "{0:#0{1}x}".format(section.VirtualAddress, 10))
            sdata += "  {:24} {:>10} ({:})\n".format(
                "|-Virtual Size:",
                "{0:#0{1}x}".format(section.Misc_VirtualSize,
                                    10), section.Misc_VirtualSize)
            sdata += "  {:24} {:>10}\n".format(
                "|-Characteristics:",
                "{0:#0{1}x}".format(section.Characteristics, 10))
            for flag in cflags:
                if getattr(section, flag[0]):
                    sdata += "  {:24}{:>5}{:<24}\n".format(
                        '|', '|-', str(flag[0]))
            sdata += "  {:24} {:<10}\n".format("|-Number Of Relocations:",
                                               section.NumberOfRelocations)
            sdata += "  {:24} {:<10}\n".format("|-Line Numbers:",
                                               section.NumberOfLinenumbers)

            if dump_address == 'ALL' or dump_address == '{0:#0{1}x}'.format(
                    section.VirtualAddress, 10):
                sdata += "  |-[Exported]\n"
                with open(
                        'exported-%s-%s' %
                    (section.Name.strip('\0'), '{0:#0{1}x}'.format(
                        section.VirtualAddress, 10)), 'wb') as out:
                    out.write(section.get_data())
            sdata += '\n'

        if overlay > 0:
            sdata += " {:10}\n".format(".overlay")
            sdata += "  {:24} {:>10} ({:})\n".format(
                "|-Raw Data Size:",
                "{0:#0{1}x}".format(target.filesize - overlay,
                                    10), target.filesize - overlay)
            sdata += "  {:24} {:>10}\n".format(
                "|-Raw Data Pointer:", "{0:#0{1}x}".format(overlay, 10))

    print sdata