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