Python struct Module Quick Reference
====================================

IMPORT
  import struct

PACK (Python → bytes)
  struct.pack("<I", 0x41414141)    Little-endian uint32
  struct.pack(">I", 0x41414141)    Big-endian uint32
  struct.pack("<Q", addr)          Little-endian uint64
  struct.pack("<HH", 0x1234, 0x5678)  Two uint16

UNPACK (bytes → Python)
  struct.unpack("<I", data)        → (value,)  tuple
  struct.unpack("<II", data)       → (val1, val2)
  val = struct.unpack("<I", data)[0]  Single value

FORMAT CHARACTERS
  Byte order:
    <         Little-endian
    >         Big-endian
    !         Network (big-endian)
    =         Native

  Types:
    b / B     int8 / uint8      (1 byte)
    h / H     int16 / uint16    (2 bytes)
    i / I     int32 / uint32    (4 bytes)
    l / L     int32 / uint32    (4 bytes)
    q / Q     int64 / uint64    (8 bytes)
    f         float             (4 bytes)
    d         double            (8 bytes)
    s         char[]            (N bytes)
    x         padding           (1 byte)

SIZE
  struct.calcsize("<IHH")         Calculate packed size

COMMON CTF PATTERNS
  # Read binary header
  with open("file", "rb") as f:
      magic = struct.unpack("<I", f.read(4))[0]
      size = struct.unpack("<H", f.read(2))[0]

  # Parse ELF header fields
  data = open("binary", "rb").read()
  e_entry = struct.unpack("<Q", data[0x18:0x20])[0]

  # Build payload with addresses
  payload = b""
  payload += struct.pack("<Q", 0x400000)   # return addr
  payload += struct.pack("<Q", 0x601020)   # GOT entry

  # Unpack multiple values
  fields = struct.unpack("<IIHH", data[:12])
  id, flags, type, size = fields

  # Iterate over array of structs
  ENTRY_SIZE = struct.calcsize("<IIQ")
  for i in range(0, len(data), ENTRY_SIZE):
      a, b, c = struct.unpack("<IIQ", data[i:i+ENTRY_SIZE])
