Static Runtime#
This document aims to provide a detailed guide on internal classes used to organize the parsed metadata.
Public Interface#
- umbrella.runtime.get_context_value(ctx, name: str)[source]#
Retrieve a context variable by its name (recursively).
- Parameters:
ctx (construct.Container) – the context
name (str) – the variable’s name
- Raises:
cs.ConstructError – if the variable could not be found
- Returns:
the associated value
Note that this method is used within the
Virtual
object creation. You can use it to search for a value within a context that has been set in the parent context.
- umbrella.runtime.__x64__(binary: Binary | Binary) bool [source]#
Returns whether the binary is using 64-bit pointers
- Parameters:
binary (BinaryT) – the parsed binary
- Returns:
whether the binary has 64-bit pointers
- Return type:
bool
- umbrella.runtime.sizeof(__struct: t.Union[cs.Construct, dc._DataclassT], **contextkw) int [source]#
Computes the size of a Construct object or dataclass struct.
- Parameters:
__struct (t.Union[cs.Construct, dc._DataclassT]) – the struct or dataclass type
- Returns:
the struct’s size
- Return type:
int
Examples:
>>> from umbrella.runtime import sizeof >>> sizeof(Virtual) # type reference 0 >>> sizeof(construct.Int32ul) # struct reference 4
Types#
The following table serves as a reference for annotated types in structs. It tries to illustrate each type’s size.
Name |
Size (in bytes) |
Python Type |
Info |
---|---|---|---|
Void |
NaN |
|
This object represents an incomplete type that can be used within relative pointers (see Swift ABI) |
int8_t |
1 |
|
signed char |
uint8_t |
1 |
|
unsigned char |
int16_t |
2 |
|
signed short |
uint16_t |
2 |
|
unsigned short |
int32_t |
4 |
|
signed integer |
uint32_t |
4 |
|
unsigned integer |
int64_t |
8 |
|
signed long |
uint64_t |
8 |
|
unsigned long |
uintptr_t |
4 or 8 |
|
Pointer type with a size of 8 bytes on 64-bit architectures and 4 on 32-bit ones. |
Abstract Classes#
- class umbrella.runtime.DataStream[source]#
Dummy class used for type annotations.
It should be used to parse construct classes based on their virtual address value. In addition every
DataStream
supports reading single or multiple raw bytes.- abstract read_struct(_DataStream__struct: t.Generic[T], _DataStream__vaddress: int, fix=False) t.Optional[T] [source]#
Reads a generic construct object or dataclass struct from the untderlying stream.
- Parameters:
__struct (t.Generic[T]) – the struct to parse
__vaddress (int) – the virtual memory address
fix (bool, optional) – whether the address should be fixed, defaults to False
- Returns:
the parsed object or nothing in case of an error
- Return type:
t.Optional[T]
- abstract read_raw(_DataStream__vaddress: int, _DataStream__size: int, fix=False) bytes | None [source]#
Reads raw bytes from the underlying stream.
- Parameters:
__vaddress (int) – the virtual memory address
__size (int) – the block size (how many bytes to consume)
fix (bool, optional) – whether the address should be translated before, defaults to False
- Returns:
the bytes read or none if an invalid virtual address was provided
- Return type:
t.Optional[bytes]
The next classes will be more important as they can be used as markers to trigger special struct parsing.
- class umbrella.runtime.CString#
A typing class that can be used to mark pointers to strings in virtual memory. Note that the returened string instance won’t store the zero termination character at the end. As this class is marked to be a singelton instance, you can reference it directly. Be aware that the following code won’t work:
1from umbrella.runtime import CString 2 3@dataclass 4class Foo: 5 name: str = csfield(CString) # !!! DON'T DO THAT
Due to the fact that this class is only a template/marker we can’t use it for parsing purposes directly.
1from umbrella.runtime import CString 2 3runtime = Runtime(...) 4objc: str = runtime.read_struct(CString, 0x1234) # Thats the right way
- class umbrella.runtime.RawCString#
A typing class that can be used to mark pointers to zero terminated bytearrays in virtual memory.
- is_raw_cstring(ty) bool #
Returns whether the given object or type conforms to a
RawCString
.- Parameters:
ty (type | RawCString) – the object or type
- Returns:
whether the given type conforms to a RawCString
- Return type:
bool
- class umbrella.runtime.Virtual[source]#
Base class of all virtual memory objects.
Each runtime implementation should set the
'address'
and'fp'
variable in the base context before parsing any struct. It ensures that virtual memory objects store their address and datastream correctly.Example:
>>> stream = ... # instance of DataStream >>> obj = stream.read_struct(Virtual, 12345) >>> obj._address 12345
- class umbrella.runtime.VirtualMemoryBlock(stream, struct=None)[source]#
A virtual memory block that can be used to parse struct at certain addresses.
This class can be used in ‘with’ statements and supports the ‘@’ operation to parse the structs:
>>> with VirtualMemoryBlock(runtime) as block: ... obj = (block+StructClass) @ 0x1234 ...
The ‘+’ operation is used to assign a struct type to this memory block and ‘@’ finally to parse it. The shortcut for the code above would be:
>>> obj = (runtime+StructClass) @ 0x1234
- stream: DataStream#
the datastream
- struct: Type[T] | Construct#
the dataclass or construct to parse
- class umbrella.runtime.VirtualArray(length, subcon)[source]#
Reimplementation of construct.Array that supports asigning virtual addresses.
- class umbrella.runtime.AlignedUnion(length, subcon: Construct)[source]#
Wrapper around construct’s
Union
class that supports a size.Parsing first parses the union and then consumes the amount of bytes specified in the length of this struct.
- class umbrella.runtime.Runtime(_Runtime__binary: Binary | Binary)[source]#
Basic implementation of a
DataStream
.Each ABI implementation should extend this class as it provides basic functionality when parsing structs or strings. In addition, there is an inbuilt cache that returns its values on requested virtual addresses. This class provides the following methods as its public API:
read_struct
: parsing structsread_raw
: reading raw data blocksread_string
: parsing of zero-terminated stringsread_ptr_section
: parsing a whole section as pointersread_terminated
: abstract parsing of terminated sequences
- Parameters:
__binary (BinaryT) – the parsed binary
- property binary: Binary | Binary#
Returns the parsed binary.
- get_binary_kind() str [source]#
Returns the module name for the parsed binary.
- Returns:
the binary’s module name
- Return type:
str
- fixup_address(_Runtime__vaddress: int) int [source]#
Transforms the given virtual address.
Some virtual addresses contain extra information that should be emitted. Therefore, sub-classes may implement this function to remove that information.
- Parameters:
__vaddress (int) – the virtual memory address
- Returns:
the ‘fixed’ address
- Return type:
int
- is_64() bool [source]#
Returns whether this runtime is using 64-bit structures
- Returns:
whether the underlying binary uses 64-bit
- Return type:
bool
- read_struct(_Runtime__struct: t.Generic[T], _Runtime__vaddress: int, /, fix=False) t.Optional[T] [source]#
Parses the given struct at the provided virtual address.
This method not only accepts construct objects, it also supports raw dataclass types. For example, the follwing class is defined to be a dataclass stuct:
>>> @dataclass ... class Foo: ... value: int = csfield(Int32ul) ...
with an object extending the
Runtime
class, you can use a raw type reference to parse the virtual memory.>>> runtime = ... # assume your instance here >>> runtime.read_struct(Foo, 0x12345) Foo(value=...)
Note that the usage of
CString
will result in a returned string value andRawString
will return the string as a bytearray (bytes
object).- Parameters:
__struct (dataclass type reference or Construct instance) – the struct to parse
__vaddress (int) – the virtual memory address
fix (bool, optional) – whether to fix the provided address, defaults to False
- Returns:
the parsed struct or nothing on an invalid address
- Return type:
t.Optional[T]
- read_raw(_Runtime__vaddress: int, _Runtime__size: int, /, fix=False) bytes | None [source]#
Reads the data from the provided virtual address
- Parameters:
__vaddress (int) – the virtual starting address
__size (int) – the amount of bytes to read
fix (bool, optional) – whether to fix the virtual address, defaults to False
- Returns:
the bytes consumed
- Return type:
t.Optional[bytes]
- read_terminated(_Runtime__vaddress: int, term=0, fix=False) bytes | None [source]#
Parses a terminated byte sequence using a 16-byte buffer.
- Parameters:
__vaddress (int) – the starting address
term (int, optional) – the terminator, defaults to 0
fix (bool, optional) – whether to apply a fix the given address, defaults to False
- Returns:
the consumed bytes excluding the terminator
- Return type:
t.Optional[bytes]
- read_string(_Runtime__vaddress: int, fix=False) str | None [source]#
Parses a CString without the trailing zero.
- Parameters:
__vaddress (int) – the starting address
fix (bool, optional) – whether to fix the address, defaults to False
- Returns:
the parsed string or nothing on failure
- Return type:
t.Optional[str]
- read_ptr_section(_Runtime__name: str, struct: Construct | None = None) Dict[int, int] [source]#
Parses a pointer section (see
ReflectionSectionIterator
)- Parameters:
__name (str) – the section’s name
struct (t.Optional[cs.Construct], optional (default is Int64ul)) – the pointer struct, defaults to None
- Returns:
the pointer values mapped to their virtual address
- Return type:
t.Dict[int, int]
- pointers(_Runtime__name: str, struct: Construct | None = None) List[int] [source]#
Returns only the values of all pointers
- Parameters:
__name (str) – the section’s name
struct (t.Optional[cs.Construct], optional) – the pointer struct to use, defaults to None
- Returns:
a list of parsed pointer values
- Return type:
t.List[int]