pwnlib.util.packing
— Packing and unpacking of strings¶
Module for packing and unpacking integers.
Simplifies access to the standard struct.pack
and struct.unpack
functions, and also adds support for packing/unpacking arbitrary-width
integers.
The packers are all context-aware for endian
and signed
arguments,
though they can be overridden in the parameters.
Examples
>>> p8(0)
'\x00'
>>> p32(0xdeadbeef)
'\xef\xbe\xad\xde'
>>> p32(0xdeadbeef, endian='big')
'\xde\xad\xbe\xef'
>>> with context.local(endian='big'): p32(0xdeadbeef)
'\xde\xad\xbe\xef'
Make a frozen packer, which does not change with context.
>>> p=make_packer('all')
>>> p(0xff)
'\xff'
>>> p(0x1ff)
'\xff\x01'
>>> with context.local(endian='big'): print repr(p(0x1ff))
'\xff\x01'
-
pwnlib.util.packing.
dd
(dst, src, count = 0, skip = 0, seek = 0, truncate = False) → dst[源代码]¶ Inspired by the command line tool
dd
, this function copies count byte values from offset seek in src to offset skip in dst. If count is 0, all ofsrc[seek:]
is copied.If dst is a mutable type it will be updated. Otherwise a new instance of the same type will be created. In either case the result is returned.
src can be an iterable of characters or integers, a unicode string or a file object. If it is an iterable of integers, each integer must be in the range [0;255]. If it is a unicode string, its UTF-8 encoding will be used.
The seek offset of file objects will be preserved.
参数: - dst – Supported types are :class:file, :class:list, :class:tuple, :class:str, :class:bytearray and :class:unicode.
- src – An iterable of byte values (characters or integers), a unicode string or a file object.
- count (int) – How many bytes to copy. If count is 0 or larger than
len(src[seek:])
, all bytes until the end of src are copied. - skip (int) – Offset in dst to copy to.
- seek (int) – Offset in src to copy from.
- truncate (bool) – If :const:True, dst is truncated at the last copied byte.
返回: A modified version of dst. If dst is a mutable type it will be modified in-place.
Examples
>>> dd(tuple('Hello!'), '?', skip = 5) ('H', 'e', 'l', 'l', 'o', '?') >>> dd(list('Hello!'), (63,), skip = 5) ['H', 'e', 'l', 'l', 'o', '?'] >>> file('/tmp/foo', 'w').write('A' * 10) >>> dd(file('/tmp/foo'), file('/dev/zero'), skip = 3, count = 4).read() 'AAA\x00\x00\x00\x00AAA' >>> file('/tmp/foo', 'w').write('A' * 10) >>> dd(file('/tmp/foo'), file('/dev/zero'), skip = 3, count = 4, truncate = True).read() 'AAA\x00\x00\x00\x00'
-
pwnlib.util.packing.
fit
(pieces, filler = de_bruijn(), length = None, preprocessor = None) → str[源代码]¶ Generates a string from a dictionary mapping offsets to data to place at that offset.
For each key-value pair in pieces, the key is either an offset or a byte sequence. In the latter case, the offset will be the lowest index at which the sequence occurs in filler. See examples below.
Each piece of data is passed to
flat()
along with the keyword arguments word_size, endianness and sign.Space between pieces of data is filled out using the iterable filler. The n’th byte in the output will be byte at index
n % len(iterable)
byte in filler if it has finite length or the byte at index n otherwise.If length is given, the output will padded with bytes from filler to be this size. If the output is longer than length, a
ValueError
exception is raised.If entries in pieces overlap, a
ValueError
exception is raised.参数: - pieces – Offsets and values to output.
- length – The length of the output.
- filler – Iterable to use for padding.
- preprocessor (function) – Gets called on every element to optionally
transform the element before flattening. If
None
is returned, then the original value is used. - word_size (int) – Word size of the converted integer.
- endianness (str) – Endianness of the converted integer (“little”/”big”).
- sign (str) – Signedness of the converted integer (False/True)
Examples
>>> fit({12: 0x41414141, ... 24: 'Hello', ... }) 'aaaabaaacaaaAAAAeaaafaaaHello' >>> fit({'caaa': ''}) 'aaaabaaa' >>> fit({12: 'XXXX'}, filler = 'AB', length = 20) 'ABABABABABABXXXXABAB' >>> fit({ 8: [0x41414141, 0x42424242], ... 20: 'CCCC'}) 'aaaabaaaAAAABBBBeaaaCCCC' >>> fit({ 0x61616162: 'X'}) 'aaaaX'
-
pwnlib.util.packing.
flat
(*args, preprocessor = None, word_size = None, endianness = None, sign = None)[源代码]¶ Flattens the arguments into a string.
This function takes an arbitrary number of arbitrarily nested lists and tuples. It will then find every string and number inside those and flatten them out. Strings are inserted directly while numbers are packed using the
pack()
function.The three kwargs word_size, endianness and sign will default to using values in
pwnlib.context
if not specified as an argument.参数: - args – Values to flatten
- preprocessor (function) – Gets called on every element to optionally
transform the element before flattening. If
None
is returned, then the original value is uded. - word_size (int) – Word size of the converted integer.
- endianness (str) – Endianness of the converted integer (“little”/”big”).
- sign (str) – Signedness of the converted integer (False/True)
Examples
>>> flat(1, "test", [[["AB"]*2]*3], endianness = 'little', word_size = 16, sign = False) '\x01\x00testABABABABABAB' >>> flat([1, [2, 3]], preprocessor = lambda x: str(x+1)) '234'
-
pwnlib.util.packing.
make_packer
(word_size = None, endianness = None, sign = None) → number → str[源代码]¶ Creates a packer by “freezing” the given arguments.
Semantically calling
make_packer(w, e, s)(data)
is equivalent to callingpack(data, w, e, s)
. If word_size is one of 8, 16, 32 or 64, it is however faster to call this function, since it will then use a specialized version.参数: - word_size (int) – The word size to be baked into the returned packer or the string all.
- endianness (str) – The endianness to be baked into the returned packer. (“little”/”big”)
- sign (str) – The signness to be baked into the returned packer. (“unsigned”/”signed”)
- kwargs – Additional context flags, for setting by alias (e.g.
endian=
rather than index)
返回: A function, which takes a single argument in the form of a number and returns a string of that number in a packed form.
Examples
>>> p = make_packer(32, endian='little', sign='unsigned') >>> p <function _p32lu at 0x...> >>> p(42) '*\x00\x00\x00' >>> p(-1) Traceback (most recent call last): ... error: integer out of range for 'I' format code >>> make_packer(33, endian='little', sign='unsigned') <function <lambda> at 0x...>
-
pwnlib.util.packing.
make_unpacker
(word_size = None, endianness = None, sign = None, **kwargs) → str → number[源代码]¶ Creates a unpacker by “freezing” the given arguments.
Semantically calling
make_unpacker(w, e, s)(data)
is equivalent to callingunpack(data, w, e, s)
. If word_size is one of 8, 16, 32 or 64, it is however faster to call this function, since it will then use a specialized version.参数: - word_size (int) – The word size to be baked into the returned packer.
- endianness (str) – The endianness to be baked into the returned packer. (“little”/”big”)
- sign (str) – The signness to be baked into the returned packer. (“unsigned”/”signed”)
- kwargs – Additional context flags, for setting by alias (e.g.
endian=
rather than index)
返回: A function, which takes a single argument in the form of a string and returns a number of that string in an unpacked form.
Examples
>>> u = make_unpacker(32, endian='little', sign='unsigned') >>> u <function _u32lu at 0x...> >>> hex(u('/bin')) '0x6e69622f' >>> u('abcde') Traceback (most recent call last): ... error: unpack requires a string argument of length 4 >>> make_unpacker(33, endian='little', sign='unsigned') <function <lambda> at 0x...>
-
pwnlib.util.packing.
p16
(number, sign, endian, ...) → str[源代码]¶ Packs an 16-bit integer
参数: 返回: The packed number as a string
-
pwnlib.util.packing.
p32
(number, sign, endian, ...) → str[源代码]¶ Packs an 32-bit integer
参数: 返回: The packed number as a string
-
pwnlib.util.packing.
p64
(number, sign, endian, ...) → str[源代码]¶ Packs an 64-bit integer
参数: 返回: The packed number as a string
-
pwnlib.util.packing.
p8
(number, sign, endian, ...) → str[源代码]¶ Packs an 8-bit integer
参数: 返回: The packed number as a string
-
pwnlib.util.packing.
pack
(number, word_size = None, endianness = None, sign = None, **kwargs) → str[源代码]¶ Packs arbitrary-sized integer.
Word-size, endianness and signedness is done according to context.
word_size can be any positive number or the string “all”. Choosing the string “all” will output a string long enough to contain all the significant bits and thus be decodable by
unpack()
.word_size can be any positive number. The output will contain word_size/8 rounded up number of bytes. If word_size is not a multiple of 8, it will be padded with zeroes up to a byte boundary.
参数: 返回: The packed number as a string.
Examples
>>> pack(0x414243, 24, 'big', True) 'ABC' >>> pack(0x414243, 24, 'little', True) 'CBA' >>> pack(0x814243, 24, 'big', False) '\x81BC' >>> pack(0x814243, 24, 'big', True) Traceback (most recent call last): ... ValueError: pack(): number does not fit within word_size >>> pack(0x814243, 25, 'big', True) '\x00\x81BC' >>> pack(-1, 'all', 'little', True) '\xff' >>> pack(-256, 'all', 'big', True) '\xff\x00' >>> pack(0x0102030405, 'all', 'little', True) '\x05\x04\x03\x02\x01' >>> pack(-1) '\xff\xff\xff\xff' >>> pack(0x80000000, 'all', 'big', True) '\x00\x80\x00\x00\x00'
-
pwnlib.util.packing.
routine
(*a, **kw)[源代码]¶ u32(number, sign, endian, …) -> int
Unpacks an 32-bit integer
参数: 返回: The unpacked number
-
pwnlib.util.packing.
u16
(number, sign, endian, ...) → int[源代码]¶ Unpacks an 16-bit integer
参数: 返回: The unpacked number
-
pwnlib.util.packing.
u32
(number, sign, endian, ...) → int[源代码]¶ Unpacks an 32-bit integer
参数: 返回: The unpacked number
-
pwnlib.util.packing.
u64
(number, sign, endian, ...) → int[源代码]¶ Unpacks an 64-bit integer
参数: 返回: The unpacked number
-
pwnlib.util.packing.
u8
(number, sign, endian, ...) → int[源代码]¶ Unpacks an 8-bit integer
参数: 返回: The unpacked number
-
pwnlib.util.packing.
unpack
(data, word_size = None, endianness = None, sign = None, **kwargs) → int[源代码]¶ Packs arbitrary-sized integer.
Word-size, endianness and signedness is done according to context.
word_size can be any positive number or the string “all”. Choosing the string “all” is equivalent to
len(data)*8
.If word_size is not a multiple of 8, then the bits used for padding are discarded.
参数: 返回: The unpacked number.
Examples
>>> hex(unpack('\xaa\x55', 16, endian='little', sign=False)) '0x55aa' >>> hex(unpack('\xaa\x55', 16, endian='big', sign=False)) '0xaa55' >>> hex(unpack('\xaa\x55', 16, endian='big', sign=True)) '-0x55ab' >>> hex(unpack('\xaa\x55', 15, endian='big', sign=True)) '0x2a55' >>> hex(unpack('\xff\x02\x03', 'all', endian='little', sign=True)) '0x302ff' >>> hex(unpack('\xff\x02\x03', 'all', endian='big', sign=True)) '-0xfdfd'
-
pwnlib.util.packing.
unpack_many
(*a, **kw)[源代码]¶ unpack(data, word_size = None, endianness = None, sign = None) -> int list
Splits data into groups of
word_size//8
bytes and callsunpack()
on each group. Returns a list of the results.word_size must be a multiple of 8 or the string “all”. In the latter case a singleton list will always be returned.
- Args
- number (int): String to convert word_size (int): Word size of the converted integers or the string “all”. endianness (str): Endianness of the converted integer (“little”/”big”) sign (str): Signedness of the converted integer (False/True) kwargs: Anything that can be passed to context.local
返回: The unpacked numbers. Examples
>>> map(hex, unpack_many('\xaa\x55\xcc\x33', 16, endian='little', sign=False)) ['0x55aa', '0x33cc'] >>> map(hex, unpack_many('\xaa\x55\xcc\x33', 16, endian='big', sign=False)) ['0xaa55', '0xcc33'] >>> map(hex, unpack_many('\xaa\x55\xcc\x33', 16, endian='big', sign=True)) ['-0x55ab', '-0x33cd'] >>> map(hex, unpack_many('\xff\x02\x03', 'all', endian='little', sign=True)) ['0x302ff'] >>> map(hex, unpack_many('\xff\x02\x03', 'all', endian='big', sign=True)) ['-0xfdfd']