Skip to content

Commit b81105f

Browse files
authored
Merge pull request #1587 from gcmoreira/intel_translation_performance_improvement
intel: address translation: performance improvements caching by page address
2 parents 702257f + c82ef0c commit b81105f

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

volatility3/framework/layers/intel.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,18 +186,45 @@ def _translate_entry(self, offset: int) -> Tuple[int, int]:
186186
187187
Returns the translated entry value
188188
"""
189+
offset &= self.address_mask
190+
191+
if not (self.minimum_address <= offset <= self.maximum_address):
192+
raise exceptions.InvalidAddressException(
193+
offset, f"Address {offset:#x} outside virtual address range"
194+
)
195+
196+
page_address = offset & self.page_mask
197+
return self._translate_page(page_address)
198+
199+
@functools.lru_cache(maxsize=1024)
200+
def _translate_page(self, page_address: int) -> int:
201+
"""Translates a page address based on paging tables.
202+
203+
Args:
204+
page_address: The page base address
205+
206+
Returns:
207+
the translated entry value
208+
"""
209+
if page_address & ~self.page_mask != 0:
210+
raise exceptions.InvalidAddressException(
211+
page_address,
212+
f"Invalid page address {page_address:#x}. The address must be aligned to the page size",
213+
)
189214
# Setup the entry and how far we are through the offset
190215
# Position maintains the number of bits left to process
191216
# We or with 0x1 to ensure our page_map_offset is always valid
192217
position = self._initial_position
193218
entry = self._initial_entry
194219

195220
if not (
196-
self.minimum_address <= (offset & self.address_mask) <= self.maximum_address
221+
self.minimum_address
222+
<= (page_address & self.address_mask)
223+
<= self.maximum_address
197224
):
198225
raise exceptions.PagedInvalidAddressException(
199226
self.name,
200-
offset,
227+
page_address,
201228
position + 1,
202229
entry,
203230
"Entry outside virtual address range: " + hex(entry),
@@ -209,7 +236,7 @@ def _translate_entry(self, offset: int) -> Tuple[int, int]:
209236
if not self._page_is_valid(entry):
210237
raise exceptions.PagedInvalidAddressException(
211238
self.name,
212-
offset,
239+
page_address,
213240
position + 1,
214241
entry,
215242
"Page Fault at entry " + hex(entry) + " in table " + name,
@@ -225,7 +252,7 @@ def _translate_entry(self, offset: int) -> Tuple[int, int]:
225252
# Figure out how much of the offset we should be using
226253
start = position
227254
position -= size
228-
index = self._mask(offset, start, position + 1) >> (position + 1)
255+
index = self._mask(page_address, start, position + 1) >> (position + 1)
229256

230257
# Grab the base address of the table we'll be getting the next entry from
231258
base_address = self._mask(
@@ -236,17 +263,15 @@ def _translate_entry(self, offset: int) -> Tuple[int, int]:
236263
if table is None:
237264
raise exceptions.PagedInvalidAddressException(
238265
self.name,
239-
offset,
266+
page_address,
240267
position + 1,
241268
entry,
242269
"Page Fault at entry " + hex(entry) + " in table " + name,
243270
)
244271

245272
# Read the data for the next entry
246-
entry_data = table[
247-
(index << self._index_shift) : (index << self._index_shift)
248-
+ self._entry_size
249-
]
273+
entry_data_start = index << self._index_shift
274+
entry_data = table[entry_data_start : entry_data_start + self._entry_size]
250275

251276
if INTEL_TRANSLATION_DEBUGGING:
252277
vollog.log(
@@ -259,7 +284,6 @@ def _translate_entry(self, offset: int) -> Tuple[int, int]:
259284

260285
return entry, position
261286

262-
@functools.lru_cache(maxsize=1025)
263287
def _get_valid_table(self, base_address: int) -> Optional[bytes]:
264288
"""Extracts the table, validates it and returns it if it's valid."""
265289
table = self._context.layers.read(

0 commit comments

Comments
 (0)