pwnlib.util.fiddling — Utilities bit fiddling

pwnlib.util.fiddling.b64d(s) → str[source]

Base64 decodes a string

Example

>>> b64d('dGVzdA==')
'test'
pwnlib.util.fiddling.b64e(s) → str[source]

Base64 encodes a string

Example

>>> b64e("test")
'dGVzdA=='
pwnlib.util.fiddling.bits(s, endian = 'big', zero = 0, one = 1) → list[source]

Converts the argument a list of bits.

Parameters:
  • s – A string or number to be converted into bits.
  • endian (str) – The binary endian, default ‘big’.
  • zero – The representing a 0-bit.
  • one – The representing a 1-bit.
Returns:

A list consisting of the values specified in zero and one.

Examples

>>> bits(511, zero = "+", one = "-")
['+', '+', '+', '+', '+', '+', '+', '-', '-', '-', '-', '-', '-', '-', '-', '-']
>>> sum(bits("test"))
17
>>> bits(0)
[0, 0, 0, 0, 0, 0, 0, 0]
pwnlib.util.fiddling.bits_str(s, endian = 'big', zero = '0', one = '1') → str[source]

A wrapper around bits(), which converts the output into a string.

Examples

>>> bits_str(511)
'0000000111111111'
>>> bits_str("bits_str", endian = "little")
'0100011010010110001011101100111011111010110011100010111001001110'
pwnlib.util.fiddling.bitswap(s) → str[source]

Reverses the bits in every byte of a given string.

Example

>>> bitswap("1234")
'\x8cL\xcc,'
pwnlib.util.fiddling.bitswap_int(n) → int[source]

Reverses the bits of a numbers and returns the result as a new number.

Parameters:
  • n (int) – The number to swap.
  • width (int) – The width of the integer

Examples

>>> hex(bitswap_int(0x1234, 8))
'0x2c'
>>> hex(bitswap_int(0x1234, 16))
'0x2c48'
>>> hex(bitswap_int(0x1234, 24))
'0x2c4800'
>>> hex(bitswap_int(0x1234, 25))
'0x589000'
pwnlib.util.fiddling.bnot(value, width=None)[source]

Returns the binary inverse of ‘value’.

pwnlib.util.fiddling.enhex(x) → str[source]

Hex-encodes a string.

Example

>>> enhex("test")
'74657374'
pwnlib.util.fiddling.hexdump_iter(s, width=16, skip=True, hexii=False, begin=0, style=None, highlight=None, cyclic=False)[source]
hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
style = {}, highlight = []) -> str generator

Return a hexdump-dump of a string as a generator of lines.

Parameters:
  • s (str) – The string to dump
  • width (int) – The number of characters per line
  • skip (bool) – Set to True, if repeated lines should be replaced by a “*”
  • hexii (bool) – Set to True, if a hexii-dump should be returned instead of a hexdump.
  • begin (int) – Offset of the first byte to print in the left column
  • style (dict) – Color scheme to use.
  • highlight (iterable) – Byte values to highlight.
  • cyclic (bool) – Attempt to skip consecutive, unmodified cyclic lines
Returns:

A hexdump-dump in the form of a string.

pwnlib.util.fiddling.hexii(s, width = 16, skip = True) → str[source]

Return a HEXII-dump of a string.

Parameters:
  • s (str) – The string to dump
  • width (int) – The number of characters per line
  • skip (bool) – Should repeated lines be replaced by a “*”
Returns:

A HEXII-dump in the form of a string.

pwnlib.util.fiddling.isprint(c) → bool[source]

Return True if a character is printable

pwnlib.util.fiddling.naf(int) → int generator[source]

Returns a generator for the non-adjacent form (NAF[1]) of a number, n. If naf(n) generates z_0, z_1, ..., then n == z_0 + z_1 * 2 + z_2 * 2**2, ....

[1] https://en.wikipedia.org/wiki/Non-adjacent_form

Example

>>> n = 45
>>> m = 0
>>> x = 1
>>> for z in naf(n):
...     m += x * z
...     x *= 2
>>> n == m
True
pwnlib.util.fiddling.negate(value, width=None)[source]

Returns the two’s complement of ‘value’.

pwnlib.util.fiddling.randoms(count, alphabet = string.lowercase) → str[source]

Returns a random string of a given length using only the specified alphabet.

Parameters:
  • count (int) – The length of the desired string.
  • alphabet – The alphabet of allowed characters. Defaults to all lowercase characters.
Returns:

A random string.

Example

>>> randoms(10) 
'evafjilupm'
pwnlib.util.fiddling.rol(n, k, word_size=None)[source]

Returns a rotation by k of n.

When n is a number, then means ((n << k) | (n >> (word_size - k))) truncated to word_size bits.

When n is a list, tuple or string, this is n[k % len(n):] + n[:k % len(n)].

Parameters:
  • n – The value to rotate.
  • k (int) – The rotation amount. Can be a positive or negative number.
  • word_size (int) – If n is a number, then this is the assumed bitsize of n. Defaults to pwnlib.context.word_size if None .

Example

>>> rol('abcdefg', 2)
'cdefgab'
>>> rol('abcdefg', -2)
'fgabcde'
>>> hex(rol(0x86, 3, 8))
'0x34'
>>> hex(rol(0x86, -3, 8))
'0xd0'
pwnlib.util.fiddling.ror(n, k, word_size=None)[source]

A simple wrapper around rol(), which negates the values of k.

pwnlib.util.fiddling.unbits(s, endian = 'big') → str[source]

Converts an iterable of bits into a string.

Parameters:
  • s – Iterable of bits
  • endian (str) – The string “little” or “big”, which specifies the bits endianness.
Returns:

A string of the decoded bits.

Example

>>> unbits([1])
'\x80'
>>> unbits([1], endian = 'little')
'\x01'
>>> unbits(bits('hello'), endian = 'little')
'\x16\xa666\xf6'
pwnlib.util.fiddling.unhex(s) → str[source]

Hex-decodes a string.

Example

>>> unhex("74657374")
'test'
>>> unhex("F\n")
'\x0f'
pwnlib.util.fiddling.urldecode(s, ignore_invalid = False) → str[source]

URL-decodes a string.

Example

>>> urldecode("test%20%41")
'test A'
>>> urldecode("%qq")
Traceback (most recent call last):
...
ValueError: Invalid input to urldecode
>>> urldecode("%qq", ignore_invalid = True)
'%qq'
pwnlib.util.fiddling.urlencode(s) → str[source]

URL-encodes a string.

Example

>>> urlencode("test")
'%74%65%73%74'
pwnlib.util.fiddling.xor(*args, cut = 'max') → str[source]

Flattens its arguments using pwnlib.util.packing.flat() and then xors them together. If the end of a string is reached, it wraps around in the string.

Parameters:
  • args – The arguments to be xor’ed together.
  • cut – How long a string should be returned. Can be either ‘min’/’max’/’left’/’right’ or a number.
Returns:

The string of the arguments xor’ed together.

Example

>>> xor('lol', 'hello', 42)
'. ***'
pwnlib.util.fiddling.xor_key(data, size=None, avoid='x00n') -> None or (int, str)[source]

Finds a size-width value that can be XORed with a string to produce data, while neither the XOR value or XOR string contain any bytes in avoid.

Parameters:
  • data (str) – The desired string.
  • avoid – The list of disallowed characters. Defaults to nulls and newlines.
  • size (int) – Size of the desired output value, default is word size.
Returns:

A tuple containing two strings; the XOR key and the XOR string. If no such pair exists, None is returned.

Example

>>> xor_key("Hello, world")
('\x01\x01\x01\x01', 'Idmmn-!vnsme')
pwnlib.util.fiddling.xor_pair(data, avoid = 'x00n') -> None or (str, str)[source]

Finds two strings that will xor into a given string, while only using a given alphabet.

Parameters:
  • data (str) – The desired string.
  • avoid – The list of disallowed characters. Defaults to nulls and newlines.
Returns:

Two strings which will xor to the given string. If no such two strings exist, then None is returned.

Example

>>> xor_pair("test")
('\x01\x01\x01\x01', 'udru')