Skip to content
All tools
Binary exploitationRuns locallyNo account

Struct pack and unpack (p32, p64, u32, u64)

Convert integers to little-endian byte strings and back at 8, 16, 32, and 64 bits - the pwntools p32/p64 helpers without the install.

Open in ctfpal

Every exploit payload is a sequence of addresses and integers laid out in memory order. Packing is the conversion from the number you reasoned about to the bytes that go in the buffer, and unpacking is the reverse for leaks you read back.

It is worth having as a dedicated step rather than doing in your head, because the two directions fail differently. A packing mistake produces a payload that jumps somewhere absurd; an unpacking mistake produces an address you then build an entire chain around. The second is much more expensive, and much harder to notice.

The 64-bit detail that trips people

x86-64 addresses are 64-bit but user-space addresses only use the low 48 bits, so a packed address ends in two null bytes. Those nulls terminate C strings - which is why a strcpy-based overflow cannot write a full 64-bit address, and why the address goes last in the payload when it goes anywhere at all.

>>> p64(0x401196)
b'\x96\x11\x40\x00\x00\x00\x00\x00'   # note the trailing nulls

>>> u64(b'\x60\xf7\xd4\xf7\xff\x7f\x00\x00')
0x7ffff7d4f760                        # a leaked libc pointer
What packing produces

Go deeper

Related tools