diff options
| author | Florent Monjalet <florent.monjalet@gmail.com> | 2015-11-30 15:48:09 +0100 |
|---|---|---|
| committer | Florent Monjalet <florent.monjalet@gmail.com> | 2016-01-18 14:02:31 +0100 |
| commit | b3b0b03b4a7b3e69c62bf6742c3ea582e0e78061 (patch) | |
| tree | e68886e345a2de1ce9f9cfbe9f6f0ab8055a100e | |
| parent | 31650c36e3c079445fe6c26fc0a40c1bd19da57d (diff) | |
| download | miasm-b3b0b03b4a7b3e69c62bf6742c3ea582e0e78061.tar.gz miasm-b3b0b03b4a7b3e69c62bf6742c3ea582e0e78061.zip | |
MemStruct: Pinned* renamed back to Mem*
Diffstat (limited to '')
| -rw-r--r-- | example/jitter/memstruct.py | 22 | ||||
| -rw-r--r-- | miasm2/analysis/mem.py | 250 | ||||
| -rw-r--r-- | test/analysis/mem.py | 60 |
3 files changed, 166 insertions, 166 deletions
diff --git a/example/jitter/memstruct.py b/example/jitter/memstruct.py index 77d65d17..4ddbea86 100644 --- a/example/jitter/memstruct.py +++ b/example/jitter/memstruct.py @@ -6,14 +6,14 @@ as well. """ from miasm2.analysis.machine import Machine -from miasm2.analysis.mem import PinnedStruct, Self, Void, Str, Array, Ptr, \ +from miasm2.analysis.mem import MemStruct, Self, Void, Str, Array, Ptr, \ Num, Array, set_allocator from miasm2.os_dep.common import heap # Instanciate a heap my_heap = heap() # And set it as the default memory allocator, to avoid manual allocation and -# explicit address passing to the PinnedType subclasses (like PinnedStruct) +# explicit address passing to the MemType subclasses (like MemStruct) # constructor set_allocator(my_heap.vm_alloc) @@ -22,7 +22,7 @@ set_allocator(my_heap.vm_alloc) # All the structures and methods will use the python objects but all the data # is in fact stored in the VmMngr -class ListNode(PinnedStruct): +class ListNode(MemStruct): fields = [ # The "<I" is the struct-like format of the pointer in memory, in this # case a Little Endian 32 bits unsigned int. @@ -48,10 +48,10 @@ class ListNode(PinnedStruct): return self.data.deref -class LinkedList(PinnedStruct): +class LinkedList(MemStruct): fields = [ # For convenience, either a Type instance (like Self() or Num("I") or a - # PinnedStruct subclass can be passed to the Ptr constructor. + # MemStruct subclass can be passed to the Ptr constructor. ("head", Ptr("<I", ListNode)), ("tail", Ptr("<I", ListNode)), # Num can take any one-field struct-like format, including floats and @@ -72,7 +72,7 @@ class LinkedList(PinnedStruct): return self.tail.deref def push(self, data): - """Push a data (PinnedType instance) to the linked list.""" + """Push a data (MemType instance) to the linked list.""" # Allocate a new node node = ListNode(self._vm) @@ -125,19 +125,19 @@ class LinkedList(PinnedStruct): # Some data types to put in the LinkedList and play with: -class DataArray(PinnedStruct): +class DataArray(MemStruct): fields = [ ("val1", Num("B")), ("val2", Num("B")), # Ptr can also be instanciated with a Type instance as an argument, the - # corresponding Pinnedtype will be returned when dereferencing + # corresponding Memtype will be returned when dereferencing # Here, data_array.array.deref will allow to access an Array ("arrayptr", Ptr("<I", Array(Num("B"), 16))), # Array of 10 uint8 ("array", Array(Num("B"), 16)), ] -class DataStr(PinnedStruct): +class DataStr(MemStruct): fields = [ ("valshort", Num("<H")), # Pointer to an utf16 null terminated string @@ -179,7 +179,7 @@ print repr(link), '\n' print "Its uninitialized data elements:" for data in link: - # __iter__ returns PinnedVoids here, just cast them to the real data type + # __iter__ returns MemVoids here, just cast them to the real data type real_data = data.cast(DataArray) print repr(real_data) print @@ -212,7 +212,7 @@ memstr = datastr.data.deref # Note that memstr is Str("utf16") memstr.val = 'Miams' -print "Cast data.array to PinnedStr and set the string value:" +print "Cast data.array to MemStr and set the string value:" print repr(memstr) print diff --git a/miasm2/analysis/mem.py b/miasm2/analysis/mem.py index b2d91ed2..3c8d5b8b 100644 --- a/miasm2/analysis/mem.py +++ b/miasm2/analysis/mem.py @@ -2,8 +2,8 @@ object (a miasm sandbox virtual memory). It provides two families of classes, Type-s (Num, Ptr, Str...) and their -associated PinnedType-s. A Type subclass instance represents a fully defined C -type. A PinnedType subclass instance represents a C LValue (or variable): it is +associated MemType-s. A Type subclass instance represents a fully defined C +type. A MemType subclass instance represents a C LValue (or variable): it is a type attached to the memory. Available types are: - Num: for number (float or int) handling @@ -29,15 +29,15 @@ And some less common types: - RawStruct: abstraction over a simple struct pack/unpack (no mapping to a standard C type) -For each type, the `.pinned` property returns a PinnedType subclass that +For each type, the `.pinned` property returns a MemType subclass that allows to access the field in memory. The easiest way to use the API to declare and manipulate new structures is to -subclass PinnedStruct and define a list of (<field_name>, <field_definition>): +subclass MemStruct and define a list of (<field_name>, <field_definition>): # FIXME: "I" => "u32" - class MyStruct(PinnedStruct): + class MyStruct(MemStruct): fields = [ # Scalar field: just struct.pack field with one value ("num", Num("I")), @@ -60,7 +60,7 @@ And access the fields: mstruct.other = addr2 mstruct.other.deref = OtherStruct(jitter.vm, addr) -PinnedUnion and PinnedBitField can also be subclassed, the `fields` field being +MemUnion and MemBitField can also be subclassed, the `fields` field being in the format expected by, respectively, Union and BitField. The `addr` argument can be omited if an allocator is set, in which case the @@ -70,7 +70,7 @@ structure will be automatically allocated in memory: # the allocator is a func(VmMngr) -> integer_address set_allocator(my_heap) -Note that some structures (e.g. PinnedStr or PinnedArray) do not have a static +Note that some structures (e.g. MemStr or MemArray) do not have a static size and cannot be allocated automatically. """ @@ -84,15 +84,15 @@ log.addHandler(console_handler) log.setLevel(logging.WARN) # ALLOCATOR is a function(vm, size) -> allocated_address -# TODO: as a PinnedType class attribute +# TODO: as a MemType class attribute ALLOCATOR = None -# Cache for dynamically generated PinnedTypes +# Cache for dynamically generated MemTypes DYN_MEM_STRUCT_CACHE = {} def set_allocator(alloc_func): """Set an allocator for this module; allows to instanciate statically sized - PinnedTypes (i.e. sizeof() is implemented) without specifying the address + MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm. @alloc_func: func(VmMngr) -> integer_address @@ -169,11 +169,11 @@ class Type(object): """Base class to provide methods to describe a type, as well as how to set and get fields from virtual mem. - Each Type subclass is linked to a PinnedType subclass (e.g. Struct to - PinnedStruct, Ptr to PinnedPtr, etc.). + Each Type subclass is linked to a MemType subclass (e.g. Struct to + MemStruct, Ptr to MemPtr, etc.). - When nothing is specified, PinnedValue is used to access the type in memory. - PinnedValue instances have one `.val` field, setting and getting it call + When nothing is specified, MemValue is used to access the type in memory. + MemValue instances have one `.val` field, setting and getting it call the set and get of the Type. Subclasses can either override _pack and _unpack, or get and set if data @@ -214,7 +214,7 @@ class Type(object): """Returns a class with a (vm, addr) constructor that allows to interact with this type in memory. - @return: a PinnedType subclass. + @return: a MemType subclass. """ if self in DYN_MEM_STRUCT_CACHE: return DYN_MEM_STRUCT_CACHE[self] @@ -223,26 +223,26 @@ class Type(object): return pinned_type def _build_pinned_type(self): - """Builds the PinnedType subclass allowing to interract with this type. + """Builds the MemType subclass allowing to interract with this type. Called by self.pinned when it is not in cache. """ pinned_base_class = self._get_pinned_base_class() - pinned_type = type("Pinned%r" % self, (pinned_base_class,), + pinned_type = type("Mem%r" % self, (pinned_base_class,), {'_type': self}) return pinned_type def _get_pinned_base_class(self): - """Return the PinnedType subclass that maps this type in memory""" - return PinnedValue + """Return the MemType subclass that maps this type in memory""" + return MemValue def _get_self_type(self): """Used for the Self trick.""" return self._self_type def _set_self_type(self, self_type): - """If this field refers to PinnedSelf/Self, replace it with @self_type - (a PinnedType subclass) when using it. Generally not used outside this + """If this field refers to MemSelf/Self, replace it with @self_type + (a MemType subclass) when using it. Generally not used outside this module. """ self._self_type = self_type @@ -306,45 +306,45 @@ class Num(RawStruct): class Ptr(Num): """Special case of number of which value indicates the address of a - PinnedType. + MemType. - Mapped to PinnedPtr (see its doc for more info): + Mapped to MemPtr (see its doc for more info): - assert isinstance(mystruct.ptr, PinnedPtr) + assert isinstance(mystruct.ptr, MemPtr) mystruct.ptr = 0x4000 # Assign the Ptr numeric value mystruct.ptr.val = 0x4000 # Also assigns the Ptr numeric value assert isinstance(mystruct.ptr.val, int) # Get the Ptr numeric value - mystruct.ptr.deref # Get the pointed PinnedType - mystruct.ptr.deref = other # Set the pointed PinnedType + mystruct.ptr.deref # Get the pointed MemType + mystruct.ptr.deref = other # Set the pointed MemType """ def __init__(self, fmt, dst_type, *type_args, **type_kwargs): """ @fmt: (str) Num compatible format that will be the Ptr representation in memory - @dst_type: (PinnedType or Type) the PinnedType this Ptr points to. - If a Type is given, it is transformed into a PinnedType with + @dst_type: (MemType or Type) the MemType this Ptr points to. + If a Type is given, it is transformed into a MemType with TheType.pinned. *type_args, **type_kwargs: arguments to pass to the the pointed - PinnedType when instanciating it (e.g. for PinnedStr encoding or - PinnedArray field_type). + MemType when instanciating it (e.g. for MemStr encoding or + MemArray field_type). """ if (not isinstance(dst_type, Type) and not (isinstance(dst_type, type) and - issubclass(dst_type, PinnedType)) and - not dst_type == PinnedSelf): - raise ValueError("dst_type of Ptr must be a PinnedType type, a " - "Type instance, the PinnedSelf marker or a class " + issubclass(dst_type, MemType)) and + not dst_type == MemSelf): + raise ValueError("dst_type of Ptr must be a MemType type, a " + "Type instance, the MemSelf marker or a class " "name.") super(Ptr, self).__init__(fmt) if isinstance(dst_type, Type): - # Patch the field to propagate the PinnedSelf replacement + # Patch the field to propagate the MemSelf replacement dst_type._get_self_type = lambda: self._get_self_type() # dst_type cannot be patched here, since _get_self_type of the outer # class has not yet been set. Patching dst_type involves calling # dst_type.pinned, which will only return a type that does not point - # on PinnedSelf but on the right class only when _get_self_type of the - # outer class has been replaced by _MetaPinnedStruct. + # on MemSelf but on the right class only when _get_self_type of the + # outer class has been replaced by _MetaMemStruct. # In short, dst_type = dst_type.pinned is not valid here, it is done # lazily in _fix_dst_type self._dst_type = dst_type @@ -352,23 +352,23 @@ class Ptr(Num): self._type_kwargs = type_kwargs def _fix_dst_type(self): - if self._dst_type == PinnedSelf: + if self._dst_type == MemSelf: if self._get_self_type() is not None: self._dst_type = self._get_self_type() else: - raise ValueError("Unsupported usecase for PinnedSelf, sorry") + raise ValueError("Unsupported usecase for MemSelf, sorry") if isinstance(self._dst_type, Type): self._dst_type = self._dst_type.pinned @property def dst_type(self): - """Return the type (PinnedType subtype) this Ptr points to.""" + """Return the type (MemType subtype) this Ptr points to.""" self._fix_dst_type() return self._dst_type def set(self, vm, addr, val): - """A Ptr field can be set with a PinnedPtr or an int""" - if isinstance(val, PinnedType) and isinstance(val.get_type(), Ptr): + """A Ptr field can be set with a MemPtr or an int""" + if isinstance(val, MemType) and isinstance(val.get_type(), Ptr): self.set_val(vm, addr, val.val) else: super(Ptr, self).set(vm, addr, val) @@ -393,7 +393,7 @@ class Ptr(Num): *self._type_args, **self._type_kwargs) def deref_set(self, vm, addr, val): - """Serializes the @val PinnedType subclass instance in @vm (VmMngr) at + """Serializes the @val MemType subclass instance in @vm (VmMngr) at @addr. Equivalent to a pointer dereference assignment in C. """ # Sanity check @@ -406,7 +406,7 @@ class Ptr(Num): vm.set_mem(dst_addr, str(val)) def _get_pinned_base_class(self): - return PinnedPtr + return MemPtr def __repr__(self): return "%s(%r)" % (self.__class__.__name__, self.dst_type.get_type()) @@ -427,10 +427,10 @@ class Struct(Type): (<field_name (str)>, <Type_subclass_instance>) list describing the fields of the struct. - Mapped to PinnedStruct. + Mapped to MemStruct. NOTE: The `.pinned` property of Struct creates classes on the fly. If an - equivalent structure is created by subclassing PinnedStruct, an exception + equivalent structure is created by subclassing MemStruct, an exception is raised to prevent creating multiple classes designating the same type. Example: @@ -440,7 +440,7 @@ class Struct(Type): # This raises an exception, because it describes the same structure as # Toto1 - class Toto(PinnedStruct): + class Toto(MemStruct): fields = [("f1", Num("I")), ("f2", Num("I"))] """ @@ -507,7 +507,7 @@ class Struct(Type): return self._fields_desc[name]['field'] def _get_pinned_base_class(self): - return PinnedStruct + return MemStruct def __repr__(self): return "struct %s" % self.name @@ -526,15 +526,15 @@ class Struct(Type): class Union(Struct): """Represents a C union. - Allows to put multiple fields at the same offset in a PinnedStruct, + Allows to put multiple fields at the same offset in a MemStruct, similar to unions in C. The Union will have the size of the largest of its fields. - Mapped to PinnedUnion. + Mapped to MemUnion. Example: - class Example(PinnedStruct): + class Example(MemStruct): fields = [("uni", Union([ ("f1", Num("<B")), ("f2", Num("<H")) @@ -557,7 +557,7 @@ class Union(Struct): return 0 def _get_pinned_base_class(self): - return PinnedUnion + return MemUnion def __repr__(self): fields_repr = ', '.join("%s: %r" % (name, field) @@ -572,20 +572,20 @@ class Array(Type): if no @array_len is given to the constructor (similar to char* used as an array). - Mapped to PinnedArray or PinnedSizedArray, depending on if the Array is + Mapped to MemArray or MemSizedArray, depending on if the Array is sized or not. - Getting an array field actually returns a PinnedSizedArray. Setting it is - possible with either a list or a PinnedSizedArray instance. Examples of + Getting an array field actually returns a MemSizedArray. Setting it is + possible with either a list or a MemSizedArray instance. Examples of syntax: - class Example(PinnedStruct): + class Example(MemStruct): fields = [("array", Array(Num("B"), 4))] mystruct = Example(vm, addr) mystruct.array[3] = 27 mystruct.array = [1, 4, 8, 9] - mystruct.array = PinnedSizedArray(vm, addr2, Num("B"), 4) + mystruct.array = MemSizedArray(vm, addr2, Num("B"), 4) """ def __init__(self, field_type, array_len=None): @@ -597,17 +597,17 @@ class Array(Type): self.field_type._set_self_type(self_type) def set(self, vm, addr, val): - # PinnedSizedArray assignment - if isinstance(val, PinnedSizedArray): + # MemSizedArray assignment + if isinstance(val, MemSizedArray): if val.array_len != self.array_len or len(val) != self.size(): - raise ValueError("Size mismatch in PinnedSizedArray assignment") + raise ValueError("Size mismatch in MemSizedArray assignment") raw = str(val) vm.set_mem(addr, raw) # list assignment elif isinstance(val, list): if len(val) != self.array_len: - raise ValueError("Size mismatch in PinnedSizedArray assignment ") + raise ValueError("Size mismatch in MemSizedArray assignment ") offset = 0 for elt in val: self.field_type.set(vm, addr + offset, elt) @@ -615,7 +615,7 @@ class Array(Type): else: raise RuntimeError( - "Assignment only implemented for list and PinnedSizedArray") + "Assignment only implemented for list and MemSizedArray") def get(self, vm, addr): return self.pinned(vm, addr) @@ -686,9 +686,9 @@ class Array(Type): def _get_pinned_base_class(self): if self.is_sized(): - return PinnedSizedArray + return MemSizedArray else: - return PinnedArray + return MemArray def __repr__(self): return "%r[%s]" % (self.field_type, self.array_len or "unsized") @@ -774,11 +774,11 @@ class BitField(Union): endian int, little endian short...). Can be seen (and implemented) as a Union of Bits fields. - Mapped to PinnedBitField. + Mapped to MemBitField. Creates fields that allow to access the bitfield fields easily. Example: - class Example(PinnedStruct): + class Example(MemStruct): fields = [("bf", BitField(Num("B"), [ ("f1", 2), ("f2", 4), @@ -812,7 +812,7 @@ class BitField(Union): self._num.set(vm, addr, val) def _get_pinned_base_class(self): - return PinnedBitField + return MemBitField def __eq__(self, other): return self.__class__ == other.__class__ and \ @@ -835,7 +835,7 @@ class Str(Type): terminated "ansi" (latin1) or (double) null terminated "utf16". Be aware that the utf16 implementation is a bit buggy... - Mapped to PinnedStr. + Mapped to MemStr. """ def __init__(self, encoding="ansi"): @@ -874,7 +874,7 @@ class Str(Type): return self._enc def _get_pinned_base_class(self): - return PinnedStr + return MemStr def __repr__(self): return "%s(%s)" % (self.__class__.__name__, self.enc) @@ -889,11 +889,11 @@ class Str(Type): class Void(Type): """Represents the C void type. - Mapped to PinnedVoid. + Mapped to MemVoid. """ def _build_pinned_type(self): - return PinnedVoid + return MemVoid def __eq__(self, other): return self.__class__ == other.__class__ @@ -905,10 +905,10 @@ class Void(Type): class Self(Void): """Special marker to reference a type inside itself. - Mapped to PinnedSelf. + Mapped to MemSelf. Example: - class ListNode(PinnedStruct): + class ListNode(MemStruct): fields = [ ("next", Ptr("<I", Self())), ("data", Ptr("<I", Void())), @@ -916,26 +916,26 @@ class Self(Void): """ def _build_pinned_type(self): - return PinnedSelf + return MemSelf -# PinnedType classes +# MemType classes -class _MetaPinnedType(type): +class _MetaMemType(type): def __repr__(cls): return cls.__name__ -class _MetaPinnedStruct(_MetaPinnedType): - """PinnedStruct metaclass. Triggers the magic that generates the class +class _MetaMemStruct(_MetaMemType): + """MemStruct metaclass. Triggers the magic that generates the class fields from the cls.fields list. - Just calls PinnedStruct.gen_fields() if the fields class attribute has been + Just calls MemStruct.gen_fields() if the fields class attribute has been set, the actual implementation can seen be there. """ def __init__(cls, name, bases, dct): - super(_MetaPinnedStruct, cls).__init__(name, bases, dct) + super(_MetaMemStruct, cls).__init__(name, bases, dct) if cls.fields is not None: cls.fields = tuple(cls.fields) # Am I able to generate fields? (if not, let the user do it manually @@ -944,16 +944,16 @@ class _MetaPinnedStruct(_MetaPinnedType): cls.gen_fields() -class PinnedType(object): +class MemType(object): """Base class for classes that allow to map python objects to C types in virtual memory. - Globally, PinnedTypes are not meant to be used directly: specialized + Globally, MemTypes are not meant to be used directly: specialized subclasses are generated by Type(...).pinned and should be used instead. - The main exception is PinnedStruct, which you may want to subclass yourself + The main exception is MemStruct, which you may want to subclass yourself for syntactic ease. """ - __metaclass__ = _MetaPinnedType + __metaclass__ = _MetaMemType _type = None @@ -962,7 +962,7 @@ class PinnedType(object): self._vm = vm if addr is None: if ALLOCATOR is None: - raise ValueError("Cannot provide None address to PinnedType() if" + raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) self._addr = ALLOCATOR(vm, self.get_size()) @@ -971,11 +971,11 @@ class PinnedType(object): if type_ is not None: self._type = type_ if self._type is None: - raise ValueError("Subclass PinnedType and define cls._type or pass " + raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor") def get_addr(self, field=None): - """Return the address of this PinnedType or one of its fields. + """Return the address of this MemType or one of its fields. @field: (str, optional) used by subclasses to specify the name or index of the field to get the address of @@ -988,7 +988,7 @@ class PinnedType(object): @classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this - PinnedType. + MemType. """ return cls._type @@ -1003,14 +1003,14 @@ class PinnedType(object): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. - For example, PinnedStr defines get_size but not sizeof, as an instance + For example, MemStr defines get_size but not sizeof, as an instance has a fixed size (at least its value has), but all the instance do not have the same size. """ return self.sizeof() def memset(self, byte='\x00'): - """Fill the memory space of this PinnedType with @byte ('\x00' by + """Fill the memory space of this MemType with @byte ('\x00' by default). The size is retrieved with self.get_size() (dynamic size). """ # TODO: multibyte patterns @@ -1019,29 +1019,29 @@ class PinnedType(object): self._vm.set_mem(self.get_addr(), byte * self.get_size()) def cast(self, other_type): - """Cast this PinnedType to another PinnedType (same address, same vm, - but different type). Return the casted PinnedType. + """Cast this MemType to another MemType (same address, same vm, + but different type). Return the casted MemType. @other_type: either a Type instance (other_type.pinned is used) or a - PinnedType subclass + MemType subclass """ if isinstance(other_type, Type): other_type = other_type.pinned return other_type(self._vm, self.get_addr()) def cast_field(self, field, other_type, *type_args, **type_kwargs): - """ABSTRACT: Same as cast, but the address of the returned PinnedType - is the address at which @field is in the current PinnedType. + """ABSTRACT: Same as cast, but the address of the returned MemType + is the address at which @field is in the current MemType. @field: field specification, for example its name for a struct, or an index in an array. See the subclass doc. @other_type: either a Type instance (other_type.pinned is used) or a - PinnedType subclass + MemType subclass """ raise NotImplementedError("Abstract") def raw(self): - """Raw binary (str) representation of the PinnedType as it is in + """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size()) @@ -1053,7 +1053,7 @@ class PinnedType(object): return self.raw() def __repr__(self): - return "Pinned%r" % self._type + return "Mem%r" % self._type def __eq__(self, other): return self.__class__ == other.__class__ and \ @@ -1064,8 +1064,8 @@ class PinnedType(object): return not self == other -class PinnedValue(PinnedType): - """Simple PinnedType that gets and sets the Type through the `.val` +class MemValue(MemType): + """Simple MemType that gets and sets the Type through the `.val` attribute. """ @@ -1081,7 +1081,7 @@ class PinnedValue(PinnedType): return "%r: %r" % (self.__class__, self.val) -class PinnedStruct(PinnedType): +class MemStruct(MemType): """Base class to easily implement VmMngr backed C-like structures in miasm. Represents a structure in virtual memory. @@ -1092,7 +1092,7 @@ class PinnedStruct(PinnedType): fields. Example: - class MyStruct(PinnedStruct): + class MyStruct(MemStruct): fields = [ # Scalar field: just struct.pack field with one value ("num", Num("I")), @@ -1114,7 +1114,7 @@ class PinnedStruct(PinnedType): 4))[0] assert memval == mstruct.num - # Pinnedset sets the whole structure + # Memset sets the whole structure mstruct.memset() assert mstruct.num == 0 mstruct.memset('\x11') @@ -1130,11 +1130,11 @@ class PinnedStruct(PinnedType): MyStruct = Struct("MyStruct", <same fields>).pinned is equivalent to the previous MyStruct declaration. - See the various Type-s doc for more information. See PinnedStruct.gen_fields + See the various Type-s doc for more information. See MemStruct.gen_fields doc for more information on how to handle recursive types and cyclic dependencies. """ - __metaclass__ = _MetaPinnedStruct + __metaclass__ = _MetaMemStruct fields = None def get_addr(self, field_name=None): @@ -1179,18 +1179,18 @@ class PinnedStruct(PinnedType): Useful in case of a type cyclic dependency. For example, the following is not possible in python: - class A(PinnedStruct): + class A(MemStruct): fields = [("b", Ptr("I", B))] - class B(PinnedStruct): + class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: - class A(PinnedStruct): + class A(MemStruct): pass - class B(PinnedStruct): + class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) @@ -1204,13 +1204,13 @@ class PinnedStruct(PinnedType): if cls._type is None: if cls.fields is None: - raise ValueError("Cannot create a PinnedStruct subclass without" + raise ValueError("Cannot create a MemStruct subclass without" " a cls._type or a cls.fields") cls._type = cls._gen_type(cls.fields) if cls._type in DYN_MEM_STRUCT_CACHE: # FIXME: Maybe a warning would be better? - raise RuntimeError("Another PinnedType has the same type as this " + raise RuntimeError("Another MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when @@ -1242,21 +1242,21 @@ class PinnedStruct(PinnedType): return '%r:\n' % self.__class__ + indent('\n'.join(out), 2) -class PinnedUnion(PinnedStruct): - """Same as PinnedStruct but all fields have a 0 offset in the struct.""" +class MemUnion(MemStruct): + """Same as MemStruct but all fields have a 0 offset in the struct.""" @classmethod def _gen_type(cls, fields): return Union(fields) -class PinnedBitField(PinnedUnion): - """PinnedUnion of Bits(...) fields.""" +class MemBitField(MemUnion): + """MemUnion of Bits(...) fields.""" @classmethod def _gen_type(cls, fields): return BitField(fields) -class PinnedSelf(PinnedStruct): +class MemSelf(MemStruct): """Special Marker class for reference to current class in a Ptr or Array (mostly Array of Ptr). See Self doc. """ @@ -1264,7 +1264,7 @@ class PinnedSelf(PinnedStruct): return self.__class__.__name__ -class PinnedVoid(PinnedType): +class MemVoid(MemType): """Placeholder for e.g. Ptr to an undetermined type. Useful mostly when casted to another type. Allows to implement C's "void*" pattern. """ @@ -1274,8 +1274,8 @@ class PinnedVoid(PinnedType): return self.__class__.__name__ -class PinnedPtr(PinnedValue): - """Pinned version of a Ptr, provides two properties: +class MemPtr(MemValue): + """Mem version of a Ptr, provides two properties: - val, to set and get the numeric value of the Ptr - deref, to set and get the pointed type """ @@ -1299,7 +1299,7 @@ class PinnedPtr(PinnedValue): return "*%s" % hex(self.val) -class PinnedStr(PinnedValue): +class MemStr(MemValue): """Implements a string representation in memory. The string value can be got or set (with python str/unicode) through the @@ -1330,7 +1330,7 @@ class PinnedStr(PinnedValue): return "%r: %r" % (self.__class__, self.val) -class PinnedArray(PinnedType): +class MemArray(MemType): """An unsized array of type @field_type (a Type subclass instance). This class has no static or dynamic size. @@ -1345,7 +1345,7 @@ class PinnedArray(PinnedType): @property def field_type(self): """Return the Type subclass instance that represents the type of - this PinnedArray items. + this MemArray items. """ return self.get_type().field_type @@ -1360,15 +1360,15 @@ class PinnedArray(PinnedType): def raw(self): raise ValueError("%s is unsized, which prevents from getting its full " - "raw representation. Use PinnedSizedArray instead." % + "raw representation. Use MemSizedArray instead." % self.__class__) def __repr__(self): return "[%r, ...] [%r]" % (self[0], self.field_type) -class PinnedSizedArray(PinnedArray): - """A fixed size PinnedArray. +class MemSizedArray(MemArray): + """A fixed size MemArray. This type is dynamically sized. Generate a fixed @field_type and @array_len array which has a static size by using Array(type, size).pinned. diff --git a/test/analysis/mem.py b/test/analysis/mem.py index b6664cd2..6c7fc9e3 100644 --- a/test/analysis/mem.py +++ b/test/analysis/mem.py @@ -5,20 +5,20 @@ import struct from miasm2.analysis.machine import Machine -from miasm2.analysis.mem import PinnedStruct, Num, Ptr, Str, \ +from miasm2.analysis.mem import MemStruct, Num, Ptr, Str, \ Array, RawStruct, Union, \ BitField, Self, Void, Bits, \ - set_allocator, PinnedUnion, Struct + set_allocator, MemUnion, Struct from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.os_dep.common import heap # Two structures with some fields -class OtherStruct(PinnedStruct): +class OtherStruct(MemStruct): fields = [ ("foo", Num("H")), ] -class MyStruct(PinnedStruct): +class MyStruct(MemStruct): fields = [ # Number field: just struct.pack fields with one value ("num", Num("I")), @@ -43,7 +43,7 @@ addr_str3 = 0x1300 jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\xaa"*size) -# PinnedStruct tests +# MemStruct tests ## Creation # Use manual allocation with explicit addr for the first example mstruct = MyStruct(jitter.vm, addr) @@ -57,7 +57,7 @@ assert mstruct.num == 3 memval = struct.unpack("I", jitter.vm.get_mem(mstruct.get_addr(), 4))[0] assert memval == 3 -## Pinnedset sets the whole structure +## Memset sets the whole structure mstruct.memset() assert mstruct.num == 0 assert mstruct.flags == 0 @@ -105,7 +105,7 @@ assert other2.foo == 0xbeef assert other.get_addr() != other2.get_addr() # Not the same address assert other == other2 # But same value -## Same stuff for Ptr to PinnedField +## Same stuff for Ptr to MemField alloc_addr = my_heap.vm_alloc(jitter.vm, mstruct.get_type().get_field_type("i") .dst_type.sizeof()) @@ -148,7 +148,7 @@ memstr3 = Str("utf16").pinned(jitter.vm, addr_str3) memstr3.val = "That's all folks!" assert memstr3.get_addr() != memstr.get_addr() assert memstr3.get_size() != memstr.get_size() # Size is different -assert str(memstr3) != str(memstr) # Pinned representation is different +assert str(memstr3) != str(memstr) # Mem representation is different assert memstr3 != memstr # Encoding is different, so they are not eq assert memstr3.val == memstr.val # But the python value is the same @@ -204,7 +204,7 @@ assert str(memsarray) == '\x02\x00\x00\x00' + '\xcc' * (4 * 9) # Atypical fields (RawStruct and Array) -class MyStruct2(PinnedStruct): +class MyStruct2(MemStruct): fields = [ ("s1", RawStruct("=BI")), ("s2", Array(Num("B"), 10)), @@ -236,7 +236,7 @@ ms2.s2 = [1] * 10 for val in ms2.s2: assert val == 1 -### Field assignment (PinnedSizedArray) +### Field assignment (MemSizedArray) array2 = Array(Num("B"), 10).pinned(jitter.vm) jitter.vm.set_mem(array2.get_addr(), '\x02'*10) for val in array2: @@ -246,14 +246,14 @@ for val in ms2.s2: assert val == 2 -# Inlining a PinnedType tests -class InStruct(PinnedStruct): +# Inlining a MemType tests +class InStruct(MemStruct): fields = [ ("foo", Num("B")), ("bar", Num("B")), ] -class ContStruct(PinnedStruct): +class ContStruct(MemStruct): fields = [ ("one", Num("B")), ("instruct", InStruct.get_type()), @@ -286,7 +286,7 @@ assert jitter.vm.get_mem(cont.get_addr(), len(cont)) == '\x01\x02\x03\x04' # Union test -class UniStruct(PinnedStruct): +class UniStruct(MemStruct): fields = [ ("one", Num("B")), ("union", Union([ @@ -312,7 +312,7 @@ assert uni.union.instruct.bar == 0x22 # BitField test -class BitStruct(PinnedUnion): +class BitStruct(MemUnion): fields = [ ("flags_num", Num("H")), ("flags", BitField(Num("H"), [ @@ -346,7 +346,7 @@ assert bit.flags.f4_1 == 1 # Unhealthy ideas -class UnhealthyIdeas(PinnedStruct): +class UnhealthyIdeas(MemStruct): fields = [ ("pastruct", Ptr("I", Array(RawStruct("=Bf")))), ("apstr", Array(Ptr("I", Str()), 10)), @@ -387,10 +387,10 @@ assert ideas.pppself.deref.deref.deref == ideas # Circular dependencies -class A(PinnedStruct): +class A(MemStruct): pass -class B(PinnedStruct): +class B(MemStruct): fields = [("a", Ptr("I", A)),] # Gen A's fields after declaration @@ -405,30 +405,30 @@ assert b.a.deref == a # Cast tests -# PinnedStruct cast -PinnedInt = Num("I").pinned -PinnedShort = Num("H").pinned -dword = PinnedInt(jitter.vm) +# MemStruct cast +MemInt = Num("I").pinned +MemShort = Num("H").pinned +dword = MemInt(jitter.vm) dword.val = 0x12345678 -assert isinstance(dword.cast(PinnedShort), PinnedShort) -assert dword.cast(PinnedShort).val == 0x5678 +assert isinstance(dword.cast(MemShort), MemShort) +assert dword.cast(MemShort).val == 0x5678 # Field cast ms2.s2[0] = 0x34 ms2.s2[1] = 0x12 -assert ms2.cast_field("s2", PinnedShort).val == 0x1234 +assert ms2.cast_field("s2", MemShort).val == 0x1234 # Other method -assert PinnedShort(jitter.vm, ms2.get_addr("s2")).val == 0x1234 +assert MemShort(jitter.vm, ms2.get_addr("s2")).val == 0x1234 # Manual cast inside an Array ms2.s2[4] = 0xcd ms2.s2[5] = 0xab -assert PinnedShort(jitter.vm, ms2.s2.get_addr(4)).val == 0xabcd +assert MemShort(jitter.vm, ms2.s2.get_addr(4)).val == 0xabcd # void* style cast -PinnedPtrVoid = Ptr("I", Void()).pinned -p = PinnedPtrVoid(jitter.vm) +MemPtrVoid = Ptr("I", Void()).pinned +p = MemPtrVoid(jitter.vm) p.val = mstruct.get_addr() assert p.deref.cast(MyStruct) == mstruct assert p.cast(Ptr("I", MyStruct)).deref == mstruct @@ -474,7 +474,7 @@ assert BitField(Num("B"), [("f1", 1), ("f2", 4), ("f3", 1)]) != \ BitField(Num("B"), [("f1", 2), ("f2", 4), ("f3", 1)]) -# Quick PinnedField.pinned/PinnedField hash test +# Quick MemField.pinned/MemField hash test assert Num("f").pinned(jitter.vm, addr) == Num("f").pinned(jitter.vm, addr) # Types are cached assert Num("f").pinned == Num("f").pinned |