miasm.os_dep.win_32_structs module
from miasm.core.types import MemStruct, Num, Ptr, Str, \ Array, RawStruct, Union, \ BitField, Self, Void, Bits, \ set_allocator, MemUnion, Struct class UnicodeString(MemStruct): fields = [ ("length", Num("H")), ("maxlength", Num("H")), ("data", Ptr("<I", Str("utf16"))), ] class ListEntry(MemStruct): fields = [ ("flink", Ptr("<I", Void())), ("blink", Ptr("<I", Void())), ] class LdrDataEntry(MemStruct): """ +0x000 InLoadOrderLinks : _LIST_ENTRY +0x008 InMemoryOrderLinks : _LIST_ENTRY +0x010 InInitializationOrderLinks : _LIST_ENTRY +0x018 DllBase : Ptr32 Void +0x01c EntryPoint : Ptr32 Void +0x020 SizeOfImage : Uint4B +0x024 FullDllName : _UNICODE_STRING +0x02c BaseDllName : _UNICODE_STRING +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void +0x048 EntryPointActivationContext : Ptr32 Void +0x04c PatchInformation : Ptr32 Void """ fields = [ ("InLoadOrderLinks", ListEntry), ("InMemoryOrderLinks", ListEntry), ("InInitializationOrderLinks", ListEntry), ("DllBase", Ptr("<I", Void())), ("EntryPoint", Ptr("<I", Void())), ("SizeOfImage", Num("<I")), ("FullDllName", UnicodeString), ("BaseDllName", UnicodeString), ("Flags", Array(Num("B"), 4)), ("LoadCount", Num("H")), ("TlsIndex", Num("H")), ("union1", Union([ ("HashLinks", Ptr("<I", Void())), ("SectionPointer", Ptr("<I", Void())), ])), ("CheckSum", Num("<I")), ("union2", Union([ ("TimeDateStamp", Num("<I")), ("LoadedImports", Ptr("<I", Void())), ])), ("EntryPointActivationContext", Ptr("<I", Void())), ("PatchInformation", Ptr("<I", Void())), ] class PEB_LDR_DATA(MemStruct): """ +0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr32 Void +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01C InInitializationOrderModuleList : _LIST_ENTRY """ fields = [ ("Length", Num("<I")), ("Initialized", Num("<I")), ("SsHandle", Ptr("<I", Void())), ("InLoadOrderModuleList", ListEntry), ("InMemoryOrderModuleList", ListEntry), ("InInitializationOrderModuleList", ListEntry) ] class PEB(MemStruct): """ +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 SpareBool : UChar +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA +0x010 processparameter """ fields = [ ("InheritedAddressSpace", Num("B")), ("ReadImageFileExecOptions", Num("B")), ("BeingDebugged", Num("B")), ("SpareBool", Num("B")), ("Mutant", Ptr("<I", Void())), ("ImageBaseAddress", Num("<I")), ("Ldr", Ptr("<I", PEB_LDR_DATA)), ] class EXCEPTION_REGISTRATION_RECORD(MemStruct): """ +0x00 Next : struct _EXCEPTION_REGISTRATION_RECORD * +0x04 Handler : Ptr32 Void """ fields = [ ("Next", Ptr("<I", Self())), ("Handler", Ptr("<I", Void())), ] class EXCEPTION_RECORD(MemStruct): """ DWORD ExceptionCode; DWORD ExceptionFlags; struct _EXCEPTION_RECORD *ExceptionRecord; PVOID ExceptionAddress; DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; """ EXCEPTION_MAXIMUM_PARAMETERS = 15 fields = [ ("ExceptionCode", Num("<I")), ("ExceptionFlags", Num("<I")), ("ExceptionRecord", Ptr("<I", Self())), ("ExceptionAddress", Ptr("<I", Void())), ("NumberParameters", Num("<I")), ("ExceptionInformation", Ptr("<I", Void())), ] class NT_TIB(MemStruct): """ +00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList +04 void *StackBase +08 void *StackLimit +0c void *SubSystemTib +10 void *FiberData +10 uint32 Version +14 void *ArbitraryUserPointer +18 struct _NT_TIB *Self """ fields = [ ("ExceptionList", Ptr("<I", EXCEPTION_REGISTRATION_RECORD)), ("StackBase", Ptr("<I", Void())), ("StackLimit", Ptr("<I", Void())), ("SubSystemTib", Ptr("<I", Void())), (None, Union([ ("FiberData", Ptr("<I", Void())), ("Version", Num("<I")) ])), ("ArbitraryUserPointer", Ptr("<I", Void())), ("Self", Ptr("<I", Self())), ] class TEB(MemStruct): """ +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B ... """ fields = [ ("NtTib", NT_TIB), ("EnvironmentPointer", Ptr("<I", Void())), ("ClientId", Array(Num("B"), 0x8)), ("ActiveRpcHandle", Ptr("<I", Void())), ("ThreadLocalStoragePointer", Ptr("<I", Void())), ("ProcessEnvironmentBlock", Ptr("<I", PEB)), ("LastErrorValue", Num("<I")), ] class ContextException(MemStruct): fields = [ ("ContextFlags", Num("<I")), ("dr0", Num("<I")), ("dr1", Num("<I")), ("dr2", Num("<I")), ("dr3", Num("<I")), ("dr4", Num("<I")), ("dr5", Num("<I")), ("Float", Array(Num("B"), 112)), ("gs", Num("<I")), ("fs", Num("<I")), ("es", Num("<I")), ("ds", Num("<I")), ("edi", Num("<I")), ("esi", Num("<I")), ("ebx", Num("<I")), ("edx", Num("<I")), ("ecx", Num("<I")), ("eax", Num("<I")), ("ebp", Num("<I")), ("eip", Num("<I")), ("cs", Num("<I")), ("eflags", Num("<I")), ("esp", Num("<I")), ("ss", Num("<I")), ]
Classes
class ContextException
Base class to easily implement VmMngr backed C-like structures in miasm. Represents a structure in virtual memory.
The mechanism is the following:
- set a "fields" class field to be a list of
(
Example: class MyStruct(MemStruct): fields = [ # Scalar field: just struct.pack field with one value ("num", Num("I")), ("flags", Num("B")), # Ptr fields contain two fields: "val", for the numerical value, # and "deref" to get the pointed object ("other", Ptr("I", OtherStruct)), # Ptr to a variable length String ("s", Ptr("I", Str())), ("i", Ptr("I", Num("I"))), ]
mstruct = MyStruct(vm, addr) # Field assignment modifies virtual memory mstruct.num = 3 assert mstruct.num == 3 memval = struct.unpack("I", vm.get_mem(mstruct.get_addr(), 4))[0] assert memval == mstruct.num # Memset sets the whole structure mstruct.memset() assert mstruct.num == 0 mstruct.memset('') assert mstruct.num == 0x11111111 other = OtherStruct(vm, addr2) mstruct.other = other.get_addr() assert mstruct.other.val == other.get_addr() assert mstruct.other.deref == other assert mstruct.other.deref.foo == 0x1234
Note that:
MyStruct = Struct("MyStruct",
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.
class ContextException(MemStruct): fields = [ ("ContextFlags", Num("<I")), ("dr0", Num("<I")), ("dr1", Num("<I")), ("dr2", Num("<I")), ("dr3", Num("<I")), ("dr4", Num("<I")), ("dr5", Num("<I")), ("Float", Array(Num("B"), 112)), ("gs", Num("<I")), ("fs", Num("<I")), ("es", Num("<I")), ("ds", Num("<I")), ("edi", Num("<I")), ("esi", Num("<I")), ("ebx", Num("<I")), ("edx", Num("<I")), ("ecx", Num("<I")), ("eax", Num("<I")), ("ebp", Num("<I")), ("eip", Num("<I")), ("cs", Num("<I")), ("eflags", Num("<I")), ("esp", Num("<I")), ("ss", Num("<I")), ]
Ancestors (in MRO)
- ContextException
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var ContextFlags
var Float
var cs
var dr0
var dr1
var dr2
var dr3
var dr4
var dr5
var ds
var eax
var ebp
var ebx
var ecx
var edi
var edx
var eflags
var eip
var es
var esi
var esp
var fs
var gs
var ss
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class EXCEPTION_RECORD
DWORD ExceptionCode; DWORD ExceptionFlags; struct _EXCEPTION_RECORD *ExceptionRecord; PVOID ExceptionAddress; DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
class EXCEPTION_RECORD(MemStruct): """ DWORD ExceptionCode; DWORD ExceptionFlags; struct _EXCEPTION_RECORD *ExceptionRecord; PVOID ExceptionAddress; DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; """ EXCEPTION_MAXIMUM_PARAMETERS = 15 fields = [ ("ExceptionCode", Num("<I")), ("ExceptionFlags", Num("<I")), ("ExceptionRecord", Ptr("<I", Self())), ("ExceptionAddress", Ptr("<I", Void())), ("NumberParameters", Num("<I")), ("ExceptionInformation", Ptr("<I", Void())), ]
Ancestors (in MRO)
- EXCEPTION_RECORD
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var EXCEPTION_MAXIMUM_PARAMETERS
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var ExceptionAddress
var ExceptionCode
var ExceptionFlags
var ExceptionInformation
var ExceptionRecord
var NumberParameters
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class EXCEPTION_REGISTRATION_RECORD
+0x00 Next : struct _EXCEPTION_REGISTRATION_RECORD * +0x04 Handler : Ptr32 Void
class EXCEPTION_REGISTRATION_RECORD(MemStruct): """ +0x00 Next : struct _EXCEPTION_REGISTRATION_RECORD * +0x04 Handler : Ptr32 Void """ fields = [ ("Next", Ptr("<I", Self())), ("Handler", Ptr("<I", Void())), ]
Ancestors (in MRO)
- EXCEPTION_REGISTRATION_RECORD
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var Handler
var Next
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class LdrDataEntry
+0x000 InLoadOrderLinks : _LIST_ENTRY +0x008 InMemoryOrderLinks : _LIST_ENTRY +0x010 InInitializationOrderLinks : _LIST_ENTRY +0x018 DllBase : Ptr32 Void +0x01c EntryPoint : Ptr32 Void +0x020 SizeOfImage : Uint4B +0x024 FullDllName : _UNICODE_STRING +0x02c BaseDllName : _UNICODE_STRING +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void +0x048 EntryPointActivationContext : Ptr32 Void +0x04c PatchInformation : Ptr32 Void
class LdrDataEntry(MemStruct): """ +0x000 InLoadOrderLinks : _LIST_ENTRY +0x008 InMemoryOrderLinks : _LIST_ENTRY +0x010 InInitializationOrderLinks : _LIST_ENTRY +0x018 DllBase : Ptr32 Void +0x01c EntryPoint : Ptr32 Void +0x020 SizeOfImage : Uint4B +0x024 FullDllName : _UNICODE_STRING +0x02c BaseDllName : _UNICODE_STRING +0x034 Flags : Uint4B +0x038 LoadCount : Uint2B +0x03a TlsIndex : Uint2B +0x03c HashLinks : _LIST_ENTRY +0x03c SectionPointer : Ptr32 Void +0x040 CheckSum : Uint4B +0x044 TimeDateStamp : Uint4B +0x044 LoadedImports : Ptr32 Void +0x048 EntryPointActivationContext : Ptr32 Void +0x04c PatchInformation : Ptr32 Void """ fields = [ ("InLoadOrderLinks", ListEntry), ("InMemoryOrderLinks", ListEntry), ("InInitializationOrderLinks", ListEntry), ("DllBase", Ptr("<I", Void())), ("EntryPoint", Ptr("<I", Void())), ("SizeOfImage", Num("<I")), ("FullDllName", UnicodeString), ("BaseDllName", UnicodeString), ("Flags", Array(Num("B"), 4)), ("LoadCount", Num("H")), ("TlsIndex", Num("H")), ("union1", Union([ ("HashLinks", Ptr("<I", Void())), ("SectionPointer", Ptr("<I", Void())), ])), ("CheckSum", Num("<I")), ("union2", Union([ ("TimeDateStamp", Num("<I")), ("LoadedImports", Ptr("<I", Void())), ])), ("EntryPointActivationContext", Ptr("<I", Void())), ("PatchInformation", Ptr("<I", Void())), ]
Ancestors (in MRO)
- LdrDataEntry
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var BaseDllName
var CheckSum
var DllBase
var EntryPoint
var EntryPointActivationContext
var Flags
var FullDllName
var InInitializationOrderLinks
var InLoadOrderLinks
var InMemoryOrderLinks
var LoadCount
var PatchInformation
var SizeOfImage
var TlsIndex
var union1
var union2
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class ListEntry
Base class to easily implement VmMngr backed C-like structures in miasm. Represents a structure in virtual memory.
The mechanism is the following:
- set a "fields" class field to be a list of
(
Example: class MyStruct(MemStruct): fields = [ # Scalar field: just struct.pack field with one value ("num", Num("I")), ("flags", Num("B")), # Ptr fields contain two fields: "val", for the numerical value, # and "deref" to get the pointed object ("other", Ptr("I", OtherStruct)), # Ptr to a variable length String ("s", Ptr("I", Str())), ("i", Ptr("I", Num("I"))), ]
mstruct = MyStruct(vm, addr) # Field assignment modifies virtual memory mstruct.num = 3 assert mstruct.num == 3 memval = struct.unpack("I", vm.get_mem(mstruct.get_addr(), 4))[0] assert memval == mstruct.num # Memset sets the whole structure mstruct.memset() assert mstruct.num == 0 mstruct.memset('') assert mstruct.num == 0x11111111 other = OtherStruct(vm, addr2) mstruct.other = other.get_addr() assert mstruct.other.val == other.get_addr() assert mstruct.other.deref == other assert mstruct.other.deref.foo == 0x1234
Note that:
MyStruct = Struct("MyStruct",
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.
class ListEntry(MemStruct): fields = [ ("flink", Ptr("<I", Void())), ("blink", Ptr("<I", Void())), ]
Ancestors (in MRO)
- ListEntry
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var blink
var flink
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class NT_TIB
+00 struct _EXCEPTION_REGISTRATION_RECORD ExceptionList +04 void StackBase +08 void StackLimit +0c void SubSystemTib +10 void FiberData +10 uint32 Version +14 void ArbitraryUserPointer +18 struct _NT_TIB *Self
class NT_TIB(MemStruct): """ +00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList +04 void *StackBase +08 void *StackLimit +0c void *SubSystemTib +10 void *FiberData +10 uint32 Version +14 void *ArbitraryUserPointer +18 struct _NT_TIB *Self """ fields = [ ("ExceptionList", Ptr("<I", EXCEPTION_REGISTRATION_RECORD)), ("StackBase", Ptr("<I", Void())), ("StackLimit", Ptr("<I", Void())), ("SubSystemTib", Ptr("<I", Void())), (None, Union([ ("FiberData", Ptr("<I", Void())), ("Version", Num("<I")) ])), ("ArbitraryUserPointer", Ptr("<I", Void())), ("Self", Ptr("<I", Self())), ]
Ancestors (in MRO)
- NT_TIB
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var ArbitraryUserPointer
var ExceptionList
var FiberData
var Self
var StackBase
var StackLimit
var SubSystemTib
var Version
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class PEB
+0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 SpareBool : UChar +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA +0x010 processparameter
class PEB(MemStruct): """ +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 SpareBool : UChar +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA +0x010 processparameter """ fields = [ ("InheritedAddressSpace", Num("B")), ("ReadImageFileExecOptions", Num("B")), ("BeingDebugged", Num("B")), ("SpareBool", Num("B")), ("Mutant", Ptr("<I", Void())), ("ImageBaseAddress", Num("<I")), ("Ldr", Ptr("<I", PEB_LDR_DATA)), ]
Ancestors (in MRO)
- PEB
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var BeingDebugged
var ImageBaseAddress
var InheritedAddressSpace
var Ldr
var Mutant
var ReadImageFileExecOptions
var SpareBool
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class PEB_LDR_DATA
+0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr32 Void +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01C InInitializationOrderModuleList : _LIST_ENTRY
class PEB_LDR_DATA(MemStruct): """ +0x000 Length : Uint4B +0x004 Initialized : UChar +0x008 SsHandle : Ptr32 Void +0x00c InLoadOrderModuleList : _LIST_ENTRY +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01C InInitializationOrderModuleList : _LIST_ENTRY """ fields = [ ("Length", Num("<I")), ("Initialized", Num("<I")), ("SsHandle", Ptr("<I", Void())), ("InLoadOrderModuleList", ListEntry), ("InMemoryOrderModuleList", ListEntry), ("InInitializationOrderModuleList", ListEntry) ]
Ancestors (in MRO)
- PEB_LDR_DATA
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var InInitializationOrderModuleList
var InLoadOrderModuleList
var InMemoryOrderModuleList
var Initialized
var Length
var SsHandle
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class TEB
+0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B ...
class TEB(MemStruct): """ +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB +0x034 LastErrorValue : Uint4B ... """ fields = [ ("NtTib", NT_TIB), ("EnvironmentPointer", Ptr("<I", Void())), ("ClientId", Array(Num("B"), 0x8)), ("ActiveRpcHandle", Ptr("<I", Void())), ("ThreadLocalStoragePointer", Ptr("<I", Void())), ("ProcessEnvironmentBlock", Ptr("<I", PEB)), ("LastErrorValue", Num("<I")), ]
Ancestors (in MRO)
- TEB
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var ActiveRpcHandle
var ClientId
var EnvironmentPointer
var LastErrorValue
var NtTib
var ProcessEnvironmentBlock
var ThreadLocalStoragePointer
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size
class UnicodeString
Base class to easily implement VmMngr backed C-like structures in miasm. Represents a structure in virtual memory.
The mechanism is the following:
- set a "fields" class field to be a list of
(
Example: class MyStruct(MemStruct): fields = [ # Scalar field: just struct.pack field with one value ("num", Num("I")), ("flags", Num("B")), # Ptr fields contain two fields: "val", for the numerical value, # and "deref" to get the pointed object ("other", Ptr("I", OtherStruct)), # Ptr to a variable length String ("s", Ptr("I", Str())), ("i", Ptr("I", Num("I"))), ]
mstruct = MyStruct(vm, addr) # Field assignment modifies virtual memory mstruct.num = 3 assert mstruct.num == 3 memval = struct.unpack("I", vm.get_mem(mstruct.get_addr(), 4))[0] assert memval == mstruct.num # Memset sets the whole structure mstruct.memset() assert mstruct.num == 0 mstruct.memset('') assert mstruct.num == 0x11111111 other = OtherStruct(vm, addr2) mstruct.other = other.get_addr() assert mstruct.other.val == other.get_addr() assert mstruct.other.deref == other assert mstruct.other.deref.foo == 0x1234
Note that:
MyStruct = Struct("MyStruct",
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.
class UnicodeString(MemStruct): fields = [ ("length", Num("H")), ("maxlength", Num("H")), ("data", Ptr("<I", Str("utf16"))), ]
Ancestors (in MRO)
- UnicodeString
- miasm.core.types.MemStruct
- miasm.core.types.MemType
- builtins.object
Class variables
var allocator
var fields
Static methods
def __init__(
self, vm, addr=None, type_=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, vm, addr=None, type_=None): self._vm = vm if addr is None: self._addr = self.alloc(vm, self.get_size()) else: self._addr = addr if type_ is not None: self._type = type_ if self._type is None: raise ValueError("Subclass MemType and define cls._type or pass " "a type to the constructor")
def cast(
self, other_type)
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.lval is used) or a MemType subclass
def cast(self, other_type): """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.lval is used) or a MemType subclass """ if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr())
def cast_field(
self, field, other_type)
In this implementation, @field is a field name
def cast_field(self, field, other_type): """In this implementation, @field is a field name""" if isinstance(other_type, Type): other_type = other_type.lval return other_type(self._vm, self.get_addr(field))
def get_addr(
self, field_name=None)
@field_name: (str, optional) the name of the field to get the address of
def get_addr(self, field_name=None): """ @field_name: (str, optional) the name of the field to get the address of """ if field_name is not None: offset = self._type.get_offset(field_name) else: offset = 0 return self._addr + offset
def get_field(
self, name)
Get a field value by name.
useless most of the time since fields are accessible via self.
def get_field(self, name): """Get a field value by name. useless most of the time since fields are accessible via self.<name>. """ return self._type.get_field(self._vm, self.get_addr(), name)
def get_size(
self)
Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class.
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.
def get_size(self): """Return the dynamic size of this structure (e.g. the size of an instance). Defaults to sizeof for this base class. 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=b'\x00')
Fill the memory space of this MemType with @byte (' ' by default). The size is retrieved with self.get_size() (dynamic size).
def memset(self, byte=b'\x00'): """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 if not isinstance(byte, bytes) or len(byte) != 1: raise ValueError("byte must be a 1-lengthed str") self._vm.set_mem(self.get_addr(), byte * self.get_size())
def raw(
self)
Raw binary (str) representation of the MemType as it is in memory.
def raw(self): """Raw binary (str) representation of the MemType as it is in memory. """ return self._vm.get_mem(self.get_addr(), self.get_size())
def set_field(
self, name, val)
Set a field value by name. @val is the python value corresponding to this field type.
useless most of the time since fields are accessible via self.
def set_field(self, name, val): """Set a field value by name. @val is the python value corresponding to this field type. useless most of the time since fields are accessible via self.<name>. """ return self._type.set_field(self._vm, self.get_addr(), name, val)
Instance variables
var data
var length
var maxlength
Methods
def alloc(
cls, vm, size)
Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise.
@classmethod def alloc(cls, vm, size): """Returns an allocated page of size @size if cls.allocator is set. Raises ValueError otherwise. """ if cls.allocator is None: raise ValueError("Cannot provide None address to MemType() if" "%s.set_allocator has not been called." % __name__) return cls.allocator(vm, size)
def gen_fields(
cls, fields=None)
Generate the fields of this class (so that they can be accessed with
self.
Useful in case of a type cyclic dependency. For example, the following is not possible in python:
class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))]
With gen_fields, the following is the legal equivalent:
class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))])
@classmethod def gen_fields(cls, fields=None): """Generate the fields of this class (so that they can be accessed with self.<field_name>) from a @fields list, as described in the class doc. Useful in case of a type cyclic dependency. For example, the following is not possible in python: class A(MemStruct): fields = [("b", Ptr("I", B))] class B(MemStruct): fields = [("a", Ptr("I", A))] With gen_fields, the following is the legal equivalent: class A(MemStruct): pass class B(MemStruct): fields = [("a", Ptr("I", A))] A.gen_fields([("b", Ptr("I", B))]) """ if fields is not None: if cls.fields is not None: raise ValueError("Cannot regen fields of a class. Setting " "cls.fields at class definition and calling " "gen_fields are mutually exclusive.") cls.fields = fields if cls._type is None: if cls.fields is None: 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 MemType has the same type as this " "one. Use it instead.") # Register this class so that another one will not be created when # calling cls._type.lval DYN_MEM_STRUCT_CACHE[cls._type] = cls cls._gen_attributes()
def get_offset(
cls, field_name)
Shorthand for self.get_type().get_offset(field_name).
@classmethod def get_offset(cls, field_name): """Shorthand for self.get_type().get_offset(field_name).""" return cls.get_type().get_offset(field_name)
def get_type(
cls)
Returns the Type subclass instance representing the C type of this MemType.
@classmethod def get_type(cls): """Returns the Type subclass instance representing the C type of this MemType. """ return cls._type
def set_allocator(
cls, alloc_func)
Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm).
You may call set_allocator on specific MemType classes if you want to use a different allocator.
@alloc_func: func(VmMngr) -> integer_address
@classmethod def set_allocator(cls, alloc_func): """Set an allocator for this class; allows to instantiate statically sized MemTypes (i.e. sizeof() is implemented) without specifying the address (the object is allocated by @alloc_func in the vm). You may call set_allocator on specific MemType classes if you want to use a different allocator. @alloc_func: func(VmMngr) -> integer_address """ cls.allocator = alloc_func
def sizeof(
cls)
Return the static size of this type. By default, it is the size of the underlying Type.
@classmethod def sizeof(cls): """Return the static size of this type. By default, it is the size of the underlying Type. """ return cls._type.size