diff --git a/volatility/framework/layers/lime.py b/volatility/framework/layers/lime.py new file mode 100644 index 0000000000..c125390414 --- /dev/null +++ b/volatility/framework/layers/lime.py @@ -0,0 +1,132 @@ +""" +Created on 6 Apr 2016 + +@author: npetroni@volexity.com +""" + +import struct + +from volatility.framework import interfaces, exceptions +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("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): + """Returns a sorted list of (offset, mapped_offset, length, layer) mappings""" + if length == 0: + logical_start, base_start, size = self._find_segment(offset) + mapped_offset = offset - logical_start + base_start + return [(offset, mapped_offset, 0, self._base_layer)] + result = [] + 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) + 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""" + return [self._base_layer] + + @classmethod + def get_schema(cls): + return [requirements.TranslationLayerRequirement(name = 'base_layer', + constraints = {"type": "physical"}, + optional = False)]