Skip to content

Structure — Binary DSL

Back to the Technology Index

Almost every Windows protocol PDU is a subclass of impacket.structure.Structure. Fixed layouts outside ASN.1 / NDR, including SMB, NTLM, DPAPI, parts of PAC, TDS, and registry hives, are handled here.

It raises struct.pack / unpack to ordered field declarations. Field order is wire order. A dictionary cannot be used to declare it.

A subclass has these two class attributes:

AttributeMeaning
commonHdrLeading fields shared with the parent; used for inheritance
structureBody fields; redefining it in a subclass replaces the parent’s structure

Each field is (name, format) or (name, format, third). third is a nested class for a : field or a string evaluated during unpacking for a _ field.

class Example(Structure):
structure = (
('Magic', '"SMB'),
('Count', '<H-Data'),
('Data', ':'),
)
  • getData() packs commonHdr + structure in order and, if alignment is set, pads after each field.
  • fromString(data) unpacks in the same order and advances the buffer by the packed size plus alignment.
  • __setitem__ invalidates the self.data cache; the next getData() recalculates it.

The default encoding is ENCODING = 'latin-1'.

SpecifierMeaning
struct codes (<H, !L, 16s, etc.)One value per field; do not combine several values as in 'Hl'
:Raw bytes, a nested Structure, or an object with getData(). Without an explicit length, consumes the rest
zASCIIZ
uUTF-16LE, terminated by \x00\x00 on an even boundary
wNDR string macro (MaxCount, Offset, ActualCount, data)
'xxxx / "xxxxLiteral; must also match when unpacking
?-fieldLength of a named field, for example '<H-Data'
?1*?2Array; ?1 gives the count (which may be constant), or consumes the rest if ?1 is empty
_Not packed; evaluates the third argument during unpacking if present
?=pythonPacks the result of evaluating Python in the field context
?&fieldnameOptional pointer; if zero, skips the target field
%...printf-style; pack only, cannot unpack

A length specifier using '-field' is the standard way to safely delimit a variable-length : field. SMB2’s SMB2SessionSetup does the same with _ and SecurityBufferLength.

There is no helper to merge fields. To retain the parent layout, put shared fields in commonHdr and add only the child’s fields in structure. Nesting uses ('inner', ':', InnerClass).

In SMB1, AsciiOrUnicodeStructure (smb.py) selects UnicodeStructure or AsciiStructure according to FLAGS2_UNICODE.

  • Field order is wire order. Inserting a field in the middle breaks backward compatibility.
  • Without a length field, : consumes the rest.
  • The terminator for u must be on an even offset.
  • A default such as '<L=0' is evaluated during packing; it is not a constructor default.
  • alignment applies per field and is separate from NDR alignment rules.

Use NDR for protocol-specific arrays, pointers, and conformant structures. Do not use Structure in place of an NDR CALL.