third_party/pefile_py3/pefile.py
def parse_import_directory(self, rva, size, dllnames_only=False):
        """Walk and parse the import directory."""

        import_descs =  []
        error_count = 0
        while True:
            try:
                # If the RVA is invalid all would blow up. Some EXEs seem to be
                # specially nasty and have an invalid RVA.
                data = self.get_data(rva, Structure(
                        self.__IMAGE_IMPORT_DESCRIPTOR_format__).sizeof() )
            except PEFormatError as e:
                self.__warnings.append(
                    'Error parsing the import directory at RVA: 0x%x' % ( rva ) )
                break

            file_offset = self.get_offset_from_rva(rva)
            import_desc =  self.__unpack_data__(
                self.__IMAGE_IMPORT_DESCRIPTOR_format__,
                data, file_offset = file_offset )

            # If the structure is all zeros, we reached the end of the list
            if not import_desc or import_desc.all_zeroes():
                break

            rva += import_desc.sizeof()

            # If the array of thunks is somewhere earlier than the import
            # descriptor we can set a maximum length for the array. Otherwise
            # just set a maximum length of the size of the file
            max_len = len(self.__data__) - file_offset
            if rva > import_desc.OriginalFirstThunk or rva > import_desc.FirstThunk:
                max_len = max(rva-import_desc.OriginalFirstThunk, rva-import_desc.FirstThunk)

            import_data = []
            if not dllnames_only:
                try:
                    import_data = self.parse_imports(
                        import_desc.OriginalFirstThunk,
                        import_desc.FirstThunk,
                        import_desc.ForwarderChain,
                        max_length = max_len)
                except PEFormatError as e:
                    self.__warnings.append(
                        'Error parsing the import directory. '
                        'Invalid Import data at RVA: 0x{0:x} ({1})'.format(
                            rva, e.value))

                if error_count > 5:
                    self.__warnings.append(
                        'Too many errors parsing the import directory. '
                        'Invalid import data at RVA: 0x{0:x}'.format(rva) )
                    break

                if not import_data:
                    error_count += 1
                    # TODO: do not continue here
                    continue

            dll = self.get_string_at_rva(import_desc.Name, MAX_DLL_LENGTH)
            if not is_valid_dos_filename(dll):
                dll = b('*invalid*')

            if dll:
                for symbol in import_data:
                    if symbol.name is None:
                        funcname = ordlookup.ordLookup(dll.lower(), symbol.ordinal)
                        if funcname:
                            symbol.name = funcname
                import_descs.append(
                    ImportDescData(
                        struct = import_desc,
                        imports = import_data,
                        dll = dll))

        if not dllnames_only:
            suspicious_imports = set([ u'LoadLibrary', u'GetProcAddress' ])
            suspicious_imports_count = 0
            total_symbols = 0
            for imp_dll in import_descs:
                for symbol in imp_dll.imports:
                    for suspicious_symbol in suspicious_imports:
                        if not symbol or not symbol.name:
                            continue
                        name = symbol.name
                        if type(symbol.name) == bytes:
                            name = symbol.name.decode('utf-8')
                        if name.startswith(suspicious_symbol):
                            suspicious_imports_count += 1
                            break
                    total_symbols += 1
            if suspicious_imports_count == len(suspicious_imports) and total_symbols < 20:
                self.__warnings.append(
                    'Imported symbols contain entries typical of packed executables.' )

        return import_descs
Walk and parse the import directory.
Walk and parse the import directory.
Walk and parse the import directory .
def parse_import_directory(self, rva, size, dllnames_only=False):
        import_descs =  []
        error_count = 0
        while True:
            try:
                data = self.get_data(rva, Structure(
                        self.__IMAGE_IMPORT_DESCRIPTOR_format__).sizeof() )
            except PEFormatError as e:
                self.__warnings.append(
                    'Error parsing the import directory at RVA: 0x%x' % ( rva ) )
                break
            file_offset = self.get_offset_from_rva(rva)
            import_desc =  self.__unpack_data__(
                self.__IMAGE_IMPORT_DESCRIPTOR_format__,
                data, file_offset = file_offset )
            if not import_desc or import_desc.all_zeroes():
                break
            rva += import_desc.sizeof()
            max_len = len(self.__data__) - file_offset
            if rva > import_desc.OriginalFirstThunk or rva > import_desc.FirstThunk:
                max_len = max(rva-import_desc.OriginalFirstThunk, rva-import_desc.FirstThunk)
            import_data = []
            if not dllnames_only:
                try:
                    import_data = self.parse_imports(
                        import_desc.OriginalFirstThunk,
                        import_desc.FirstThunk,
                        import_desc.ForwarderChain,
                        max_length = max_len)
                except PEFormatError as e:
                    self.__warnings.append(
                        'Error parsing the import directory. '
                        'Invalid Import data at RVA: 0x{0:x} ({1})'.format(
                            rva, e.value))
                if error_count > 5:
                    self.__warnings.append(
                        'Too many errors parsing the import directory. '
                        'Invalid import data at RVA: 0x{0:x}'.format(rva) )
                    break
                if not import_data:
                    error_count += 1
                    continue
            dll = self.get_string_at_rva(import_desc.Name, MAX_DLL_LENGTH)
            if not is_valid_dos_filename(dll):
                dll = b('*invalid*')
            if dll:
                for symbol in import_data:
                    if symbol.name is None:
                        funcname = ordlookup.ordLookup(dll.lower(), symbol.ordinal)
                        if funcname:
                            symbol.name = funcname
                import_descs.append(
                    ImportDescData(
                        struct = import_desc,
                        imports = import_data,
                        dll = dll))
        if not dllnames_only:
            suspicious_imports = set([ u'LoadLibrary', u'GetProcAddress' ])
            suspicious_imports_count = 0
            total_symbols = 0
            for imp_dll in import_descs:
                for symbol in imp_dll.imports:
                    for suspicious_symbol in suspicious_imports:
                        if not symbol or not symbol.name:
                            continue
                        name = symbol.name
                        if type(symbol.name) == bytes:
                            name = symbol.name.decode('utf-8')
                        if name.startswith(suspicious_symbol):
                            suspicious_imports_count += 1
                            break
                    total_symbols += 1
            if suspicious_imports_count == len(suspicious_imports) and total_symbols < 20:
                self.__warnings.append(
                    'Imported symbols contain entries typical of packed executables.' )
        return import_descs
def parse_import_directory ( self , rva , size , dllnames_only = False ) : import_descs = [ ] error_count = 0 while True : try : data = self . get_data ( rva , Structure ( self . __IMAGE_IMPORT_DESCRIPTOR_format__ ) . sizeof ( ) ) except PEFormatError as e : self . __warnings . append ( 'Error parsing the import directory at RVA: 0x%x' % ( rva ) ) break file_offset = self . get_offset_from_rva ( rva ) import_desc = self . __unpack_data__ ( self . __IMAGE_IMPORT_DESCRIPTOR_format__ , data , file_offset = file_offset ) if not import_desc or import_desc . all_zeroes ( ) : break rva += import_desc . sizeof ( ) max_len = len ( self . __data__ ) - file_offset if rva > import_desc . OriginalFirstThunk or rva > import_desc . FirstThunk : max_len = max ( rva - import_desc . OriginalFirstThunk , rva - import_desc . FirstThunk ) import_data = [ ] if not dllnames_only : try : import_data = self . parse_imports ( import_desc . OriginalFirstThunk , import_desc . FirstThunk , import_desc . ForwarderChain , max_length = max_len ) except PEFormatError as e : self . __warnings . append ( 'Error parsing the import directory. ' 'Invalid Import data at RVA: 0x{0:x} ({1})' . format ( rva , e . value ) ) if error_count > 5 : self . __warnings . append ( 'Too many errors parsing the import directory. ' 'Invalid import data at RVA: 0x{0:x}' . format ( rva ) ) break if not import_data : error_count += 1 continue dll = self . get_string_at_rva ( import_desc . Name , MAX_DLL_LENGTH ) if not is_valid_dos_filename ( dll ) : dll = b ( '*invalid*' ) if dll : for symbol in import_data : if symbol . name is None : funcname = ordlookup . ordLookup ( dll . lower ( ) , symbol . ordinal ) if funcname : symbol . name = funcname import_descs . append ( ImportDescData ( struct = import_desc , imports = import_data , dll = dll ) ) if not dllnames_only : suspicious_imports = set ( [ u'LoadLibrary' , u'GetProcAddress' ] ) suspicious_imports_count = 0 total_symbols = 0 for imp_dll in import_descs : for symbol in imp_dll . imports : for suspicious_symbol in suspicious_imports : if not symbol or not symbol . name : continue name = symbol . name if type ( symbol . name ) == bytes : name = symbol . name . decode ( 'utf-8' ) if name . startswith ( suspicious_symbol ) : suspicious_imports_count += 1 break total_symbols += 1 if suspicious_imports_count == len ( suspicious_imports ) and total_symbols < 20 : self . __warnings . append ( 'Imported symbols contain entries typical of packed executables.' ) return import_descs
Walk and parse the import directory.
Walk and parse the import directory .
"""Walk and parse the import directory.""" # If the RVA is invalid all would blow up. Some EXEs seem to be # specially nasty and have an invalid RVA. # If the structure is all zeros, we reached the end of the list # If the array of thunks is somewhere earlier than the import # descriptor we can set a maximum length for the array. Otherwise # just set a maximum length of the size of the file # TODO: do not continue here
self
rva
size
dllnames_only