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

        import_descs = []
        error_count = 0
        image_import_descriptor_size = Structure(
            self.__IMAGE_IMPORT_DESCRIPTOR_format__
        ).sizeof()
        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, image_import_descriptor_size)
            except PEFormatError:
                self.__warnings.append(
                    f"Error parsing the import directory at RVA: 0x{rva:x}"
                )
                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. "
                        f"Invalid Import data at RVA: 0x{rva:x} ({e.value})"
                    )

                if error_count > 5:
                    self.__warnings.append(
                        "Too many errors parsing the import directory. "
                        f"Invalid import data at RVA: 0x{rva:x}"
                    )
                    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 = {"LoadLibrary", "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.
pefile.py