Dissect Cstruct
dissect-cstruct is a Python library from the Dissect project designed for parsing C-like structures from binary data. It allows users to define structures using Python classes or C-like syntax and then parse byte streams into accessible Python objects. The current version is 4.7, and it is actively maintained with a regular release cadence.
Common errors
-
ModuleNotFoundError: No module named 'cstruct'
cause Attempting to import `cstruct` directly instead of from its location within the `dissect` package.fixUse the correct import path: `from dissect.cstruct import cstruct`. -
TypeError: 'str' object cannot be interpreted as a byte-like object
cause Passing a Python string to a `cstruct` type constructor (e.g., `ctx.MyStruct('some string')`) which expects bytes for parsing.fixEnsure the input data is a `bytes` object. For example, use a byte literal (`b'some string'`) or encode a string (`'some string'.encode('ascii')`). -
AttributeError: type object 'Instance' has no attribute 'X'
cause This often occurs when migrating from `dissect-cstruct` versions older than 4.0.0, where the `Instance` class was moved.fixUpdate your import statement for `Instance` from `from dissect.cstruct import Instance` to `from dissect.cstruct.types import Instance`.
Warnings
- breaking The `Instance` class was renamed from `dissect.cstruct.Instance` to `dissect.cstruct.types.Instance`.
- breaking The `Structure` and `Array` classes (e.g., used for type hints) now inherit from `typing.Generic` and are parameterized. They can no longer be used as bare types in a `cstruct` definition without proper parameterization.
- breaking `dissect-cstruct` dropped support for Python 3.7 and 3.8.
- gotcha The `cstruct` parsing functions (e.g., `ctx.MyStruct(data)`) expect a bytes-like object (e.g., `bytes` or `bytearray`) for input. Passing a `str` will result in a `TypeError`.
Install
-
pip install dissect-cstruct
Imports
- cstruct
import cstruct
from dissect.cstruct import cstruct
Quickstart
from dissect.cstruct import cstruct
import struct
# Initialize a cstruct context
ctx = cstruct()
# Define a C-like structure using a multiline string
ctx.typedef(
"""
struct Header {
uint32_t magic;
uint16_t version;
char name[10];
};
"""
)
# Example binary data conforming to the structure
# magic = 0xDEADBEEF (little endian)
# version = 0x0100 (little endian)
# name = "TestHeader" (10 chars)
# Use struct.pack to ensure correct byte ordering for the example
example_data = struct.pack("<I H 10s", 0xDEADBEEF, 0x0100, b"TestHeader")
# Parse the data using the defined structure
parsed_header = ctx.Header(example_data)
# Access fields of the parsed structure
print(f"Magic: {hex(parsed_header.magic)}")
print(f"Version: {parsed_header.version}")
print(f"Name: {parsed_header.name.decode('ascii')}")
# Assertions to verify correct parsing
assert parsed_header.magic == 0xDEADBEEF
assert parsed_header.version == 0x0100
assert parsed_header.name == b"TestHeader"
print("Structure parsed successfully!")