dissect.cstruct

Subpackages

Submodules

Package Contents

Classes

BitBuffer

Implements a bit buffer that can read and write bit fields.

cstruct

Main class of cstruct. All types are registered in here.

Expression

Expression parser for calculations in definitions.

LEB128

Variable-length code compression to store an arbitrarily large integer in a small number of bytes.

Array

Built-in mutable sequence.

BaseType

Base class for cstruct type classes.

Char

Character type for reading and writing bytes.

CharArray

Character array type for reading and writing byte strings.

Enum

Enum type supercharged with cstruct functionality.

Field

Structure field.

Flag

Flag type supercharged with cstruct functionality.

Int

Integer type that can span an arbitrary amount of bytes.

MetaType

Base metaclass for cstruct type classes.

Packed

Packed type for Python struct (un)packing.

Pointer

Pointer to some other type.

Structure

Base class for cstruct structure type classes.

Union

Base class for cstruct union type classes.

Void

Void type.

Wchar

Wide-character type for reading and writing UTF-16 characters.

WcharArray

Wide-character array type for reading and writing UTF-16 strings.

Functions

ctypes

Create ctypes structures from cstruct structures.

ctypes_type

dumpstruct

Dump a structure or parsed structure instance.

hexdump

Hexdump some data.

p8

Pack an 8 bit integer.

p16

Pack a 16 bit integer.

p32

Pack a 32 bit integer.

p64

Pack a 64 bit integer.

pack

Pack an integer value to a given bit size, endianness.

swap

Swap the endianness of an integer with a given bit size.

swap16

Swap the endianness of a 16 bit integer.

swap32

Swap the endianness of a 32 bit integer.

swap64

Swap the endianness of a 64 bit integer.

u8

Unpack an 8 bit integer.

u16

Unpack a 16 bit integer.

u32

Unpack a 32 bit integer.

u64

Unpack a 64 bit integer.

unpack

Unpack an integer value from a given bit size, endianness and sign.

class dissect.cstruct.BitBuffer(stream: BinaryIO, endian: str)

Implements a bit buffer that can read and write bit fields.

stream
endian
read(field_type: type[dissect.cstruct.types.BaseType], bits: int) int
write(field_type: type[dissect.cstruct.types.BaseType], data: int, bits: int) None
flush() None
reset() None
class dissect.cstruct.cstruct(load: str = '', *, endian: str = '<', pointer: str | None = None)

Main class of cstruct. All types are registered in here.

Parameters:
  • endian – The endianness to use when parsing.

  • pointer – The pointer type to use for pointers.

DEF_CSTYLE = 1
DEF_LEGACY = 2
endian = '<'
consts
lookups
includes = []
typedefs
pointer: type[dissect.cstruct.types.BaseType] = 'uint64'
__getattr__(attr: str) Any
add_type(name: str, type_: type[dissect.cstruct.types.BaseType] | str, replace: bool = False) None

Add a type or type reference.

Only use this method when creating type aliases or adding already bound types.

Parameters:
  • name – Name of the type to be added.

  • type – The type to be added. Can be a str reference to another type or a compatible type class.

Raises:

ValueError – If the type already exists.

addtype
add_custom_type(name: str, type_: type[dissect.cstruct.types.BaseType], size: int | None = None, alignment: int | None = None, **kwargs) None

Add a custom type.

Use this method to add custom types to this cstruct instance. This is largely a convenience method for the internal _make_type() method, which binds a class to this cstruct instance.

Parameters:
  • name – Name of the type to be added.

  • type – The type to be added.

  • size – The size of the type.

  • alignment – The alignment of the type.

  • **kwargs – Additional attributes to add to the type.

load(definition: str, deftype: int | None = None, **kwargs) cstruct

Parse structures from the given definitions using the given definition type.

Definitions can be parsed using different parsers. Currently, there’s only one supported parser - DEF_CSTYLE. Parsers can add types and modify this cstruct instance. Arguments can be passed to parsers using kwargs.

The CSTYLE parser was recently replaced with token based parser, instead of a strictly regex based one. The old parser is still available by using DEF_LEGACY.

Parameters:
  • definition – The definition to parse.

  • deftype – The definition type to parse the definitions with.

  • **kwargs – Keyword arguments for parsers.

loadfile(path: str, deftype: int | None = None, **kwargs) None

Load structure definitions from a file.

The given path will be read and parsed using the load() function.

Parameters:
  • path – The path to load definitions from.

  • deftype – The definition type to parse the definitions with.

  • **kwargs – Keyword arguments for parsers.

read(name: str, stream: BinaryIO) Any

Parse data using a given type.

Parameters:
  • name – Type name to read.

  • stream – File-like object or byte string to parse.

Returns:

The parsed data.

resolve(name: type[dissect.cstruct.types.BaseType] | str) type[dissect.cstruct.types.BaseType]

Resolve a type name to get the actual type object.

Types can be referenced using different names. When we want the actual type object, we need to resolve these references.

Parameters:

name – Type name to resolve.

Returns:

The resolved type object.

Raises:

ResolveError – If the type can’t be resolved.

dissect.cstruct.ctypes(structure: type[dissect.cstruct.types.Structure]) type[ctypes.Structure]

Create ctypes structures from cstruct structures.

dissect.cstruct.ctypes_type(type_: type[dissect.cstruct.types.BaseType]) Any
exception dissect.cstruct.Error

Bases: Exception

Common base class for all non-exit exceptions.

exception dissect.cstruct.NullPointerDereference

Bases: Error

Common base class for all non-exit exceptions.

exception dissect.cstruct.ParserError

Bases: Error

Common base class for all non-exit exceptions.

exception dissect.cstruct.ResolveError

Bases: Error

Common base class for all non-exit exceptions.

class dissect.cstruct.Expression(expression: str)

Expression parser for calculations in definitions.

binary_operators: ClassVar[dict[str, collections.abc.Callable[[int, int], int]]]
unary_operators: ClassVar[dict[str, collections.abc.Callable[[int], int]]]
precedence_levels: ClassVar[dict[str, int]]
expression
tokens = []
stack = []
queue = []
__repr__() str
precedence(o1: str, o2: str) bool
evaluate_exp() None
is_number(token: str) bool
evaluate(cs: dissect.cstruct.cstruct, context: dict[str, int] | None = None) int

Evaluates an expression using a Shunting-Yard implementation.

class dissect.cstruct.LEB128

Bases: int, dissect.cstruct.types.base.BaseType

Variable-length code compression to store an arbitrarily large integer in a small number of bytes.

See https://en.wikipedia.org/wiki/LEB128 for more information and an explanation of the algorithm.

signed: bool
class dissect.cstruct.Array

Bases: list[T], BaseArray

Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

class dissect.cstruct.BaseType

Base class for cstruct type classes.

dumps
write
__len__() int

Return the byte size of the type.

class dissect.cstruct.Char

Bases: bytes, dissect.cstruct.types.base.BaseType

Character type for reading and writing bytes.

ArrayType
classmethod __default__() typing_extensions.Self
class dissect.cstruct.CharArray

Bases: bytes, dissect.cstruct.types.base.BaseArray

Character array type for reading and writing byte strings.

classmethod __default__() typing_extensions.Self
class dissect.cstruct.Enum

Bases: dissect.cstruct.types.base.BaseType, enum.IntEnum

Enum type supercharged with cstruct functionality.

Enums are (mostly) compatible with the Python 3 standard library IntEnum with some notable differences:
  • Duplicate members are their own unique member instead of being an alias

  • Non-existing values are allowed and handled similarly to IntFlag: <Enum: 0>

  • Enum members are only considered equal if the enum class is the same

Enums can be made using any integer type.

Example

When using the default C-style parser, the following syntax is supported:

enum <name> [: <type>] {
    <values>
};

For example, an enum that has A=1, B=5 and C=6 could be written like so:

enum Test : uint16 {
    A, B=5, C
};
__repr__() str

Return repr(self).

__eq__(other: int | Enum) bool

Return self==value.

__ne__(value: int | Enum) bool

Return self!=value.

__hash__() int

Return hash(self).

class dissect.cstruct.Field(name: str | None, type_: type[dissect.cstruct.types.base.BaseType], bits: int | None = None, offset: int | None = None)

Structure field.

name
type
bits = None
offset = None
alignment
__repr__() str
class dissect.cstruct.Flag

Bases: dissect.cstruct.types.base.BaseType, enum.IntFlag

Flag type supercharged with cstruct functionality.

Flags are (mostly) compatible with the Python 3 standard library IntFlag with some notable differences:
  • Flag members are only considered equal if the flag class is the same

Flags can be made using any integer type.

Example

When using the default C-style parser, the following syntax is supported:

flag <name> [: <type>] {
    <values>
};

For example, a flag that has A=1, B=4 and C=8 could be written like so:

flag Test : uint16 {
    A, B=4, C
};
__repr__() str

Return repr(self).

__str__() str

Return str(self).

__eq__(other: int | Flag) bool

Return self==value.

__ne__(value: int | Flag) bool

Return self!=value.

__hash__() int

Return hash(self).

class dissect.cstruct.Int

Bases: int, dissect.cstruct.types.base.BaseType

Integer type that can span an arbitrary amount of bytes.

signed: bool
class dissect.cstruct.MetaType

Bases: type

Base metaclass for cstruct type classes.

cs: dissect.cstruct.cstruct.cstruct

The cstruct instance this type class belongs to.

size: int | None

The size of the type in bytes. Can be None for dynamic sized types.

dynamic: bool

Whether or not the type is dynamically sized.

alignment: int | None

The alignment of the type in bytes. A value of None will be treated as 1-byte aligned.

ArrayType: type[BaseArray] = 'Array'

The array type for this type class.

__call__(*args, **kwargs) typing_extensions.Self

Adds support for TypeClass(bytes | file-like object) parsing syntax.

__getitem__(num_entries: int | dissect.cstruct.expression.Expression | None) type[BaseArray]

Create a new array with the given number of entries.

__bool__() bool

Type class is always truthy.

__len__() int

Return the byte size of the type.

__default__() typing_extensions.Self

Return the default value of this type.

reads(data: bytes | memoryview | bytearray) typing_extensions.Self

Parse the given data from a bytes-like object.

Parameters:

data – Bytes-like object to parse.

Returns:

The parsed value of this type.

read(obj: BinaryIO | bytes | memoryview | bytearray) typing_extensions.Self

Parse the given data.

Parameters:

obj – Data to parse. Can be a bytes-like object or a file-like object.

Returns:

The parsed value of this type.

write(stream: BinaryIO, value: Any) int

Write a value to a writable file-like object.

Parameters:
  • stream – File-like objects that supports writing.

  • value – Value to write.

Returns:

The amount of bytes written.

dumps(value: Any) bytes

Dump a value to a byte string.

Parameters:

value – Value to dump.

Returns:

The raw bytes of this type.

class dissect.cstruct.Packed

Bases: dissect.cstruct.types.base.BaseType, Generic[T]

Packed type for Python struct (un)packing.

packchar: str
class dissect.cstruct.Pointer

Bases: int, dissect.cstruct.types.base.BaseType, Generic[T]

Pointer to some other type.

type: Pointer.type[T]
__repr__() str

Return repr(self).

__str__() str

Return str(self).

__getattr__(attr: str) Any
__add__(other: int) typing_extensions.Self

Return self+value.

__sub__(other: int) typing_extensions.Self

Return self-value.

__mul__(other: int) typing_extensions.Self

Return self*value.

__floordiv__(other: int) typing_extensions.Self

Return self//value.

__mod__(other: int) typing_extensions.Self

Return self%value.

__pow__(other: int) typing_extensions.Self

Return pow(self, value, mod).

__lshift__(other: int) typing_extensions.Self

Return self<<value.

__rshift__(other: int) typing_extensions.Self

Return self>>value.

__and__(other: int) typing_extensions.Self

Return self&value.

__xor__(other: int) typing_extensions.Self

Return self^value.

__or__(other: int) typing_extensions.Self

Return self|value.

classmethod __default__() typing_extensions.Self
dereference() T
class dissect.cstruct.Structure

Bases: dissect.cstruct.types.base.BaseType

Base class for cstruct structure type classes.

Note that setting attributes which do not correspond to a field in the structure results in undefined behavior. For performance reasons, the structure does not check if the field exists when writing to an attribute.

__dynamic_sizes__: dict[str, int]
__len__() int

Return the byte size of the type.

__bytes__() bytes
__getitem__(item: str) Any
__repr__() str
property __values__: collections.abc.MutableMapping[str, Any]
property __sizes__: collections.abc.Mapping[str, int | None]
class dissect.cstruct.Union

Bases: Structure

Base class for cstruct union type classes.

__eq__(other: object) bool
__setattr__(attr: str, value: Any) None
class dissect.cstruct.Void

Bases: dissect.cstruct.types.base.BaseType

Void type.

ArrayType
__bool__() bool
__eq__(value: object) bool
class dissect.cstruct.Wchar

Bases: str, dissect.cstruct.types.base.BaseType

Wide-character type for reading and writing UTF-16 characters.

ArrayType
__slots__ = ()
__encoding_map__: ClassVar[dict[str, str]]
classmethod __default__() Wchar
class dissect.cstruct.WcharArray

Bases: str, dissect.cstruct.types.base.BaseArray

Wide-character array type for reading and writing UTF-16 strings.

__slots__ = ()
classmethod __default__() WcharArray
dissect.cstruct.dumpstruct(obj: dissect.cstruct.types.structure.Structure | type[dissect.cstruct.types.structure.Structure], data: bytes | None = None, offset: int = 0, color: bool = True, output: str = 'print') str | None

Dump a structure or parsed structure instance.

Prints a colorized hexdump and parsed structure output.

Parameters:
  • obj – Structure to dump.

  • data – Bytes to parse the Structure on, if obj is not a parsed Structure already.

  • offset – Byte offset of the hexdump.

  • output – Output format, can be ‘print’ or ‘string’.

dissect.cstruct.hexdump(data: bytes, palette: Palette | None = None, offset: int = 0, prefix: str = '', output: str = 'print') collections.abc.Iterator[str] | str | None

Hexdump some data.

Parameters:
  • data – Bytes to hexdump.

  • palette – Colorize the hexdump using this color pattern.

  • offset – Byte offset of the hexdump.

  • prefix – Optional prefix.

  • output – Output format, can be ‘print’, ‘generator’ or ‘string’.

dissect.cstruct.p8(value: int, endian: str = 'little') bytes

Pack an 8 bit integer.

Parameters:
  • value – Value to pack.

  • endian – Endianness to use (little, big, network, <, > or !)

dissect.cstruct.p16(value: int, endian: str = 'little') bytes

Pack a 16 bit integer.

Parameters:
  • value – Value to pack.

  • endian – Endianness to use (little, big, network, <, > or !)

dissect.cstruct.p32(value: int, endian: str = 'little') bytes

Pack a 32 bit integer.

Parameters:
  • value – Value to pack.

  • endian – Endianness to use (little, big, network, <, > or !)

dissect.cstruct.p64(value: int, endian: str = 'little') bytes

Pack a 64 bit integer.

Parameters:
  • value – Value to pack.

  • endian – Endianness to use (little, big, network, <, > or !)

dissect.cstruct.pack(value: int, size: int | None = None, endian: str = 'little') bytes

Pack an integer value to a given bit size, endianness.

Parameters:
  • value – Value to pack.

  • size – Integer size in bits.

  • endian – Endianness to use (little, big, network, <, > or !)

dissect.cstruct.swap(value: int, size: int) int

Swap the endianness of an integer with a given bit size.

Parameters:
  • value – Integer to swap.

  • size – Integer size in bits.

dissect.cstruct.swap16(value: int) int

Swap the endianness of a 16 bit integer.

Parameters:

value – Integer to swap.

dissect.cstruct.swap32(value: int) int

Swap the endianness of a 32 bit integer.

Parameters:

value – Integer to swap.

dissect.cstruct.swap64(value: int) int

Swap the endianness of a 64 bit integer.

Parameters:

value – Integer to swap.

dissect.cstruct.u8(value: bytes, endian: str = 'little', sign: bool = False) int

Unpack an 8 bit integer.

Parameters:
  • value – Value to unpack.

  • endian – Endianness to use (little, big, network, <, > or !)

  • sign – Signedness of the integer.

dissect.cstruct.u16(value: bytes, endian: str = 'little', sign: bool = False) int

Unpack a 16 bit integer.

Parameters:
  • value – Value to unpack.

  • endian – Endianness to use (little, big, network, <, > or !)

  • sign – Signedness of the integer.

dissect.cstruct.u32(value: bytes, endian: str = 'little', sign: bool = False) int

Unpack a 32 bit integer.

Parameters:
  • value – Value to unpack.

  • endian – Endianness to use (little, big, network, <, > or !)

  • sign – Signedness of the integer.

dissect.cstruct.u64(value: bytes, endian: str = 'little', sign: bool = False) int

Unpack a 64 bit integer.

Parameters:
  • value – Value to unpack.

  • endian – Endianness to use (little, big, network, <, > or !)

  • sign – Signedness of the integer.

dissect.cstruct.unpack(value: bytes, size: int | None = None, endian: str = 'little', sign: bool = False) int

Unpack an integer value from a given bit size, endianness and sign.

Parameters:
  • value – Value to unpack.

  • size – Integer size in bits.

  • endian – Endianness to use (little, big, network, <, > or !)

  • sign – Signedness of the integer.