pwnlib.util.misc — We could not fit it any other place

pwnlib.util.misc.align(alignment, x) → int[source]

Rounds x up to nearest multiple of the alignment.


>>> [align(5, n) for n in range(15)]
[0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 15, 15, 15, 15]
pwnlib.util.misc.align_down(alignment, x) → int[source]

Rounds x down to nearest multiple of the alignment.


>>> [align_down(5, n) for n in range(15)]
[0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10]
pwnlib.util.misc.binary_ip(host) → str[source]

Resolve host and return IP as four byte string.


>>> binary_ip("")

Given a tube which is a shell, dealarm it.


Emulates the behavior of mkdir -p.


Parses the output from a run of ‘ldd’ on a binary. Returns a dictionary of {path: address} for each library required by the specified binary.

Parameters:output (str) – The output to parse


>>> sorted(parse_ldd_output('''
... =>  (0x00007fffbf5fe000)
... => /lib/x86_64-linux-gnu/ (0x00007fe28117f000)
... => /lib/x86_64-linux-gnu/ (0x00007fe280f7b000)
... => /lib/x86_64-linux-gnu/ (0x00007fe280bb4000)
...     /lib64/ (0x00007fe2813dd000)
... ''').keys())
['/lib/x86_64-linux-gnu/', '/lib/x86_64-linux-gnu/', '/lib/x86_64-linux-gnu/', '/lib64/'], count=-1, skip=0) → str[source]

Open file, return content.


>>> read('/proc/self/exe')[:4]
pwnlib.util.misc.register_sizes(regs, in_sizes)[source]

Create dictionaries over register sizes and relations

Given a list of lists of overlapping register names (e.g. [‘eax’,’ax’,’al’,’ah’]) and a list of input sizes, it returns the following:

  • all_regs : list of all valid registers
  • sizes[reg] : the size of reg in bits
  • bigger[reg] : list of overlapping registers bigger than reg
  • smaller[reg]: list of overlapping registers smaller than reg

Used in i386/AMD64 shellcode, e.g. the mov-shellcode.


>>> regs = [['eax', 'ax', 'al', 'ah'],['ebx', 'bx', 'bl', 'bh'],
... ['ecx', 'cx', 'cl', 'ch'],
... ['edx', 'dx', 'dl', 'dh'],
... ['edi', 'di'],
... ['esi', 'si'],
... ['ebp', 'bp'],
... ['esp', 'sp'],
... ]
>>> all_regs, sizes, bigger, smaller = register_sizes(regs, [32, 16, 8, 8])
>>> all_regs
['eax', 'ax', 'al', 'ah', 'ebx', 'bx', 'bl', 'bh', 'ecx', 'cx', 'cl', 'ch', 'edx', 'dx', 'dl', 'dh', 'edi', 'di', 'esi', 'si', 'ebp', 'bp', 'esp', 'sp']
>>> sizes
{'ch': 8, 'cl': 8, 'ah': 8, 'edi': 32, 'al': 8, 'cx': 16, 'ebp': 32, 'ax': 16, 'edx': 32, 'ebx': 32, 'esp': 32, 'esi': 32, 'dl': 8, 'dh': 8, 'di': 16, 'bl': 8, 'bh': 8, 'eax': 32, 'bp': 16, 'dx': 16, 'bx': 16, 'ecx': 32, 'sp': 16, 'si': 16}
>>> bigger
{'ch': ['ecx', 'cx', 'ch'], 'cl': ['ecx', 'cx', 'cl'], 'ah': ['eax', 'ax', 'ah'], 'edi': ['edi'], 'al': ['eax', 'ax', 'al'], 'cx': ['ecx', 'cx'], 'ebp': ['ebp'], 'ax': ['eax', 'ax'], 'edx': ['edx'], 'ebx': ['ebx'], 'esp': ['esp'], 'esi': ['esi'], 'dl': ['edx', 'dx', 'dl'], 'dh': ['edx', 'dx', 'dh'], 'di': ['edi', 'di'], 'bl': ['ebx', 'bx', 'bl'], 'bh': ['ebx', 'bx', 'bh'], 'eax': ['eax'], 'bp': ['ebp', 'bp'], 'dx': ['edx', 'dx'], 'bx': ['ebx', 'bx'], 'ecx': ['ecx'], 'sp': ['esp', 'sp'], 'si': ['esi', 'si']}
>>> smaller
{'ch': [], 'cl': [], 'ah': [], 'edi': ['di'], 'al': [], 'cx': ['cl', 'ch'], 'ebp': ['bp'], 'ax': ['al', 'ah'], 'edx': ['dx', 'dl', 'dh'], 'ebx': ['bx', 'bl', 'bh'], 'esp': ['sp'], 'esi': ['si'], 'dl': [], 'dh': [], 'di': [], 'bl': [], 'bh': [], 'eax': ['ax', 'al', 'ah'], 'bp': [], 'dx': ['dl', 'dh'], 'bx': ['bl', 'bh'], 'ecx': ['cx', 'cl', 'ch'], 'sp': [], 'si': []}
pwnlib.util.misc.run_in_new_terminal(command, terminal = None) → None[source]

Run a command in a new terminal.

When terminal is not set:
  • If context.terminal is set it will be used. If it is an iterable then context.terminal[1:] are default arguments.
  • If X11 is detected (by the presence of the DISPLAY environment variable), x-terminal-emulator is used.
  • If tmux is detected (by the presence of the TMUX environment variable), a new pane will be opened.
  • command (str) – The command to run.
  • terminal (str) – Which terminal to use.
  • args (list) – Arguments to pass to the terminal


pwnlib.util.misc.sh_command_with(f, arg0, ..., argN) → command[source]

Returns a command create by evaluating f(new_arg0, ..., new_argN) whenever f is a function and f % (new_arg0, ..., new_argN) otherwise.

If the arguments are purely alphanumeric, then they are simply passed to function. If they are simple to escape, they will be escaped and passed to the function.

If the arguments contain trailing newlines, then it is hard to use them directly because of a limitation in the posix shell. In this case the output from f is prepended with a bit of code to create the variables.


>>> print sh_command_with(lambda: "echo hello")
echo hello
>>> print sh_command_with(lambda x: "echo " + x, "hello")
echo hello
>>> print sh_command_with(lambda x: "echo " + x, "\x01")
echo "$(printf '\001')"
>>> import random
>>> random.seed(1)
>>> print sh_command_with(lambda x: "echo " + x, "\x01\n")
dwtgmlqu="$(printf '\001\nx')";dwtgmlqu=${dwtgmlqu%x};echo "$dwtgmlqu"
>>> random.seed(1)
>>> print sh_command_with("echo %s", "\x01\n")
dwtgmlqu="$(printf '\001\nx')";dwtgmlqu=${dwtgmlqu%x};echo "$dwtgmlqu"
pwnlib.util.misc.sh_prepare(variables, export=False)[source]

Outputs a posix compliant shell command that will put the data specified by the dictionary into the environment.

It is assumed that the keys in the dictionary are valid variable names that does not need any escaping.

  • variables (dict) – The variables to set.
  • export (bool) – Should the variables be exported or only stored in the shell environment?
  • output (str) – A valid posix shell command that will set the given variables.

It is assumed that var is a valid name for a variable in the shell.


>>> print sh_prepare({'X': 'foobar'})
>>> r = sh_prepare({'X': 'foobar', 'Y': 'cookies'})
>>> r == 'X=foobar;Y=cookies' or r == 'Y=cookies;X=foobar'
>>> print sh_prepare({'X': 'foo bar'})
X='foo bar'
>>> print sh_prepare({'X': "foo'bar"})
>>> print sh_prepare({'X': "foo\\bar"})
>>> print sh_prepare({'X': "foo\\'bar"})
>>> print sh_prepare({'X': "foo\x01'bar"})
X="$(printf 'foo\001\047bar')"
>>> print sh_prepare({'X': "foo\x01'bar"}, export = True)
export X="$(printf 'foo\001\047bar')"
>>> print sh_prepare({'X': "foo\x01'bar\n"})
X="$(printf 'foo\001\047bar\nx')";X=${X%x}
>>> print sh_prepare({'X': "foo\x01'bar\n"}, export = True)
X="$(printf 'foo\001\047bar\nx')";export X=${X%x}
>>> print `subprocess.check_output('%s;echo -n "$X"' % sh_prepare({'X': "foo\x01'bar"}), shell = True)`

Outputs a string in a format that will be understood by /bin/sh.

If the string does not contain any bad characters, it will simply be returned, possibly with quotes. If it contains bad characters, it will be escaped in a way which is compatible with most known systems.


>>> print sh_string('foobar')
>>> print sh_string('foo bar')
'foo bar'
>>> print sh_string("foo'bar")
>>> print sh_string("foo\\bar")
>>> print sh_string("foo\\'bar")
>>> print sh_string("foo\x01'bar")
"$(printf 'foo\001\047bar')"
>>> print `subprocess.check_output("echo -n " + sh_string("foo\x01'bar"), shell = True)`
pwnlib.util.misc.size(n, abbriv = 'B', si = False) → str[source]

Convert the length of a bytestream to human readable form.

  • n (int,str) – The length to convert to human readable form
  • abbriv (str) –


>>> size(451)
>>> size(1000)
>>> size(1024)
>>> size(1024, si = True)
>>> [size(1024 ** n) for n in range(7)]
['1B', '1.00KB', '1.00MB', '1.00GB', '1.00TB', '1.00PB', '1024.00PB']
pwnlib.util.misc.which(name, flags = os.X_OK, all = False) → str or str set[source]

Works as the system command which; searches $PATH for name and returns a full path if found.

If all is True the set of all found locations is returned, else the first occurence or None is returned.

  • name (str) – The file to search for.
  • all (bool) – Whether to return all locations where name was found.

If all is True the set of all locations where name was found, else the first location or None if not found.


>>> which('sh')
pwnlib.util.misc.write(path, data='', create_dir=False, mode='w')[source]

Create new file or truncate existing to zero length and write data.