""" Created on 7 May 2013 @author: mike """ import math import struct from volatility.framework import interfaces, exceptions class Intel(interfaces.layers.TranslationLayerInterface): """Translation Layer for the Intel IA32 memory mapping""" def __init__(self, context, name, memory_layer, page_map_offset): interfaces.layers.TranslationLayerInterface.__init__(self, context, name) self._base_layer = memory_layer self._page_map_offset = page_map_offset # All Intel address spaces work on 4096 byte pages self._page_size_in_bits = 12 # These can vary depending on the type of space self._entry_format = "> (position + 1) # Grab the base address of the table we'll be getting the next entry from base_address = self._mask(entry, self._maxphyaddr - 1, size + self._index_shift) # Create the offset for the next entry table_offset = base_address | (index << self._index_shift) # Read out the new entry from memory entry, = struct.unpack(self._entry_format, self._context.memory.read(self._base_layer, table_offset, struct.calcsize(self._entry_format))) # Now we're do if not self._page_is_valid(entry): raise exceptions.InvalidAddressException("Page Fault at entry " + hex(entry) + " in page entry") page = self._mask(entry, self._maxphyaddr - 1, position + 1) | self._mask(offset, position, 0) return page, 1 << (position + 1) def is_valid(self, offset): """Returns whether the address offset can be translated to a valid address""" try: self._translate(offset) except exceptions.InvalidAddressException: return False return True def translate(self, offset): """Translates a specific offset based on the paging tables""" result, _ = self._translate(offset) return result def mapping(self, offset, length): """Returns a sorted list of (offset, mapped_offset, length, layer) mappings This allows translation layers to provide maps of contiguous regions in one layer """ result = [] while length > 0: chunk_offset, page_size = self._translate(offset) chunk_size = min(page_size - (chunk_offset % page_size), length) result.append((offset, chunk_offset, chunk_size, self._base_layer)) length -= chunk_size offset += chunk_size return result @property def dependencies(self): """Returns a list of the lower layers that this layer is dependent upon""" # TODO: Add in the whole buffalo return [self._base_layer] class IntelPAE(Intel): """Class for handling Physical Address Extensions for Intel architectures""" def __init__(self, context, name, memory_layer, page_map_offset): Intel.__init__(self, context, name, memory_layer, page_map_offset) # These can vary depending on the type of space self._entry_format = "