dissect.cstruct#

Subpackages#

Submodules#

Package Contents#

Classes#

BitBuffer

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

Compiler

Compiler for cstruct structures. Creates somewhat optimized parsing code.

cstruct

Expression

Expression parser for calculations in definitions.

Array

Implements a fixed or dynamically sized array type.

BaseType

Base class for cstruct type classes.

RawType

Base class for raw types that have a name and size.

BytesInteger

Implements an integer type that can span an arbitrary amount of bytes.

CharType

Implements a character type that can properly handle strings.

Enum

Implements an Enum type.

EnumInstance

Implements a value instance of an Enum

Flag

Implements a Flag type.

FlagInstance

Implements a value instance of a Flag

Instance

Holds parsed structure data.

PackedType

Implements a packed type that uses Python struct packing characters.

Pointer

Implements a pointer to some other type.

PointerInstance

Like the Instance class, but for structures referenced by a pointer.

Field

Holds a structure field.

Structure

Type class for structures.

Union

Type class for unions

VoidType

Implements a void type.

WcharType

Implements a wide-character type.

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.

read(field_type: dissect.cstruct.types.RawType, bits: int | bytes) int#
write(field_type: dissect.cstruct.types.RawType, data: int, bits: int) None#
flush() None#
reset() None#
class dissect.cstruct.Compiler(cstruct: Compiler.__init__.cstruct)#

Compiler for cstruct structures. Creates somewhat optimized parsing code.

TYPES = ()#
COMPILE_TEMPLATE = Multiline-String#
Show Value
"""
class {name}(Structure):
    def __init__(self, cstruct, structure, source=None):
        self.structure = structure
        self.source = source
        super().__init__(cstruct, structure.name, structure.fields, anonymous=structure.anonymous)

    def _read(self, stream, context=None):
        r = OrderedDict()
        sizes = {{}}
        bitreader = BitBuffer(stream, self.cstruct.endian)

{read_code}

        return Instance(self, r, sizes)

    def add_field(self, name, type_, offset=None):
        raise NotImplementedError("Can't add fields to a compiled structure")

    def __repr__(self):
        return '<Structure {name} +compiled>'
"""
compile(structure: dissect.cstruct.types.Structure) dissect.cstruct.types.Structure#
gen_struct_class(name: str, structure: dissect.cstruct.types.Structure) str#
gen_read_block(size: int, block: List[str]) str#
gen_dynamic_block(field: dissect.cstruct.types.Field) str#
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#
__getattr__(attr: str) Any#
addtype(name: str, type_: dissect.cstruct.types.BaseType, replace: bool = False) None#

Add a type or type reference.

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.

load(definition: str, deftype: int = 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, **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.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: dissect.cstruct.types.Structure) ctypes.Structure#

Create ctypes structures from cstruct structures.

dissect.cstruct.ctypes_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(cstruct: Expression.__init__.cstruct, expression: str)#

Expression parser for calculations in definitions.

operators#
precedence_levels#
__repr__() str#

Return repr(self).

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.Array(cstruct: Array.__init__.cstruct, type_: BaseType, count: int)#

Bases: 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.

__repr__() str#

Return repr(self).

__len__() int#
default() List[Any]#

Return a default value of this type.

class dissect.cstruct.BaseType(cstruct: BaseType.__init__.cstruct)#

Base class for cstruct type classes.

__getitem__(count: int) Array#
__call__(*args, **kwargs) Any#
reads(data: bytes) Any#

Parse the given data according to the type that implements this class.

Parameters:

data – Byte string to parse.

Returns:

The parsed value of this type.

dumps(data: Any) bytes#

Dump the given data according to the type that implements this class.

Parameters:

data – Data to dump.

Returns:

The resulting bytes.

Raises:

ArraySizeError – Raised when len(data) does not match the size of a statically sized array field.

read(obj: BinaryIO, *args, **kwargs) Any#

Parse the given data according to the type that implements this class.

Parameters:

obj – Data to parse. Can be a (byte) string or a file-like object.

Returns:

The parsed value of this type.

write(stream: BinaryIO, data: Any) int#

Write the given data to a writable file-like object according to the type that implements this class.

Parameters:
  • stream – Writable file-like object to write to.

  • data – Data to write.

Returns:

The amount of bytes written.

Raises:

ArraySizeError – Raised when len(data) does not match the size of a statically sized array field.

abstract default() Any#

Return a default value of this type.

default_array(count: int) List[Any]#

Return a default array of this type.

class dissect.cstruct.RawType(cstruct: RawType.__init__.cstruct, name: str = None, size: int = 0, alignment: int = None)#

Bases: BaseType

Base class for raw types that have a name and size.

__len__() int#
__repr__() str#

Return repr(self).

abstract default() Any#

Return a default value of this type.

class dissect.cstruct.BytesInteger(cstruct: BytesInteger.__init__.cstruct, name: str, size: int, signed: bool, alignment: int = None)#

Bases: dissect.cstruct.types.RawType

Implements an integer type that can span an arbitrary amount of bytes.

static parse(buf: BinaryIO, size: int, count: int, signed: bool, endian: str) List[int]#
static pack(data: List[int], size: int, endian: str, signed: bool) bytes#
default() int#

Return a default value of this type.

default_array(count: int) List[int]#

Return a default array of this type.

class dissect.cstruct.CharType(cstruct: CharType.__init__.cstruct)#

Bases: dissect.cstruct.types.RawType

Implements a character type that can properly handle strings.

default() bytes#

Return a default value of this type.

default_array(count: int) bytes#

Return a default array of this type.

class dissect.cstruct.Enum(cstruct: Enum.__init__.cstruct, name: str, type_: dissect.cstruct.types.BaseType, values: Dict[str, int])#

Bases: dissect.cstruct.types.RawType

Implements an Enum type.

Enums can be made using any type. The API for accessing enums and their values is very similar to Python 3 native enums.

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 Testuint16 {

A, B=5, C

};

__call__(value: int | BinaryIO) EnumInstance#
__getitem__(attr: str) EnumInstance#
__getattr__(attr: str) EnumInstance#
__contains__(attr: str) bool#
default() EnumInstance#

Return a default value of this type.

default_array(count: int) List[EnumInstance]#

Return a default array of this type.

class dissect.cstruct.EnumInstance(enum: Enum, value: int)#

Implements a value instance of an Enum

property name: str#
__eq__(value: int | EnumInstance) bool#

Return self==value.

__ne__(value: int | EnumInstance) bool#

Return self!=value.

__hash__() int#

Return hash(self).

__str__() str#

Return str(self).

__int__() int#
__repr__() str#

Return repr(self).

class dissect.cstruct.Flag(cstruct: Enum.__init__.cstruct, name: str, type_: dissect.cstruct.types.BaseType, values: Dict[str, int])#

Bases: dissect.cstruct.types.Enum

Implements a Flag type.

Flags can be made using any type. The API for accessing flags and their values is very similar to Python 3 native flags.

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 Testuint16 {

A, B=4, C

};

__call__(value: int | BinaryIO) FlagInstance#
class dissect.cstruct.FlagInstance(enum: Enum, value: int)#

Bases: dissect.cstruct.types.EnumInstance

Implements a value instance of a Flag

property name: str#
__nonzero__#
__ror__#
__rand__#
__rxor__#
__bool__()#
__or__(other: int | FlagInstance) FlagInstance#
__and__(other: int | FlagInstance) FlagInstance#
__xor__(other: int | FlagInstance) FlagInstance#
__invert__() FlagInstance#
__str__() str#

Return str(self).

__repr__() str#

Return repr(self).

decompose() Tuple[List[str], int]#
class dissect.cstruct.Instance(type_: dissect.cstruct.types.BaseType, values: Dict[str, Any], sizes: Dict[str, int] = None)#

Holds parsed structure data.

__slots__ = ('_type', '_values', '_sizes')#
__getattr__(attr: str) Any#
__setattr__(attr: str, value: Any) None#

Implement setattr(self, name, value).

__getitem__(item: str) Any#
__contains__(attr: str) bool#
__repr__() str#

Return repr(self).

__len__() int#
__bytes__() bytes#
write(stream: BinaryIO) int#

Write this structure to a writable file-like object.

Parameters:

fh – File-like objects that supports writing.

Returns:

The amount of bytes written.

dumps() bytes#

Dump this structure to a byte string.

Returns:

The raw bytes of this structure.

class dissect.cstruct.PackedType(cstruct: PackedType.__init__.cstruct, name: str, size: int, packchar: str, alignment: int = None)#

Bases: dissect.cstruct.types.RawType

Implements a packed type that uses Python struct packing characters.

default() int#

Return a default value of this type.

default_array(count: int) List[int]#

Return a default array of this type.

class dissect.cstruct.Pointer(cstruct: Pointer.__init__.cstruct, target: dissect.cstruct.types.BaseType)#

Bases: dissect.cstruct.types.RawType

Implements a pointer to some other type.

__repr__() str#

Return repr(self).

class dissect.cstruct.PointerInstance(type_: dissect.cstruct.types.BaseType, stream: BinaryIO, addr: int, ctx: Dict[str, Any])#

Like the Instance class, but for structures referenced by a pointer.

__repr__() str#

Return repr(self).

__str__() str#

Return str(self).

__getattr__(attr: str) Any#
__int__() int#
__nonzero__() bool#
__add__(other: int | PointerInstance) PointerInstance#
__sub__(other: int | PointerInstance) PointerInstance#
__mul__(other: int | PointerInstance) PointerInstance#
__floordiv__(other: int | PointerInstance) PointerInstance#
__mod__(other: int | PointerInstance) PointerInstance#
__pow__(other: int | PointerInstance) PointerInstance#
__lshift__(other: int | PointerInstance) PointerInstance#
__rshift__(other: int | PointerInstance) PointerInstance#
__and__(other: int | PointerInstance) PointerInstance#
__xor__(other: int | PointerInstance) PointerInstance#
__or__(other: int | PointerInstance) PointerInstance#
__eq__(other: int | PointerInstance) bool#

Return self==value.

dereference() Any#
class dissect.cstruct.Field(name: str, type_: dissect.cstruct.types.BaseType, bits: int = None, offset: int = None)#

Holds a structure field.

__repr__()#

Return repr(self).

class dissect.cstruct.Structure(cstruct: Structure.__init__.cstruct, name: str, fields: List[Field] = None, align: bool = False, anonymous: bool = False)#

Bases: dissect.cstruct.types.BaseType

Type class for structures.

__len__() int#
__repr__() str#

Return repr(self).

add_field(name: str, type_: dissect.cstruct.types.BaseType, bits: int = None, offset: int = None) None#

Add a field to this structure.

Parameters:
  • name – The field name.

  • type – The field type.

  • bits – The bit of the field.

  • offset – The field offset.

default() dissect.cstruct.types.Instance#

Create and return an empty Instance from this structure.

Returns:

An empty Instance from this structure.

show(indent: int = 0) None#

Pretty print this structure.

class dissect.cstruct.Union(cstruct: Structure.__init__.cstruct, name: str, fields: List[Field] = None, align: bool = False, anonymous: bool = False)#

Bases: Structure

Type class for unions

__repr__() str#

Return repr(self).

abstract show(indent: int = 0) None#

Pretty print this structure.

class dissect.cstruct.VoidType#

Bases: dissect.cstruct.types.RawType

Implements a void type.

class dissect.cstruct.WcharType(cstruct)#

Bases: dissect.cstruct.types.RawType

Implements a wide-character type.

property encoding: str#
default() str#

Return a default value of this type.

default_array(count: int) str#

Return a default array of this type.

dissect.cstruct.dumpstruct(obj, data: bytes = None, offset: int = 0, color: bool = True, output: str = 'print')#

Dump a structure or parsed structure instance.

Prints a colorized hexdump and parsed structure output.

Parameters:
  • obj – Structure or Instance to dump.

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

  • offset – Byte offset of the hexdump.

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

dissect.cstruct.hexdump(data: bytes, palette=None, offset: int = 0, prefix: str = '', output: str = 'print')#

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, 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)#

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, 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.