dissect.esedb.page#

Module Contents#

Classes#

Page

Represents a logical page of an ESE database.

Tag

A tag is the "physical" data entry of a page.

Node

A node is the "logical" data entry of a page.

LeafNode

Special leaf node.

BranchNode

Special branch node. Parses the child page information.

class dissect.esedb.page.Page(esedb: dissect.esedb.esedb.EseDB, num: int, buf: bytes)#

Represents a logical page of an ESE database.

Parameters:
  • esedb – An instance of EseDB.

  • num – The logical page number.

  • buf – The physical page data.

is_small_page() bool#
is_root() bool#
is_leaf() bool#
is_parent() bool#
is_empty() bool#
is_space_tree() bool#
is_index() bool#
is_long_value() bool#
is_branch() bool#
key_prefix() bytes | None#
tag(num: int) Tag#

Retrieve a tag by index.

Parameters:

num – The tag number to retrieve.

Raises:

IndexError – If the tag number is out of bounds.

tags() Iterator[Tag]#

Yield all tags.

node(num: int) BranchNode | LeafNode#

Retrieve a node by index.

Nodes are just tags, but indexed from the first tag.

Parameters:

num – The node number to retrieve.

Raises:

IndexError – If the node number is out of bounds.

nodes() Iterator[BranchNode | LeafNode]#

Yield all nodes.

iter_leaf_nodes() Iterator[LeafNode]#

Walk the page tree and yield leaf nodes.

Two methods can be used, one is to travel down to the first leaf, and keep reading next_page’s, the other is to traverse the tree branches.

Impacket uses the first method, but gets caught in an infinite loop on some dirty databases. Traversing the branches seems safer, at the risk of missing a couple (possibly corrupt) pages.

For this reason, we actually explicitly check if the last page we parse has a next_page attribute, and also parse that. This methods seems to work so far.

__repr__() str#

Return repr(self).

class dissect.esedb.page.Tag(page: Page, num: int)#

A tag is the “physical” data entry of a page.

Parameters:
  • page – The Page this tag is in.

  • num – The tag number to parse.

__slots__ = ('page', 'num', 'tag', 'offset', 'size', 'data', 'flags')#
__repr__() str#

Return repr(self).

class dissect.esedb.page.Node(tag: Tag)#

A node is the “logical” data entry of a page.

Parameters:

tag – The Tag to parse a node from.

__slots__ = ('tag', 'num', 'key', 'key_prefix', 'key_suffix', 'data')#
class dissect.esedb.page.LeafNode(tag: Tag)#

Bases: Node

Special leaf node.

__repr__() str#

Return repr(self).

class dissect.esedb.page.BranchNode(tag: Tag)#

Bases: Node

Special branch node. Parses the child page information.

__slots__ = ('child',)#
__repr__() str#

Return repr(self).