:py:mod:`dissect.cstruct`
=========================
.. py:module:: dissect.cstruct
Subpackages
-----------
.. toctree::
:titlesonly:
:maxdepth: 3
types/index.rst
Submodules
----------
.. toctree::
:titlesonly:
:maxdepth: 1
bitbuffer/index.rst
compiler/index.rst
cstruct/index.rst
exceptions/index.rst
expression/index.rst
parser/index.rst
utils/index.rst
Package Contents
----------------
Classes
~~~~~~~
.. autoapisummary::
dissect.cstruct.BitBuffer
dissect.cstruct.Compiler
dissect.cstruct.cstruct
dissect.cstruct.Expression
dissect.cstruct.Array
dissect.cstruct.BaseType
dissect.cstruct.RawType
dissect.cstruct.BytesInteger
dissect.cstruct.CharType
dissect.cstruct.Enum
dissect.cstruct.EnumInstance
dissect.cstruct.Flag
dissect.cstruct.FlagInstance
dissect.cstruct.Instance
dissect.cstruct.LEB128
dissect.cstruct.PackedType
dissect.cstruct.Pointer
dissect.cstruct.PointerInstance
dissect.cstruct.Field
dissect.cstruct.Structure
dissect.cstruct.Union
dissect.cstruct.VoidType
dissect.cstruct.WcharType
Functions
~~~~~~~~~
.. autoapisummary::
:nosignatures:
dissect.cstruct.ctypes
dissect.cstruct.ctypes_type
dissect.cstruct.dumpstruct
dissect.cstruct.hexdump
dissect.cstruct.p8
dissect.cstruct.p16
dissect.cstruct.p32
dissect.cstruct.p64
dissect.cstruct.pack
dissect.cstruct.swap
dissect.cstruct.swap16
dissect.cstruct.swap32
dissect.cstruct.swap64
dissect.cstruct.u8
dissect.cstruct.u16
dissect.cstruct.u32
dissect.cstruct.u64
dissect.cstruct.unpack
.. py:class:: BitBuffer(stream: BinaryIO, endian: str)
Implements a bit buffer that can read and write bit fields.
.. py:method:: read(field_type: dissect.cstruct.types.RawType, bits: Union[int, bytes]) -> int
.. py:method:: write(field_type: dissect.cstruct.types.RawType, data: int, bits: int) -> None
.. py:method:: flush() -> None
.. py:method:: reset() -> None
.. py:class:: Compiler(cstruct: Compiler.__init__.cstruct)
Compiler for cstruct structures. Creates somewhat optimized parsing code.
.. py:attribute:: TYPES
:value: ()
.. py:attribute:: COMPILE_TEMPLATE
:value: Multiline-String
.. raw:: html
Show Value
.. code-block:: python
"""
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 ''
"""
.. raw:: html
.. py:method:: compile(structure: dissect.cstruct.types.Structure) -> dissect.cstruct.types.Structure
.. py:method:: gen_struct_class(name: str, structure: dissect.cstruct.types.Structure) -> str
.. py:method:: gen_read_block(size: int, block: List[str]) -> str
.. py:method:: gen_dynamic_block(field: dissect.cstruct.types.Field) -> str
.. py:class:: cstruct(endian: str = '<', pointer: Optional[str] = None)
Main class of cstruct. All types are registered in here.
:param endian: The endianness to use when parsing.
:param pointer: The pointer type to use for Pointers.
.. py:attribute:: DEF_CSTYLE
:value: 1
.. py:attribute:: DEF_LEGACY
:value: 2
.. py:method:: __getattr__(attr: str) -> Any
.. py:method:: addtype(name: str, type_: dissect.cstruct.types.BaseType, replace: bool = False) -> None
Add a type or type reference.
:param name: Name of the type to be added.
:param 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.
.. py:method:: 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.
:param definition: The definition to parse.
:param deftype: The definition type to parse the definitions with.
:param \*\*kwargs: Keyword arguments for parsers.
.. py:method:: 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.
:param path: The path to load definitions from.
:param deftype: The definition type to parse the definitions with.
:param \*\*kwargs: Keyword arguments for parsers.
.. py:method:: read(name: str, stream: BinaryIO) -> Any
Parse data using a given type.
:param name: Type name to read.
:param stream: File-like object or byte string to parse.
:returns: The parsed data.
.. py:method:: 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.
:param name: Type name to resolve.
:returns: The resolved type object.
:raises ResolveError: If the type can't be resolved.
.. py:function:: ctypes(structure: dissect.cstruct.types.Structure) -> ctypes.Structure
Create ctypes structures from cstruct structures.
.. py:function:: ctypes_type(type_: dissect.cstruct.types.BaseType) -> Any
.. py:exception:: Error
Bases: :py:obj:`Exception`
Common base class for all non-exit exceptions.
.. py:exception:: NullPointerDereference
Bases: :py:obj:`Error`
Common base class for all non-exit exceptions.
.. py:exception:: ParserError
Bases: :py:obj:`Error`
Common base class for all non-exit exceptions.
.. py:exception:: ResolveError
Bases: :py:obj:`Error`
Common base class for all non-exit exceptions.
.. py:class:: Expression(cstruct: Expression.__init__.cstruct, expression: str)
Expression parser for calculations in definitions.
.. py:attribute:: operators
.. py:attribute:: precedence_levels
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: precedence(o1: str, o2: str) -> bool
.. py:method:: evaluate_exp() -> None
.. py:method:: is_number(token: str) -> bool
.. py:method:: evaluate(context: Optional[dict[str, int]] = None) -> int
Evaluates an expression using a Shunting-Yard implementation.
.. py:class:: Array(cstruct: Array.__init__.cstruct, type_: BaseType, count: int)
Bases: :py:obj:`BaseType`
Implements a fixed or dynamically sized array type.
.. rubric:: 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.
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: __len__() -> int
.. py:method:: default() -> List[Any]
Return a default value of this type.
.. py:class:: BaseType(cstruct: BaseType.__init__.cstruct)
Base class for cstruct type classes.
.. py:method:: __getitem__(count: int) -> Array
.. py:method:: __call__(*args, **kwargs) -> Any
.. py:method:: reads(data: bytes) -> Any
Parse the given data according to the type that implements this class.
:param data: Byte string to parse.
:returns: The parsed value of this type.
.. py:method:: dumps(data: Any) -> bytes
Dump the given data according to the type that implements this class.
:param 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.
.. py:method:: read(obj: BinaryIO, *args, **kwargs) -> Any
Parse the given data according to the type that implements this class.
:param obj: Data to parse. Can be a (byte) string or a file-like object.
:returns: The parsed value of this type.
.. py:method:: write(stream: BinaryIO, data: Any) -> int
Write the given data to a writable file-like object according to the
type that implements this class.
:param stream: Writable file-like object to write to.
:param 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.
.. py:method:: default() -> Any
:abstractmethod:
Return a default value of this type.
.. py:method:: default_array(count: int) -> List[Any]
Return a default array of this type.
.. py:class:: RawType(cstruct: RawType.__init__.cstruct, name: str = None, size: int = 0, alignment: int = None)
Bases: :py:obj:`BaseType`
Base class for raw types that have a name and size.
.. py:method:: __len__() -> int
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: default() -> Any
:abstractmethod:
Return a default value of this type.
.. py:class:: BytesInteger(cstruct: BytesInteger.__init__.cstruct, name: str, size: int, signed: bool, alignment: int = None)
Bases: :py:obj:`dissect.cstruct.types.RawType`
Implements an integer type that can span an arbitrary amount of bytes.
.. py:method:: parse(buf: BinaryIO, size: int, count: int, signed: bool, endian: str) -> List[int]
:staticmethod:
.. py:method:: pack(data: List[int], size: int, endian: str, signed: bool) -> bytes
:staticmethod:
.. py:method:: default() -> int
Return a default value of this type.
.. py:method:: default_array(count: int) -> List[int]
Return a default array of this type.
.. py:class:: CharType(cstruct: CharType.__init__.cstruct)
Bases: :py:obj:`dissect.cstruct.types.RawType`
Implements a character type that can properly handle strings.
.. py:method:: default() -> bytes
Return a default value of this type.
.. py:method:: default_array(count: int) -> bytes
Return a default array of this type.
.. py:class:: Enum(cstruct: Enum.__init__.cstruct, name: str, type_: dissect.cstruct.types.BaseType, values: Dict[str, int])
Bases: :py:obj:`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.
.. rubric:: Example
When using the default C-style parser, the following syntax is supported:
enum [: ] {
};
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
};
.. py:method:: __call__(value: Union[int, BinaryIO]) -> EnumInstance
.. py:method:: __getitem__(attr: str) -> EnumInstance
.. py:method:: __getattr__(attr: str) -> EnumInstance
.. py:method:: __contains__(attr: str) -> bool
.. py:method:: default() -> EnumInstance
Return a default value of this type.
.. py:method:: default_array(count: int) -> List[EnumInstance]
Return a default array of this type.
.. py:class:: EnumInstance(enum: Enum, value: int)
Implements a value instance of an Enum
.. py:property:: name
:type: str
.. py:method:: __eq__(value: Union[int, EnumInstance]) -> bool
Return self==value.
.. py:method:: __ne__(value: Union[int, EnumInstance]) -> bool
Return self!=value.
.. py:method:: __hash__() -> int
Return hash(self).
.. py:method:: __str__() -> str
Return str(self).
.. py:method:: __int__() -> int
.. py:method:: __repr__() -> str
Return repr(self).
.. py:class:: Flag(cstruct: Enum.__init__.cstruct, name: str, type_: dissect.cstruct.types.BaseType, values: Dict[str, int])
Bases: :py:obj:`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.
.. rubric:: Example
When using the default C-style parser, the following syntax is supported:
flag [: ] {
};
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
};
.. py:method:: __call__(value: Union[int, BinaryIO]) -> FlagInstance
.. py:class:: FlagInstance(enum: Enum, value: int)
Bases: :py:obj:`dissect.cstruct.types.EnumInstance`
Implements a value instance of a Flag
.. py:property:: name
:type: str
.. py:attribute:: __nonzero__
.. py:attribute:: __ror__
.. py:attribute:: __rand__
.. py:attribute:: __rxor__
.. py:method:: __bool__()
.. py:method:: __or__(other: Union[int, FlagInstance]) -> FlagInstance
.. py:method:: __and__(other: Union[int, FlagInstance]) -> FlagInstance
.. py:method:: __xor__(other: Union[int, FlagInstance]) -> FlagInstance
.. py:method:: __invert__() -> FlagInstance
.. py:method:: __str__() -> str
Return str(self).
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: decompose() -> Tuple[List[str], int]
.. py:class:: Instance(type_: dissect.cstruct.types.BaseType, values: Dict[str, Any], sizes: Dict[str, int] = None)
Holds parsed structure data.
.. py:attribute:: __slots__
:value: ('_type', '_values', '_sizes')
.. py:method:: __getattr__(attr: str) -> Any
.. py:method:: __setattr__(attr: str, value: Any) -> None
Implement setattr(self, name, value).
.. py:method:: __getitem__(item: str) -> Any
.. py:method:: __contains__(attr: str) -> bool
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: __len__() -> int
.. py:method:: __bytes__() -> bytes
.. py:method:: write(stream: BinaryIO) -> int
Write this structure to a writable file-like object.
:param fh: File-like objects that supports writing.
:returns: The amount of bytes written.
.. py:method:: dumps() -> bytes
Dump this structure to a byte string.
:returns: The raw bytes of this structure.
.. py:class:: LEB128(cstruct: LEB128.__init__.cstruct, name: str, size: int, signed: bool, alignment: int = 1)
Bases: :py:obj:`dissect.cstruct.types.base.RawType`
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.
.. py:attribute:: signed
:type: bool
.. py:method:: default() -> int
Return a default value of this type.
.. py:method:: default_array(count: int) -> list[int]
Return a default array of this type.
.. py:class:: PackedType(cstruct: PackedType.__init__.cstruct, name: str, size: int, packchar: str, alignment: int = None)
Bases: :py:obj:`dissect.cstruct.types.RawType`
Implements a packed type that uses Python struct packing characters.
.. py:method:: default() -> int
Return a default value of this type.
.. py:method:: default_array(count: int) -> List[int]
Return a default array of this type.
.. py:class:: Pointer(cstruct: Pointer.__init__.cstruct, target: dissect.cstruct.types.BaseType)
Bases: :py:obj:`dissect.cstruct.types.RawType`
Implements a pointer to some other type.
.. py:method:: __repr__() -> str
Return repr(self).
.. py:class:: 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.
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: __str__() -> str
Return str(self).
.. py:method:: __getattr__(attr: str) -> Any
.. py:method:: __int__() -> int
.. py:method:: __nonzero__() -> bool
.. py:method:: __add__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __sub__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __mul__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __floordiv__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __mod__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __pow__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __lshift__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __rshift__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __and__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __xor__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __or__(other: Union[int, PointerInstance]) -> PointerInstance
.. py:method:: __eq__(other: Union[int, PointerInstance]) -> bool
Return self==value.
.. py:method:: dereference() -> Any
.. py:class:: Field(name: str, type_: dissect.cstruct.types.BaseType, bits: int = None, offset: int = None)
Holds a structure field.
.. py:method:: __repr__()
Return repr(self).
.. py:class:: Structure(cstruct: Structure.__init__.cstruct, name: str, fields: List[Field] = None, align: bool = False, anonymous: bool = False)
Bases: :py:obj:`dissect.cstruct.types.BaseType`
Type class for structures.
.. py:method:: __len__() -> int
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: add_field(name: str, type_: dissect.cstruct.types.BaseType, bits: int = None, offset: int = None) -> None
Add a field to this structure.
:param name: The field name.
:param type_: The field type.
:param bits: The bit of the field.
:param offset: The field offset.
.. py:method:: default() -> dissect.cstruct.types.Instance
Create and return an empty Instance from this structure.
:returns: An empty Instance from this structure.
.. py:method:: show(indent: int = 0) -> None
Pretty print this structure.
.. py:class:: Union(cstruct: Structure.__init__.cstruct, name: str, fields: List[Field] = None, align: bool = False, anonymous: bool = False)
Bases: :py:obj:`Structure`
Type class for unions
.. py:method:: __repr__() -> str
Return repr(self).
.. py:method:: show(indent: int = 0) -> None
:abstractmethod:
Pretty print this structure.
.. py:class:: VoidType
Bases: :py:obj:`dissect.cstruct.types.RawType`
Implements a void type.
.. py:class:: WcharType(cstruct)
Bases: :py:obj:`dissect.cstruct.types.RawType`
Implements a wide-character type.
.. py:property:: encoding
:type: str
.. py:method:: default() -> str
Return a default value of this type.
.. py:method:: default_array(count: int) -> str
Return a default array of this type.
.. py:function:: 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.
:param obj: Structure or Instance to dump.
:param data: Bytes to parse the Structure on, if obj is not a parsed Instance.
:param offset: Byte offset of the hexdump.
:param output: Output format, can be 'print' or 'string'.
.. py:function:: hexdump(data: bytes, palette=None, offset: int = 0, prefix: str = '', output: str = 'print')
Hexdump some data.
:param data: Bytes to hexdump.
:param palette: Colorize the hexdump using this color pattern.
:param offset: Byte offset of the hexdump.
:param prefix: Optional prefix.
:param output: Output format, can be 'print', 'generator' or 'string'.
.. py:function:: p8(value: int, endian: str = 'little') -> bytes
Pack an 8 bit integer.
:param value: Value to pack.
:param endian: Endianness to use (little, big, network, <, > or !)
.. py:function:: p16(value: int, endian: str = 'little') -> bytes
Pack a 16 bit integer.
:param value: Value to pack.
:param endian: Endianness to use (little, big, network, <, > or !)
.. py:function:: p32(value: int, endian: str = 'little') -> bytes
Pack a 32 bit integer.
:param value: Value to pack.
:param endian: Endianness to use (little, big, network, <, > or !)
.. py:function:: p64(value: int, endian: str = 'little') -> bytes
Pack a 64 bit integer.
:param value: Value to pack.
:param endian: Endianness to use (little, big, network, <, > or !)
.. py:function:: pack(value: int, size: int = None, endian: str = 'little') -> bytes
Pack an integer value to a given bit size, endianness.
:param value: Value to pack.
:param size: Integer size in bits.
:param endian: Endianness to use (little, big, network, <, > or !)
.. py:function:: swap(value: int, size: int)
Swap the endianness of an integer with a given bit size.
:param value: Integer to swap.
:param size: Integer size in bits.
.. py:function:: swap16(value: int) -> int
Swap the endianness of a 16 bit integer.
:param value: Integer to swap.
.. py:function:: swap32(value: int) -> int
Swap the endianness of a 32 bit integer.
:param value: Integer to swap.
.. py:function:: swap64(value: int) -> int
Swap the endianness of a 64 bit integer.
:param value: Integer to swap.
.. py:function:: u8(value: bytes, endian: str = 'little', sign: bool = False) -> int
Unpack an 8 bit integer.
:param value: Value to unpack.
:param endian: Endianness to use (little, big, network, <, > or !)
:param sign: Signedness of the integer.
.. py:function:: u16(value: bytes, endian: str = 'little', sign: bool = False) -> int
Unpack a 16 bit integer.
:param value: Value to unpack.
:param endian: Endianness to use (little, big, network, <, > or !)
:param sign: Signedness of the integer.
.. py:function:: u32(value: bytes, endian: str = 'little', sign: bool = False) -> int
Unpack a 32 bit integer.
:param value: Value to unpack.
:param endian: Endianness to use (little, big, network, <, > or !)
:param sign: Signedness of the integer.
.. py:function:: u64(value: bytes, endian: str = 'little', sign: bool = False) -> int
Unpack a 64 bit integer.
:param value: Value to unpack.
:param endian: Endianness to use (little, big, network, <, > or !)
:param sign: Signedness of the integer.
.. py:function:: 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.
:param value: Value to unpack.
:param size: Integer size in bits.
:param endian: Endianness to use (little, big, network, <, > or !)
:param sign: Signedness of the integer.