Iterators#

This document tries to provide a compact overview of the generic iterators provided by this package. Each iterator class may be extended, so that it can be used within a new feature implementation.

class umbrella.iterator.CachingIterator[source]#

Base class for all iterators that cache their parsed values.

When iterating over elements, the following method order is applied:

  • __iter__ to start the iteration

  • __next__ to prepare the next element

  • _load performs the actual parsing of the next element

Note that this iterator also supports list-like access. You can reference each element with its index position. The method ordering is as follows

  • __getitem__ gets called on item access

  • (*) __next__ if the iterator has to parse additional values

  • (*) _load if additional elements has to be parsed

Examples:

>>> iterator = ...
>>> # Get all elements of an iterator (parsed ones)
>>> elements = iterator.elements
>>> # Get all elements (including elements that have to be parsed)
>>> elements = iterator.all()
>>> # Get an element by its index
>>> element = iterator[4]
>>> # Use slicing to get mulitple elements
>>> elements = iterator[2:5]
RESET = -1#

Additional field to mark the reset value for this iterator

property pos: int#

The current position as an integer value

Returns:

the current position (may be -1)

Return type:

int

property elements: List[E]#

Returns all cached elements of this iterator.

Note that this property will return all elements that have been parsed so far. Use all() for a list of all elements including the ones to be parsed.

Returns:

all stored elements

Return type:

t.List[E]

all() List[E][source]#

Returns a list of all elements including the ones to be parsed.

this call is equivalent to list(...).

Returns:

a list of all elements.

Return type:

t.List[E]

abstract _load(pos: int) E[source]#

Parses an element at the current index position.

Parameters:

pos (int) – the index position

Returns:

the parsed element

Return type:

E

__len__() int[source]#

Returns the length of this iterator (if present)

Hint

You can raise an IndexError if your iterator does not have a fixed size.

Raises:

NotImplementedError – by default, raises an error

Returns:

the size of this iterator

Return type:

int

class umbrella.iterator.LazyIterator(runtime: Runtime, **kwds)[source]#

Partial implementation of a CachingIterator to integrate a runtime object.

This class uses an internal context to store any additional variables used by the iterator. See ReflectionSectionIterator for more details on possible usage.

In addition, this class introduces a length field, which is used to determine the length of this iterator. Subclasses must specify the legth attribute with a string assigned to reference a context variable.

>>> class Foo(LazyIterator):
...     length = "foo_length"

Here, the referenced length variable "foo_length" must be set in the internal context within the _preload_context method.

_preload_context(**kwds) None[source]#

Prepares the internal context.

property runtime: Runtime#

Returns the associated runtime

Returns:

the runtime object

Return type:

Runtime

property context: Container#

Returns the internal context

Returns:

the internal context with all relevant values

Return type:

Container

class umbrella.iterator.ReflectionSectionIterator(runtime: Runtime, pointer_ty: Construct = None, **kwds)[source]#

Base iterator class used to iterate over structs in a reflection section.

Using python’s type inspection only the section’s name has to be provided. Everything else is configured automatically. For example,

>>> class Foo: ... # assume this class is a dataclass
>>> class FooIterator(ReflectionSectionIterator[Foo]):
...     kind = "__foo_section"
...
>>> it = FooIterator(runtime)
>>> foo = it[0] # get next element

The method ordering is a little bit different compared to the initial iterator class. When iterating, the following methods will be executed:

  1. _load to parse the current element

  2. _address_of retrieves the current load address

  3. load_at looks for cached elements first before parsing

  4. (*) _load_at parses the next element if not already cached

load_at(vaddress: int, parent_address=0) E | None[source]#

Loads a new struct at the given virtual address.

Parameters:

vaddress (int) – the virtual memory address

Returns:

the parsed struct or nothing on an invalid address

Return type:

t.Optional[E]