diff --git a/volatility3/framework/layers/intel.py b/volatility3/framework/layers/intel.py index f750f3f2f..4108d7231 100644 --- a/volatility3/framework/layers/intel.py +++ b/volatility3/framework/layers/intel.py @@ -269,9 +269,12 @@ class Intel(linear.LinearlyMappedLayer): @functools.lru_cache(maxsize=1025) def _get_valid_table(self, base_address: int) -> Optional[bytes]: """Extracts the table, validates it and returns it if it's valid.""" - table = self._context.layers.read( - self._base_layer, base_address, self.page_size - ) + try: + table = self._context.layers.read( + self._base_layer, base_address, self.page_size + ) + except exceptions.InvalidAddressException: + return None # If the table is entirely duplicates, then mark the whole table as bad if table == table[: self._entry_size] * self._entry_number: @@ -375,12 +378,19 @@ class Intel(linear.LinearlyMappedLayer): while length > 0: try: chunk_offset, page_size, layer_name = self._translate(offset) - chunk_size = min(page_size - (chunk_offset % page_size), length) + # Page align the chunk size value + chunk_size = min(page_size - (offset % page_size), length) if not self._context.layers[layer_name].is_valid( chunk_offset, chunk_size ): - raise exceptions.InvalidAddressException( - layer_name=layer_name, invalid_address=chunk_offset + # Virtual -> physical is contiguous in the chunk_size range. + # If we fail, we can jump directly to the end as we know all bytes in between + # aren't mapped (virtually and) physically anyway. + raise exceptions.PagedInvalidAddressException( + layer_name=layer_name, + invalid_address=chunk_offset, + entry=0, + invalid_bits=int(math.log2(chunk_size)), ) except ( exceptions.PagedInvalidAddressException,