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

Implements a fixed or dynamically sized array type.

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: dissect.cstruct.types.BaseType, bits: int) int
write(field_type: dissect.cstruct.types.BaseType, data: int, bits: int) None
flush() None
reset() None
class dissect.cstruct.cstruct(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
typedefs
pointer = 'uint64'
__getattr__(attr: str) Any
add_type(name: str, type_: dissect.cstruct.types.MetaType | 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_: dissect.cstruct.types.MetaType, 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: str) dissect.cstruct.types.MetaType

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: dissect.cstruct.types.Structure) ctypes.Structure

Create ctypes structures from cstruct structures.

dissect.cstruct.ctypes_type(type_: dissect.cstruct.types.MetaType) 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(cstruct: Expression.__init__.cstruct, expression: str)

Expression parser for calculations in definitions.

binary_operators: ClassVar[dict[str, Callable[[int, int], int]]]
unary_operators: ClassVar[dict[str, Callable[[int], int]]]
precedence_levels: ClassVar[dict[str, int]]
cstruct
expression
tokens = []
stack = []
queue = []
__repr__() str
precedence(o1: str, o2: str) bool
evaluate_exp() None
is_number(token: str) bool
evaluate(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, BaseType

Implements a fixed or dynamically sized array type.

Example

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

x[3] -> 3 -> static length. x[] -> None -> null-terminated. x[expr] -> expr -> dynamic length.

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__() Char
class dissect.cstruct.CharArray

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

Character array type for reading and writing byte strings.

classmethod __default__() CharArray
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, type_: dissect.cstruct.types.base.MetaType, 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[Array] = 'Array'

The array type for this type class.

__call__(*args, **kwargs) MetaType | BaseType

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

__getitem__(num_entries: int | dissect.cstruct.expression.Expression | None) ArrayMetaType

Create a new array with the given number of entries.

__len__() int

Return the byte size of the type.

__default__() BaseType

Return the default value of this type.

reads(data: bytes) BaseType

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) BaseType

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

Packed type for Python struct (un)packing.

packchar: str
class dissect.cstruct.Pointer

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

Pointer to some other type.

type: dissect.cstruct.types.base.MetaType
__repr__() str

Return repr(self).

__str__() str

Return str(self).

__getattr__(attr: str) Any
__add__(other: int) Pointer

Return self+value.

__sub__(other: int) Pointer

Return self-value.

__mul__(other: int) Pointer

Return self*value.

__floordiv__(other: int) Pointer

Return self//value.

__mod__(other: int) Pointer

Return self%value.

__pow__(other: int) Pointer

Return pow(self, value, mod).

__lshift__(other: int) Pointer

Return self<<value.

__rshift__(other: int) Pointer

Return self>>value.

__and__(other: int) Pointer

Return self&value.

__xor__(other: int) Pointer

Return self^value.

__or__(other: int) Pointer

Return self|value.

classmethod __default__() Pointer
dereference() Any
class dissect.cstruct.Structure

Bases: dissect.cstruct.types.base.BaseType

Base class for cstruct structure type classes.

__len__() int

Return the byte size of the type.

__bytes__() bytes
__getitem__(item: str) Any
__repr__() str
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.

__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.BaseType

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.