mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-10-01 14:04:54 +02:00
Flesh out symbol system, reworking several parts. Still requires on-demand resolving of symbols.
This commit is contained in:
+46
-14
@@ -6,18 +6,10 @@ Created on 17 Feb 2013
|
||||
|
||||
import struct
|
||||
import collections
|
||||
import volatility.framework.interfaces as interfaces
|
||||
import volatility.framework.templates as templates
|
||||
|
||||
class ObjectInterface(object):
|
||||
""" A base object required to be the ancestor of every object used in volatility """
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size, **kwargs):
|
||||
self._context = context
|
||||
self._offset = offset
|
||||
self._layer_name = layer_name
|
||||
self._symbol_name = symbol_name
|
||||
self._size = size
|
||||
|
||||
class PrimitiveObject(ObjectInterface):
|
||||
class PrimitiveObject(interfaces.ObjectInterface):
|
||||
"""PrimitiveObject is an interface for any objects that should simulate a Python primitive"""
|
||||
|
||||
@classmethod
|
||||
@@ -32,7 +24,7 @@ class Integer(PrimitiveObject, int):
|
||||
"""Primitive Object that handles standard numeric types"""
|
||||
|
||||
def __new__(cls, context, layer_name, offset, symbol_name, struct_format, **kwargs):
|
||||
struct_format, struct_size = context.get_primitive_struct_type("int", symbol_name)
|
||||
struct_format = context.get_primitive_struct_type("int", symbol_name)
|
||||
struct_size = struct.calcsize(struct_format)
|
||||
return cls._struct_value(struct_format, context, layer_name, offset, symbol_name, size = struct_size)
|
||||
|
||||
@@ -40,7 +32,7 @@ class Float(PrimitiveObject, float):
|
||||
"""Primitive Object that handles double or floating point numbers"""
|
||||
|
||||
def __new__(cls, context, layer_name, offset, symbol_name, size, **kwargs):
|
||||
struct_format, struct_size = context.get_primitive_struct_type("float", symbol_name)
|
||||
struct_format = context.get_primitive_struct_type("float", symbol_name)
|
||||
struct_size = struct.calcsize(struct_format)
|
||||
return cls._struct_value(struct_format, context, layer_name, offset, symbol_name, size = struct_size)
|
||||
|
||||
@@ -60,7 +52,41 @@ class String(PrimitiveObject, str):
|
||||
def __new__(cls, context, layer_name, offset, symbol_name, size = None, length = 1):
|
||||
return cls._struct_value(str(length) + "s", context, layer_name, offset, symbol_name, size)
|
||||
|
||||
class Struct(ObjectInterface):
|
||||
class Pointer(Integer):
|
||||
"""Pointer which points to another object"""
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, target = None):
|
||||
if not isinstance(target, interfaces.ObjectInterface):
|
||||
raise TypeError("Pointer targets must be an ObjectInterface")
|
||||
super(Pointer, self).__init__(context, layer_name, offset, symbol_name, size)
|
||||
self._target = target
|
||||
|
||||
def derefenence(self):
|
||||
"""Dereferences the pointer"""
|
||||
# Cache the target
|
||||
if isinstance(self._target, templates.ObjectTemplate):
|
||||
self._target = self.target(context = self._context, layer_name = self._layer_name, offset = self, self = self._target.size, parent = self)
|
||||
return self._target
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Convenience function to access unknown attributes by getting them from the target object"""
|
||||
return getattr(self.dereference(), attr)
|
||||
|
||||
class BitField(Integer):
|
||||
""""""
|
||||
def __new__(self, context, layer_name, offset, symbol_name, size = None, start_bit = 0, end_bit = 0):
|
||||
# TODO: Determine endianness of the bitfield
|
||||
struct_size = (end_bit + 7) // 8
|
||||
if struct_size == 1:
|
||||
struct_format = "c"
|
||||
elif struct_size <= 2:
|
||||
struct_format = "H"
|
||||
elif struct_size <= 4:
|
||||
struct_format = "I"
|
||||
else:
|
||||
struct_format = "Q"
|
||||
return super(BitField, self).__new__(context, layer_name, offset, symbol_name, size = None, struct_format = struct_format)
|
||||
|
||||
class Struct(interfaces.ObjectInterface):
|
||||
"""Object which can contain members that are other objects"""
|
||||
|
||||
def __init__(self, context, layer_name, offset, symbol_name, size = None, members = None):
|
||||
@@ -79,6 +105,12 @@ class Struct(ObjectInterface):
|
||||
self._members = members
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Method for accessing members of the structure"""
|
||||
if attr in self._members:
|
||||
return self._members[attr]
|
||||
member = self._members[attr]
|
||||
# Cache the constructed object
|
||||
if isinstance(member, templates.ObjectTemplate):
|
||||
member = member(context = self.context, layer_name = self.layer_name, offset = self.offset + member.relative_offset, parent = self)
|
||||
self._members[attr] = member
|
||||
return member
|
||||
raise AttributeError("'" + self._symbol_name + "' Struct has no attribute '" + attr + "'")
|
||||
|
||||
Reference in New Issue
Block a user