""" Created on 6 Apr 2016 @author: npetroni@volexity.com """ import struct from volatility.framework import exceptions, interfaces from volatility.framework.configuration import requirements class LimeFormatException(exceptions.LayerException): """Thrown when an error occurs with the underlying Lime file format""" class LimeLayer(interfaces.layers.TranslationLayerInterface): """A Lime format TranslationLayer. Lime is generally used to store physical memory images where there are large holes in the physical address space""" provides = {"type": "physical"} priority = 21 MAGIC = 0x4c694d45 VERSION = 1 # Magic[4], Version[4], Start[8], End[8], Reserved[8] # XXX move this to a custom SymbolSpace? _header_struct = struct.Struct('= logical_start and offset < (logical_start + size): return (logical_start, base_start, size) raise exceptions.InvalidAddressException(self.name, offset, "Lime fault at address " + hex(offset)) def is_valid(self, offset, length = 1): """Returns whether the address offset can be translated to a valid address""" try: return all([self._context.memory[self._base_layer].is_valid(mapped_offset) for _, mapped_offset, _, _ in self.mapping(offset, length)]) except exceptions.InvalidAddressException: return False def mapping(self, offset, length, ignore_errors = False): """Returns a sorted iterable of (offset, mapped_offset, length, layer) mappings""" result = [] if ignore_errors: for (seg_offset, mapped_seg_offset, seg_length) in self._segments: if (offset + length < seg_offset) or (offset > seg_offset + seg_length): continue if seg_offset <= offset < seg_offset + seg_length: diff = offset - seg_offset seg_length -= diff mapped_seg_offset += diff seg_offset += diff if offset + length < seg_offset + seg_length: seg_length = offset + length - seg_offset yield (seg_offset, mapped_seg_offset, seg_length, self._base_layer) raise StopIteration if length == 0: logical_start, base_start, size = self._find_segment(offset) mapped_offset = offset - logical_start + base_start yield (offset, mapped_offset, 0, self._base_layer) raise StopIteration while length > 0: logical_start, base_start, size = self._find_segment(offset) chunk_offset = offset - logical_start + base_start chunk_size = min(size - (offset - logical_start), length) yield (offset, chunk_offset, chunk_size, self._base_layer) length -= chunk_size offset += chunk_size @property def dependencies(self): """Returns a list of the lower layers that this layer is dependent upon""" return [self._base_layer] @classmethod def get_requirements(cls): return [requirements.TranslationLayerRequirement(name = 'base_layer', optional = False)]