# Technical Documentation: Gallopsled/pwntools

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/Gallopsled/pwntools)

### Overview (`README.md`)

# pwntools - CTF toolkit


[](https://pypi.python.org/pypi/pwntools/)
[](https://docs.pwntools.com/)
[](https://github.com/Gallopsled/pwntools/actions/workflows/ci.yml?query=branch%3Adev)
[](https://coveralls.io/github/Gallopsled/pwntools?branch=dev)
[](http://choosealicense.com/licenses/mit/)
[](https://repology.org/project/python:pwntools/versions)
[](https://discord.gg/96VA2zvjCB)
[](https://twitter.com/pwntools)

Pwntools is a CTF framework and exploit development library. Written in Python, it is designed for rapid prototyping and development, and intended to make exploit writing as simple as possible.

```python
from pwn import *
context(arch = 'i386', os = 'linux')

r = remote('exploitme.example.com', 31337)
# EXPLOIT CODE GOES HERE
r.send(asm(shellcraft.sh()))
r.interactive()
```

# Documentation

Our documentation is available at [docs.pwntools.com](https://docs.pwntools.com/)

A series of tutorials is also [available online](https://github.com/Gallopsled/pwntools-tutorial#readme)

To get you started, we've provided some example solutions for past CTF challenges in our [write-ups repository](https://github.com/Gallopsled/pwntools-write-ups).

# Installation

Pwntools is best supported on 64-bit Ubuntu LTS releases (22.04 and 24.04).  Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).  

Pwntools supports Python 3.10+ since version 5.0.0.  Use Pwntools 4.x for older versions as well as Python 2.7. Most of the functionality of pwntools is self-contained and Python-only.  You should be able to get running quickly with

```sh
sudo apt-get update
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade pwntools
```


However, some of the features (assembling/disassembling foreign architectures) require non-Python dependencies.  For more information, see the [complete installation instructions here](https://docs.pwntools.com/en/stable/install.html).


# Contribution

See [CONTRIBUTING.md](CONTRIBUTING.md)

# Contact and Community
If you have any questions not worthy of a [bug report](https://github.com/Gallopsled/pwntools/issues), join the Discord server at https://discord.gg/96VA2zvjCB

---

### Overview (`examples/README.md`)

# Examples
While these examples should all work, they are not very representative of
the pwntools project.

We have a plan to create a separate repository with examples, primarily
exploits. Until we do so, we recommend new users to look at
https://docs.pwntools.com, as this is a better overview of our features.

In no particular order the docstrings for each example:

* `args.py`
```
When not in lib-mode (import `pwn` rather than `pwnlib`) we parse the
commandline for variables definitions.  A variable definition has the form::

  <var>=<val>

where ``<var>`` contains only uppercase letters, digits and underscores and
doesn't start with a digit.

Try running this example with::

  $ python args.py RHOST=localhost RPORT=1337
```
* `asm.py`
```
Example showing the interface to `pwnlib.asm.asm` and `pwnlib.shellcraft`.
```
* `attach.py`
```
Example showing `pwnlib.gdb.attach()`
```
* `clean_and_log.py`
```
Use case for `pwnlib.tubes.tube.clean_and_log`.

Sometimes you will have a solution to a challenge but you don't know what it
will look like when you get the flag.  Sometimes that will leave you with a
top-level exception, no flag, and angry team members.

Solution:
 1. Always run wireshark or tcpdump.  Always.
 2. Register <your socket>.clean or <your socket>.clean_and_log to run at exit.
```
* `indented.py`
```
When running in term-mode (import `pwn` rather than `pwnlib`, stdout is a TTY
and not running in a REPL), we can do proper indentation where lines too long to
fit on a screen are split into multiple individually indented lines.

Too see the difference try running with::

  $ python indented.py

and

  $ python -i indented.py

Also notice that `pause()` can react on any key when in `term_mode`.
```
* `listen_uroboros.py`
```
An example showing interconnection of sockets.  This script will wait for three
connections on port 1337, then connect them like a three-way Uroboros.
```
* `options.py`
```
Example showing `pwnlib.ui.options()`
```
* `port_forward.py`
```
A very simple port forwarder using `pwnlib.tubes.tube.connect_both()`.
```
* `readline_completers.py`
```
Example showing pwnlib's readline implementation and a few completers.  This
part of pwnlib will probably see some major changes soon, but we wanted to show
off some proof-of-concepts.
```
* `remote.py`
```
Example showing how to use the remote class.
```
* `remote_gdb_debugging.py`
```
Simple example showing how to use the remote
gdb debugging features available in pwntools.
```
* `spinners.py`
```
Just a lot of spinners!
```
* `splash.py`
```
"Easteregg"
```
* `ssh.py`
```
Example showing how to use the ssh class.
```
* `text.py`
```
Example showing how to use `pwnlib.term.text`.

Try running with::

  $ TERM=xterm python text.py

and::

  $ TERM=xterm-256color python text.py
```
* `yesno.py`
```
Example showing `pwnlib.ui.yesno()`
```

---

### Overview (`extra/bash_completion.d/README.md`)

# Bash Completion

To install the completion, add `. /path/to/bash_completion.d/pwn`to your e.g. `~/.bash_profile`.

The `./install.sh` script attempts to do this for you automatically.

### Shellcraft Autocomplete

The legacy autocompletion for `pwn shellcraft` is also available at `./shellcraft`.  

It is unsupported, and slow (runs `pwn shellcraft -l` every time your shell starts).

---

### Overview (`extra/docker/README.md`)

# Pwntools Docker Images

This directory contains some Docker images with various versions of Pwntools pre-installed.

## Getting Images

You can either make them yourself, or pull from Docker Hub.

### Docker Hub

To pull an image from Docker hub, just run the command:

```sh
$ docker pull pwntools/pwntools:stable
```

Replace `stable` with `beta` or `dev` as desired.

### Building Locally

To build the images locally, just invoke the `Makefile` with the desired branch target.

```sh
$ make -C extra/docker dev
```

## Running Images

To run the `stable`, `beta`, or `dev` image, we recommend the following command line, in this example it is the `dev` image.

```sh
$ docker run -it \
    --privileged \
    --net=host \
 		--ulimit core=-1:-1 \
 		pwntools/pwntools:dev
```

The `--privileged` option is needed to perform any debugging with GDB.

The `--ulimit` option is needed for any corefiles to drop when a program crashes.

The `--net=host` allows you to easily connect to services hosted inside the container from outside the container.

## Development Dockerfile

In addition to `stable`, `beta`, and `dev` Dockerfiles, there is also a `develop` dockerfile which mounts your Pwntools installation inside the VM so you can develop seamlessly while editing on your host.

```sh
$ make -C extra/docker develop
```

You will be dropped into a shell, and any changes you make to your local Pwntools checkout will be immediately reflected inside the Docker container.  This is useful for e.g. editing on a macOS host, but testing your changes on Ubuntu without needing to copy files around.

---

### Overview (`extra/textmate/README.md`)

# Pwntools Mako Assembly Syntax Highlighting

This should work for TextMate and anything that's compatible (e.g. Sublime Text).



## Installation

### Sublime Text

Copy the `tmLanguage` files into the `Packages/User` folder in your Sublime Text configuration folder.  

These folders are located at the paths shown below.  Replace `2` with `3` if you're a ST3 user.

- OS X: `~/Library/Application Support/Sublime Text 2`
- Windows: `%APPDATA%\Sublime Text 2`
- Linux: `~/.config/sublime-text-2`

Open a `.asm` file, and choose `View > Syntax > Open All ... > Pwntools ...`.

---

### Overview (`extra/zsh_completion/README.md`)

# ZSH Completion

To install the completion, copy `_pwn` to somewhere in your `$fpath`.

The `./install.sh` script attempts to automate this, and advises an alternative method if that's unavailable.

---

### Overview (`travis/docker/README.md`)

# Testing in a Can

This is a Dockerfile which has all of the requirements for testing pwntools.

It's pretty simple, just run `make`.  All of your changes will be copied into the docker container, and the doctest suite will be executed automatically.

```shell
$ make -C travis/docker ANDROID=yes
$ make -C travis/docker ANDROID=no TARGET=ssh.rst
```

You can get drop into a tmux session in the container to debug tests using the `shell` or `bash` targets.

```shell
$ make -C travis/docker shell
```

## Options

Currently, the options `TARGET` and `ANDROID` are available.

### `ANDROID`

Controls whether or not to run the Android test.  The valid options are ``yes`` (the default) and ``no``.

### `TARGET`

This is appended to the `sphinx` command line, but generally is useful to select a specific `rst` file to parse (e.g. to only run those tests).

## Known Issues

Currently, some tests are broken when executed in Docker.

- `process.leak()` is broken, as it relies on `/proc/<pid>/mem`
- `srop` tests are broken, since there are issues with `SYS_sigreturn` when running in Docker.

---

### Requirements (`docs/requirements.txt`)

capstone
coverage[toml]
doc2dash
docutils>=0.18
intervaltree
isort
mako>=1.0.0
paramiko>=1.15.2
pyelftools>=0.32
pygments>=2.0
pypandoc
pyserial>=2.7
pysocks
psutil
requests>=2.5.1
ropgadget>=5.3
sphinx>=8.1.3, <9
sphinx_rtd_theme
sphinxcontrib-autoprogram<=0.1.5

---

### Source About (`docs/source/about.rst`)

About pwntools
========================

Whether you're using it to write exploits, or as part
of another software project will dictate how you use it.

Historically pwntools was used as a sort of exploit-writing DSL. Simply doing
``from pwn import *`` in a previous version of pwntools would bring all sorts of
nice side-effects.

When redesigning pwntools for 2.0, we noticed two contrary goals:

* We would like to have a "normal" python module structure, to allow other
  people to familiarize themselves with pwntools quickly.
* We would like to have even more side-effects, especially by putting the
  terminal in raw-mode.

To make this possible, we decided to have two different modules. :mod:`pwnlib`
would be our nice, clean Python module, while :mod:`pwn` would be used during
CTFs.

:mod:`pwn` --- Toolbox optimized for CTFs
-----------------------------------------

.. module:: pwn

As stated, we would also like to have the ability to get a lot of these
side-effects by default. That is the purpose of this module. It does
the following:

* Imports everything from the toplevel :mod:`pwnlib` along with
  functions from a lot of submodules. This means that if you do
  ``import pwn`` or ``from pwn import *``, you will have access to
  everything you need to write an exploit.
* Calls :func:`pwnlib.term.init` to put your terminal in raw mode
  and implements functionality to make it appear like it isn't.
* Setting the :data:`pwnlib.context.log_level` to `"info"`.
* Tries to parse some of the values in :data:`sys.argv` and every
  value it succeeds in parsing it removes.

:mod:`pwnlib` --- Normal python library
---------------------------------------

.. module:: pwnlib

This module is our "clean" python-code. As a rule, we do not think that
importing :mod:`pwnlib` or any of the submodules should have any significant
side-effects (besides e.g. caching).

For the most part, you will also only get the bits you import. You for instance would
not get access to :mod:`pwnlib.util.packing` simply by doing ``import
pwnlib.util``.

Though there are a few exceptions (such as :mod:`pwnlib.shellcraft`), that does
not quite fit the goals of being simple and clean, but they can still be
imported without implicit side-effects.

---

### Source Adb (`docs/source/adb.rst`)

.. testsetup:: *

   from pprint import pprint
   from pwn import *
   adb = pwnlib.adb

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.adb` --- Android Debug Bridge
=====================================================

.. automodule:: pwnlib.adb.adb
   :members:

.. automodule:: pwnlib.adb.protocol
   :members:

---

### Source Args (`docs/source/args.rst`)

.. testsetup:: *

   from pwn import *

:mod:`pwnlib.args` --- Magic Command-Line Arguments
=====================================================

.. automodule:: pwnlib.args
   :members:

---

### Source Asm (`docs/source/asm.rst`)

.. testsetup:: *

   import tempfile
   import subprocess
   from pwn import *

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.asm` --- Assembler functions
=========================================

.. automodule:: pwnlib.asm
   :members:

Internal Functions
-----------------------------------------

These are only included so that their tests are run.

You should never need these.

.. autofunction:: pwnlib.asm.dpkg_search_for_binutils
.. autofunction:: pwnlib.asm.print_binutils_instructions

---

### Source Atexception (`docs/source/atexception.rst`)

.. testsetup:: *

   from pwnlib import atexception

:mod:`pwnlib.atexception` --- Callbacks on unhandled exception
==============================================================

.. automodule:: pwnlib.atexception
   :members:

---

### Source Atexit (`docs/source/atexit.rst`)

:mod:`pwnlib.atexit` --- Replacement for atexit
===============================================

.. automodule:: pwnlib.atexit
   :members:

---

### Source Commandline (`docs/source/commandline.rst`)

.. testsetup:: *

   from pwn import *
   old = context.defaults.copy()

.. testcleanup:: *

    context.defaults.copy = old

Command Line Tools
========================

pwntools comes with a handful of useful command-line utilities which serve as wrappers for some of the internal functionality.

If these tools do not appear to be installed, make sure that you have added ``~/.local/bin`` to your ``$PATH`` environment variable.

.. toctree::

.. autoprogram:: pwnlib.commandline.main:parser
   :prog: pwn

---

### Source Config (`docs/source/config.rst`)

:mod:`pwnlib.config` --- Pwntools Configuration File
====================================================

.. automodule:: pwnlib.config

---

### Source Constants (`docs/source/constants.rst`)

.. testsetup:: *

   from pwnlib import constants
   from pwnlib.context import context

:mod:`pwnlib.constants` --- Easy access to header file constants
================================================================

.. automodule:: pwnlib.constants

---

### Source Context (`docs/source/context.rst`)

.. testsetup:: *

   from pwn import *
   import logging
   log = pwnlib.log.getLogger('pwnlib.context')
   context.clear()

:mod:`pwnlib.context` --- Setting runtime variables
=====================================================

Many settings in ``pwntools`` are controlled via the global variable :data:`.context`, such as the selected target operating system, architecture, and bit-width.

In general, exploits will start with something like:

.. code-block:: python

    from pwn import *
    context.arch = 'amd64'

Which sets up everything in the exploit for exploiting a 64-bit Intel binary.

The recommended method is to use ``context.binary``  to automagically set all of the appropriate values.

.. code-block:: python

    from pwn import *
    context.binary = './challenge-binary'

Module Members
----------------------------------------------------

.. automodule:: pwnlib.context
   :members:

---

### Source Dynelf (`docs/source/dynelf.rst`)

:mod:`pwnlib.dynelf` --- Resolving remote functions using leaks
===============================================================

.. automodule:: pwnlib.dynelf
   :members:

---

### Source Elf (`docs/source/elf.rst`)

.. testsetup:: *

   from pwnlib.elf import *
   from pwnlib.util.misc import which

:mod:`pwnlib.elf` --- ELF Executables and Libraries
===================================================

.. automodule:: pwnlib.elf


ELF Modules
-------------------

.. toctree::
    elf/elf
    elf/config
    elf/corefile

---

### Source Encoders (`docs/source/encoders.rst`)

.. testsetup:: *

   from pwn import *

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']
   
:mod:`pwnlib.encoders` --- Encoding Shellcode
===============================================

.. automodule:: pwnlib.encoders.encoder
   :members:

.. automodule:: pwnlib.encoders.i386.ascii_shellcode
   :members:
   :special-members:
   :exclude-members: __init__

.. automodule:: pwnlib.encoders.i386.xor
   :members:

.. automodule:: pwnlib.encoders.i386.delta
   :members:

.. automodule:: pwnlib.encoders.amd64.delta
   :members:

.. automodule:: pwnlib.encoders.arm.xor
   :members:

.. automodule:: pwnlib.encoders.mips.xor
   :members:

---

### Source Exception (`docs/source/exception.rst`)

:mod:`pwnlib.exception` --- Pwnlib exceptions
====================================================

.. automodule:: pwnlib.exception
   :members:

---

### Source Filepointer (`docs/source/filepointer.rst`)

.. testsetup:: *

   from pwnlib.filepointer import *
   from pwnlib.filepointer import _update_var

:mod:`pwnlib.filepointer` --- `FILE*` structure exploitation
============================================================

.. automodule:: pwnlib.filepointer
   :members:

---

### Source Filesystem (`docs/source/filesystem.rst`)

.. testsetup:: *

    import time
    from pwnlib.context import context
    from pwnlib.tubes.ssh import ssh
    from pwnlib.filesystem import *

    # TODO: Remove global POSIX flag
    import doctest
    doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.filesystem` --- Manipulating Files Locally and Over SSH
====================================================================

Provides a Python2-compatible :py:mod:`pathlib` interface for paths
on the local filesystem (`.Path`) as well as on remote filesystems,
via SSH (`.SSHPath`).

.. automodule:: pwnlib.filesystem
   :members:

---

### Source Flag (`docs/source/flag.rst`)

.. testsetup:: *

   from pwn import *


:mod:`pwnlib.flag` --- CTF Flag Management
==========================================

.. automodule:: pwnlib.flag
   :members:

---

### Source Fmtstr (`docs/source/fmtstr.rst`)

.. testsetup:: *

	from pwn import *
	import tempfile

:mod:`pwnlib.fmtstr` --- Format string bug exploitation tools
=============================================================

.. automodule:: pwnlib.fmtstr
   :members:

---

### Source Gdb (`docs/source/gdb.rst`)

.. testsetup:: *

    from pwn import *
    context.arch = 'amd64'
    context.terminal = [os.path.join(os.path.dirname(pwnlib.__file__), 'gdb_faketerminal.py')]

    # TODO: Test on cygwin too
    import doctest
    doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.gdb` --- Working with GDB
======================================

.. automodule:: pwnlib.gdb
   :members:

---

### Source Globals (`docs/source/globals.rst`)

.. testsetup:: *

   from pwn import *

``from pwn import *``
========================

The most common way that you'll see pwntools used is

    >>> from pwn import *

Which imports a bazillion things into the global namespace to make your life easier.

This is a quick list of most of the objects and routines imported, in rough order of importance and frequency of use.

- :mod:`pwnlib.context`
    - :data:`pwnlib.context.context`
    - Responsible for most of the pwntools convenience settings
    - Set `context.log_level = 'debug'` when troubleshooting your exploit
    - Scope-aware, so you can disable logging for a subsection of code via :meth:`.ContextType.local`
- ``remote``, ``listen``, ``ssh``, ``process``
    - :mod:`pwnlib.tubes`
    - Super convenient wrappers around all of the common functionality for CTF challenges
    - Connect to anything, anywhere, and it works the way you want it to
    - Helpers for common tasks like ``recvline``, ``recvuntil``, ``clean``, etc.
    - Interact directly with the application via ``.interactive()``
- ``p32`` and ``u32``
    - :mod:`pwnlib.util.packing`
    - Useful functions to make sure you never have to remember if ``'>'`` means signed or unsigned for ``struct.pack``, and no more ugly ``[0]`` index at the end.
    - Set ``signed`` and ``endian`` in sane manners (also these can be set once on ``context`` and not bothered with again)
    - Most common sizes are pre-defined (``u8``, ``u64``, etc), and :func:`pwnlib.util.packing.pack` lets you define your own.
- ``log``
    - :mod:`pwnlib.log`
    - Make your output pretty!
- ``cyclic`` and ``cyclic_func``
    - :mod:`pwnlib.util.cyclic`
    - Utilities for generating strings such that you can find the offset of any given substring given only N (usually 4) bytes.  This is super useful for straight buffer overflows.  Instead of looking at 0x41414141, you could know that 0x61616171 means you control EIP at offset 64 in your buffer.
- ``asm`` and ``disasm``
    - :mod:`pwnlib.asm`
    - Quickly turn assembly into some bytes, or vice-versa, without mucking about
    - Supports any architecture for which you have a binutils installed
    - Over 20 different architectures have pre-built binaries at `ppa:pwntools/binutils <https://launchpad.net/~pwntools/+archive/ubuntu/binutils>`_.
- ``shellcraft``
    - :mod:`pwnlib.shellcraft`
    - Library of shellcode ready to go
    - ``asm(shellcraft.sh())`` gives you a shell
    - Templating library for reusability of shellcode fragments
- ``ELF``
    - :mod:`pwnlib.elf`
    - ELF binary manipulation tools, including symbol lookup, virtual memory to file offset helpers, and the ability to modify and save binaries back to disk
- ``DynELF``
    - :mod:`pwnlib.dynelf`
    - Dynamically resolve functions given only a pointer to any loaded module, and a function which can leak data at any address
- ``ROP``
    - :mod:`pwnlib.rop`
    - Automatically generate ROP chains using a DSL to describe what you want to do, rather than raw addresses
- ``gdb.debug`` and ``gdb.attach``
    - :mod:`pwnlib.gdb`
    - Launch a binary under GDB and pop up a new terminal to interact with it.  Automates setting breakpoints and makes iteration on exploits MUCH faster.
    - Alternately, attach to a running process given a PID, :mod:`pwnlib.tubes` object, or even just a socket that's connected to it
- ``args``
    - Dictionary containing all-caps command-line arguments for quick access
    - Run via ``python foo.py REMOTE=1`` and ``args['REMOTE'] == '1'``.
    - Can also control logging verbosity and terminal fanciness
        - `NOTERM`
        - `SILENT`
        - `DEBUG`
- ``randoms``, ``rol``, ``ror``, ``xor``, ``bits``
    - :mod:`pwnlib.util.fiddling`
    - Useful utilities for generating random data from a given alphabet, or simplifying math operations that usually require masking off with `0xffffffff` or calling `ord` and `chr` an ugly number of times
- ``net``
    - :mod:`pwnlib.util.net`
    - Routines for querying about network interfaces
- ``proc``
    - :mod:`pwnlib.util.proc`
    - Routines for querying about processes
- ``pause``
    - It's the new ``getch``
- ``safeeval``
    - :mod:`pwnlib.util.safeeval`
    - Functions for safely evaluating python code without nasty side-effects.

These are all pretty self explanatory, but are useful to have in the global namespace.

- ``hexdump``
- ``read`` and ``write``
- ``enhex`` and ``unhex``
- ``more``
- ``group``
- ``align`` and ``align_down``
- ``urlencode`` and ``urldecode``
- ``which``
- ``wget``

Additionally, all of the following modules are auto-imported for you.  You were going to do it anyway.

- ``os``
- ``sys``
- ``time``
- ``requests``
- ``re``
- ``random``

---

### Source Index (`docs/source/index.rst`)

pwntools
====================================

``pwntools`` is a CTF framework and exploit development library.
Written in Python, it is designed for rapid prototyping and development,
and intended to make exploit writing as simple as possible.

The primary location for this documentation is at docs.pwntools.com_, which uses
readthedocs_. It comes in three primary flavors:

- Stable_
- Beta_
- Dev_

.. _readthedocs: https://readthedocs.org
.. _docs.pwntools.com: https://docs.pwntools.com/en/latest
.. _Stable: https://docs.pwntools.com/en/stable
.. _Beta: https://docs.pwntools.com/en/beta
.. _Dev: https://docs.pwntools.com/en/dev


Getting Started
---------------

.. toctree::
   :maxdepth: 3
   :glob:

   about
   install
   intro
   globals
   commandline


Module Index
------------

Each of the ``pwntools`` modules is documented here.

.. toctree::
   :maxdepth: 1
   :glob:

   adb
   args
   asm
   atexception
   atexit
   constants
   config
   context
   dynelf
   encoders
   elf
   exception
   filepointer
   filesystem
   flag
   fmtstr
   gdb
   libc
   libcdb
   log
   memleak
   protocols
   qemu
   regsort
   replacements
   rop
   runner
   shellcraft
   term
   timeout
   tubes
   ui
   update
   useragents
   util/*
   windbg

.. toctree::
   :hidden:

   testexample

.. only:: not dash

   Indices and tables
   ==================

   * :ref:`genindex`
   * :ref:`modindex`
   * :ref:`search`

Bytes
-----

The bytes vs text distinction is so important that it even made it to this main page.
See the pwntools-tutorial_ repo for the latest tutorial finally
explaining the difference once and for all (hopefully).

.. _pwntools-tutorial: https://github.com/Gallopsled/pwntools-tutorial/blob/master/bytes.md

---

### Source Install (`docs/source/install.rst`)

Installation
============

Pwntools is best supported on 64-bit Ubuntu LTS releases (22.04 and 24.04).  Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).

Prerequisites
-------------

In order to get the most out of ``pwntools``, you should have the
following system libraries installed.

.. toctree::
   :maxdepth: 3
   :glob:

   install/*


Note: For Mac OS X you will need to have cmake ``brew install cmake`` and pkg-config ``brew install pkg-config`` installed.

.. code-block:: bash

    brew install pwntools

Released Version
-----------------

pwntools is available as a ``pip`` package for Python3. Version v5.0.0 supports Python3.10 or later. Use v4 if you use earlier versions of Python.

Python3
^^^^^^^

The Python version required for installing Pwntools is kept as low as possible on a best-effort basis.  However, new features target Python3.10 and later.

.. code-block:: bash

    $ sudo apt-get update
    $ sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
    $ python3 -m pip install --upgrade pip
    $ python3 -m pip install --upgrade pwntools


Python2 (Deprecated)
^^^^^^^^^^^^^^^^^^^^

Python2 support has been removed in Pwntools v5.0.0.  The last version to support Python2 was v4.15.0.

NOTE: Pwntools maintainers STRONGLY recommend using Python3 for all future Pwntools-based scripts and projects.

Additionally, due to `pip` dropping support for Python2, a specfic version of `pip` must be installed.

.. code-block:: bash

    $ sudo apt-get update
    $ sudo apt-get install python python-pip python-dev git libssl-dev libffi-dev build-essential
    $ python2 -m pip install --upgrade pip==20.3.4
    $ python2 -m pip install --upgrade pwntools


Command-Line Tools
------------------

When installed with ``sudo`` the above commands will install Pwntools' command-line tools to somewhere like ``/usr/bin``.

However, if you run as an unprivileged user, you may see a warning message that looks like this::

    WARNING: The scripts asm, checksec, common, constgrep, cyclic, debug, disablenx, disasm, 
    elfdiff, elfpatch, errno, hex, main, phd, pwn, pwnstrip, scramble, shellcraft, template, 
    unhex, update and version are installed in '/home/user/.local/bin' which is not on PATH.

Follow the instructions listed and add ``~/.local/bin`` to your ``$PATH`` environment variable.

Development
--------------

If you are hacking on Pwntools locally, you'll want to do something like this:

.. code-block:: bash

    $ git clone https://github.com/Gallopsled/pwntools
    $ pip install --upgrade --editable ./pwntools

.. _Ubuntu: https://launchpad.net/~pwntools/+archive/ubuntu/binutils

---

### Source Intro (`docs/source/intro.rst`)

.. testsetup:: *

   from pwn import *

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

Getting Started
========================

To get your feet wet with pwntools, let's first go through a few examples.

When writing exploits, pwntools generally follows the "kitchen sink" approach.

    >>> from pwn import *

This imports a lot of functionality into the global namespace.  You can now
assemble, disassemble, pack, unpack, and many other things with a single function.

A full list of everything that is imported is available on :doc:`globals`.


Tutorials
---------

A series of tutorials for Pwntools exists online, at
https://github.com/Gallopsled/pwntools-tutorial#readme


Making Connections
------------------

You need to talk to the challenge binary in order to pwn it, right?
pwntools makes this stupid simple with its :mod:`pwnlib.tubes` module.

This exposes a standard interface to talk to processes, sockets, serial ports,
and all manner of things, along with some nifty helpers for common tasks.
For example, remote connections via :mod:`pwnlib.tubes.remote`.

::

    >>> conn = remote('ftp.ubuntu.com',21)
    >>> conn.recvline() # doctest: +ELLIPSIS
    b'220 ...'
    >>> conn.send(b'USER anonymous\r\n')
    >>> conn.recvuntil(b' ', drop=True)
    b'331'
    >>> conn.recvline()
    b'Please specify the password.\r\n'
    >>> conn.close()

It's also easy to spin up a listener

    >>> l = listen()
    >>> r = remote('localhost', l.lport)
    >>> c = l.wait_for_connection()
    >>> r.send(b'hello')
    >>> c.recv()
    b'hello'

Interacting with processes is easy thanks to :mod:`pwnlib.tubes.process`.

::

    >>> sh = process('/bin/sh')
    >>> sh.sendline(b'sleep 3; echo hello world;')
    >>> sh.recvline(timeout=1)
    b''
    >>> sh.recvline(timeout=5)
    b'hello world\n'
    >>> sh.close()

Not only can you interact with processes programmatically, but you can
actually **interact** with processes.

    >>> sh.interactive() # doctest: +SKIP
    $ whoami
    user

There's even an SSH module for when you've got to SSH into a box to perform
a local/setuid exploit with :mod:`pwnlib.tubes.ssh`.  You can quickly spawn
processes and grab the output, or spawn a process and interact with it like
a ``process`` tube.

::

    >>> shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
    >>> shell['whoami']
    b'bandit0'
    >>> shell.download_file('/etc/motd')
    >>> sh = shell.run('sh')
    >>> sh.sendline(b'sleep 3; echo hello world;') # doctest: +SKIP
    >>> sh.recvline(timeout=1)
    b''
    >>> sh.recvline(timeout=5)
    b'hello world\n'
    >>> shell.close()

Packing Integers
------------------

A common task for exploit-writing is converting between integers as Python
sees them, and their representation as a sequence of bytes.
Usually folks resort to the built-in ``struct`` module.

pwntools makes this easier with :mod:`pwnlib.util.packing`.  No more remembering
unpacking codes, and littering your code with helper routines.

    >>> import struct
    >>> p32(0xdeadbeef) == struct.pack('I', 0xdeadbeef)
    True
    >>> leet = unhex('37130000')
    >>> u32(b'abcd') == struct.unpack('I', b'abcd')[0]
    True

The packing/unpacking operations are defined for many common bit-widths.

    >>> u8(b'A') == 0x41
    True

Setting the Target Architecture and OS
--------------------------------------

The target architecture can generally be specified as an argument to the routine that requires it.

    >>> asm('nop')
    b'\x90'
    >>> asm('nop', arch='arm')
    b'\x00\xf0 \xe3'

However, it can also be set once in the global ``context``.  The operating system, word size, and endianness can also be set here.

    >>> context.arch      = 'i386'
    >>> context.os        = 'linux'
    >>> context.endian    = 'little'
    >>> context.word_size = 32

Additionally, you can use a shorthand to set all of the values at once.

    >>> asm('nop')
    b'\x90'
    >>> context(arch='arm', os='linux', endian='big', word_size=32)
    >>> asm('nop')
    b'\xe3 \xf0\x00'

.. doctest::
   :hide:

    >>> context.clear()

Setting Logging Verbosity
-------------------------

You can control the verbosity of the standard pwntools logging via ``context``.

For example, setting

    >>> context.log_level = 'debug'

Will cause all of the data sent and received by a ``tube`` to be printed to the screen.

.. doctest::
   :hide:

    >>> context.clear()

Assembly and Disassembly
------------------------

Never again will you need to run some already-assembled pile of shellcode
from the internet!  The :mod:`pwnlib.asm` module is full of awesome.

    >>> enhex(asm('mov eax, 0'))
    'b800000000'

But if you do, it's easy to suss out!

    >>> print(disasm(unhex('6a0258cd80ebf9')))
       0:   6a 02                   push   0x2
       2:   58                      pop    eax
       3:   cd 80                   int    0x80
       5:   eb f9                   jmp    0x0

However, you shouldn't even need to write your own shellcode most of the
time!  pwntools comes with the :mod:`pwnlib.shellcraft` module, which is
loaded with useful time-saving shellcodes.

Let's say that we want to `setreuid(getuid(), getuid())` followed by `dup`ing
file descriptor 4 to `stdin`, `stdout`, and `stderr`, and then pop a shell!

    >>> enhex(asm(shellcraft.setreuid() + shellcraft.dupsh(4))) # doctest: +ELLIPSIS
    '6a3158cd80...'


Misc Tools
----------------------

Never write another hexdump, thanks to :mod:`pwnlib.util.fiddling`.


Find offsets in your buffer that cause a crash, thanks to :mod:`pwnlib.cyclic`.

    >>> cyclic(20)
    b'aaaabaaacaaadaaaeaaa'
    >>> # Assume EIP = 0x62616166 (b'faab' which is pack(0x62616166))  at crash time
    >>> cyclic_find(b'faab')
    120

ELF Manipulation
----------------

Stop hard-coding things!  Look them up at runtime with :mod:`pwnlib.elf`.

    >>> e = ELF('/bin/cat')
    >>> print(hex(e.address)) #doctest: +SKIP
    0x400000
    >>> print(hex(e.symbols['write'])) #doctest: +SKIP
    0x401680
    >>> print(hex(e.got['write'])) #doctest: +SKIP
    0x60b070
    >>> print(hex(e.plt['write'])) #doctest: +SKIP
    0x401680

You can even patch and save the files.

    >>> e = ELF('/bin/cat')
    >>> e.read(e.address, 4)
    b'\x7fELF'
    >>> e.asm(e.address, 'ret')
    >>> e.save('/tmp/quiet-cat')
    >>> disasm(open('/tmp/quiet-cat','rb').read(1))
    '   0:   c3                      ret'

---

### Source Libc (`docs/source/libc.rst`)

:mod:`pwnlib.libc` --- Convenient Functions for Libc Implementations
====================================================================

Submodules
----------

.. toctree::
   :glob:

   libc/*

---

### Source Libcdb (`docs/source/libcdb.rst`)

.. testsetup:: *

   from pwn import *
   from pwnlib.libcdb import *

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.libcdb` --- Libc Database
===========================================

.. automodule:: pwnlib.libcdb
   :members:

---

### Source Log (`docs/source/log.rst`)

:mod:`pwnlib.log` --- Logging stuff
===================================

.. automodule:: pwnlib.log
   :members: getLogger, install_default_handler, rootlogger

.. autoclass:: pwnlib.log.Progress
   :members:
   :member-order: bysource

.. autoclass:: pwnlib.log.Logger
   :members:
   :member-order: bysource

.. autoclass:: pwnlib.log.Handler
   :members:
   :member-order: bysource

.. autoclass:: pwnlib.log.Formatter
   :members:
   :member-order: bysource

---

### Source Memleak (`docs/source/memleak.rst`)

.. testsetup:: *

    from pwn import *

:mod:`pwnlib.memleak` --- Helper class for leaking memory
=========================================================

.. automodule:: pwnlib.memleak
    :members:

---

### Source Protocols (`docs/source/protocols.rst`)

.. testsetup:: *

   from pwn import *


:mod:`pwnlib.protocols.adb` --- Protocol implementations
========================================================

.. automodule:: pwnlib.protocols.adb
   :members:

---

### Source Qemu (`docs/source/qemu.rst`)

.. testsetup:: *

   from pwn import *

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']


:mod:`pwnlib.qemu` --- QEMU Utilities
==========================================

.. automodule:: pwnlib.qemu
   :members:

---

### Source Regsort (`docs/source/regsort.rst`)

.. testsetup:: *

    from pwnlib.regsort import *

:mod:`pwnlib.regsort` --- Register sorting
===========================================================

.. automodule:: pwnlib.regsort
   :members:

---

### Source Replacements (`docs/source/replacements.rst`)

:mod:`pwnlib.replacements` --- Replacements for various functions
=================================================================

.. automodule:: pwnlib.replacements
   :members:

---

### Source Rop (`docs/source/rop.rst`)

:mod:`pwnlib.rop` --- Return Oriented Programming
=================================================

Submodules
----------

.. toctree::
   :glob:

   rop/*

---

### Source Runner (`docs/source/runner.rst`)

.. testsetup:: *

   from pwnlib.runner import *
   from pwnlib.asm import asm

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.runner` --- Running Shellcode
===========================================

.. automodule:: pwnlib.runner
   :members:

---

### Source Shellcraft (`docs/source/shellcraft.rst`)

.. testsetup:: *

   from pwnlib import shellcraft

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.shellcraft` --- Shellcode generation
=================================================

.. automodule:: pwnlib.shellcraft

.. TODO:

   Write a guide to adding more shellcode.

Submodules
----------

.. toctree::
   :glob:

   shellcraft/*

---

### Source Term (`docs/source/term.rst`)

:mod:`pwnlib.term` --- Terminal handling
========================================

.. automodule:: pwnlib.term
   :members:

Term Modules
-------------------

.. toctree::
    term/readline

---

### Source Testexample (`docs/source/testexample.rst`)

.. testsetup:: *

   import os
   from pwnlib.testexample import add

:mod:`pwnlib.testexample` --- Example Test Module
==================================================

.. automodule:: pwnlib.testexample
   :members:

---

### Source Timeout (`docs/source/timeout.rst`)

.. testsetup:: *

   from pwnlib.context import context
   from pwnlib.timeout import Timeout
   import time

:mod:`pwnlib.timeout` --- Timeout handling
============================================

.. automodule:: pwnlib.timeout
   :members:

---

### Source Tubes (`docs/source/tubes.rst`)

.. testsetup:: *

   from pwn import *

:mod:`pwnlib.tubes` --- Talking to the World!
=============================================

.. automodule:: pwnlib.tubes


Types of Tubes
-------------------

.. toctree::
    :maxdepth: 3
    :glob:

    tubes/*


:mod:`pwnlib.tubes.tube` --- Common Functionality
-------------------------------------------------


.. automodule:: pwnlib.tubes.tube

  .. autoclass:: pwnlib.tubes.tube.tube()
     :members:
     :exclude-members: recv_raw, send_raw, settimeout_raw,
                       can_recv_raw, shutdown_raw, connected_raw,

---

### Source Ui (`docs/source/ui.rst`)

.. testsetup:: *

   from pwn import *
   import io

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.ui` --- Functions for user interaction
===================================================

.. automodule:: pwnlib.ui
   :members:

---

### Source Update (`docs/source/update.rst`)

.. testsetup:: *

   from pwn import *
   from pwnlib.update import *

:mod:`pwnlib.update` --- Updating Pwntools
===================================================

.. automodule:: pwnlib.update
   :members:

---

### Source Useragents (`docs/source/useragents.rst`)

.. testsetup:: *

   from pwnlib.useragents import *

:mod:`pwnlib.useragents` --- A database of useragent strings
============================================================

.. automodule:: pwnlib.useragents
   :members:

---

### Source Windbg (`docs/source/windbg.rst`)

.. testsetup:: *

    from pwn import *

:mod:`pwnlib.windbg` --- Working with WinDbg
============================================

.. automodule:: pwnlib.windbg
   :members:

---

### Source Elf Config (`docs/source/elf/config.rst`)

.. testsetup:: *

   from pwn import *
   from pwnlib.elf.config import parse_kconfig

:mod:`pwnlib.elf.config` --- Kernel Config Parsing
===========================================================

.. automodule:: pwnlib.elf.config
  :members:

---

### Source Elf Corefile (`docs/source/elf/corefile.rst`)

.. testsetup:: *

   from glob import glob
   from pwn import *

   # The Linux kernel won't overwrite an existing corefile, so in case 
   # some other part of the doctests caused a segfault and core dump,
   # we need to get rid of it before our tests run.
   #
   # We DONT need to worry about e.g. ./core existing when using Corefile()
   # because we always move and rename the corefile to prevent this situation.
   if os.path.exists('core'): 
      os.unlink('core')

   # bash-static is a statically linked version of bash, but if $SHELL is not
   # set to anything, it decides to up and load ld.so and libc.so which breaks
   # our example of showing `corefile.libc == None` for a statically linked bin.
   # Set the environment here so it's not in the middle of our tests.
   os.environ.setdefault('SHELL', '/bin/sh')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']


:mod:`pwnlib.elf.corefile` --- Core Files
===========================================================

.. automodule:: pwnlib.elf.corefile

  .. autoclass:: pwnlib.elf.corefile.Corefile
     :members:
     :show-inheritance:

  .. autoclass:: pwnlib.elf.corefile.Mapping
     :members:

---

### Source Elf Elf (`docs/source/elf/elf.rst`)

.. testsetup:: *

   from pwn import *
   from glob import glob
   from pwnlib.elf.maps import CAT_PROC_MAPS_EXIT
   import shutil

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.elf.elf` --- ELF Files
===========================================================

.. automodule:: pwnlib.elf.elf

  .. autoclass:: pwnlib.elf.elf.ELF
     :members:
     :show-inheritance:
     :inherited-members:
     :exclude-members: address_offsets,
                       get_data,
                       get_dwarf_info,
                       get_section,
                       get_segment,
                       has_dwarf_info,
                       iter_sections,
                       iter_segments

  .. autoclass:: pwnlib.elf.elf.Function
     :members:

  .. autoclass:: pwnlib.elf.elf.dotdict
     :members:

---

### Source Install Binutils (`docs/source/install/binutils.rst`)

Binutils
-------------

Assembly of foreign architectures (e.g. assembling Sparc shellcode on
Mac OS X) requires cross-compiled versions of ``binutils`` to be
installed. We've made this process as smooth as we can.

In these examples, replace ``$ARCH`` with your target architecture (e.g., arm, aarch64, mips64, vax, etc.).

Building `binutils` from source takes about 60 seconds on a modern 8-core machine.

Ubuntu
^^^^^^^^^^^^^^^^

For Ubuntu 12.04 through 15.10, you must first add the pwntools `Personal Package Archive repository <https://launchpad.net/~pwntools/+archive/ubuntu/binutils>`__.

Ubuntu Xenial (16.04) has official packages for most architectures, and does not require this step.

.. code-block:: bash

    $ sudo apt-get install software-properties-common
    $ sudo apt-add-repository ppa:pwntools/binutils
    $ sudo apt-get update

Then, install the binutils for your architecture.

.. code-block:: bash

    $ sudo apt-get install binutils-$ARCH-linux-gnu

Mac OS X
^^^^^^^^^^^^^^^^

Mac OS X is just as easy, but requires building binutils from source.
However, we've made ``homebrew`` recipes to make this just two commands.
After installing `brew <https://brew.sh>`__, grab the appropriate
recipe from our `binutils
repo <https://github.com/Gallopsled/pwntools-binutils/>`__.

.. code-block:: bash

    $ wget https://raw.githubusercontent.com/Gallopsled/pwntools-binutils/master/macos/binutils-$ARCH.rb
    $ brew install ./binutils-$ARCH.rb

Note: The pwntools/pwntools Homebrew tap is currently (August 2026) undergoing migration.
If you encounter issues on Mac OS, try running ``export HOMEBREW_DEVELOPER="true"`` before ``brew install ...``.
The actual resolution of the tap migration is still pending.


Windows
^^^^^^^^^^^^^^^^

Windows support is experimental. You can try installing a prebuilt version of binutils
for your desired architecture from the `GNU Toolchains <https://gnutoolchains.com/>`__ project.

Note: For x86 and x86_64, you should use the `ubuntu toolchain <https://gnutoolchains.com/ubuntu/>`__
instead of the MinGW toolchains due to differences in the commandline handling.

Alternate OSes
^^^^^^^^^^^^^^^^

If you want to build everything by hand, or don't use any of the above
OSes, ``binutils`` is simple to build by hand.

.. code-block:: bash

    #!/usr/bin/env bash

    V=2.38   # Binutils Version
    ARCH=arm # Target architecture

    cd ${TMPDIR:-/tmp}
    wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$V.tar.gz
    wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$V.tar.gz.sig

    gpg --keyserver keys.gnupg.net --recv-keys 4AE55E93
    gpg --verify binutils-$V.tar.gz.sig

    tar xf binutils-$V.tar.gz

    mkdir binutils-build
    cd binutils-build

    export AR=ar
    export AS=as

    ../binutils-$V/configure \
        --prefix=${PREFIX:-/usr/local} \
        --target=$ARCH-unknown-linux-gnu \
        --disable-static \
        --disable-multilib \
        --disable-werror \
        --disable-nls

    MAKE=gmake
    hash gmake || MAKE=make

    $MAKE -j clean all
    sudo $MAKE install

---

### Source Install Headers (`docs/source/install/headers.rst`)

Python Development Headers
-----------------------------

Some of pwntools' Python dependencies require native extensions (for example, Paramiko requires PyCrypto).

In order to build these native extensions, the development headers for Python must be installed.

Ubuntu
^^^^^^^^^^^^^^^^

.. code-block:: bash

    $ sudo apt-get install python-dev

Mac OS X
^^^^^^^^^^^^^^^^

No action needed.

---

### Source Libc Glibc (`docs/source/libc/glibc.rst`)

.. testsetup:: *

   from pwn import *

:mod:`pwnlib.libc.glibc` --- Convenient Functions for Glibc
===========================================================

.. automodule:: pwnlib.libc.glibc
   :members:

---

### Source Rop Ret2dlresolve (`docs/source/rop/ret2dlresolve.rst`)

.. testsetup:: *

   from pwn import *
   import tempfile

:mod:`pwnlib.rop.ret2dlresolve` --- Return to dl_resolve
========================================================

.. automodule:: pwnlib.rop.ret2dlresolve
   :members:

---

### Source Rop Rop (`docs/source/rop/rop.rst`)

.. testsetup:: *

   import time
   from glob import glob

   from pwnlib.asm import asm
   from pwnlib import constants
   from pwnlib.context import context
   from pwnlib.elf import ELF
   from pwnlib.rop import ROP
   from pwnlib.rop.call import Call, AppendedArgument
   from pwnlib.elf.maps import CAT_PROC_MAPS_EXIT
   from pwnlib.util.packing import *
   from pwnlib.util.fiddling import *
   from pwnlib.tubes.process import process
   from pwnlib import shellcraft
   from pwnlib.util.misc import which
   import pwnlib.data

   context.clear()

   # TODO: Remove global LINUX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']


:mod:`pwnlib.rop.rop` --- Return Oriented Programming
==========================================================

.. automodule:: pwnlib.rop.rop
   :members:

---

### Source Rop Srop (`docs/source/rop/srop.rst`)

.. testsetup:: *

   from pwnlib.rop.srop import *

   from pwnlib import constants
   from pwnlib import shellcraft
   from pwnlib.elf import ELF
   from pwnlib.tubes.process import process

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.rop.srop` --- Sigreturn Oriented Programming
==========================================================

.. automodule:: pwnlib.rop.srop
   :members:

---

### Source Shellcraft Aarch64 (`docs/source/shellcraft/aarch64.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='aarch64')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.aarch64` --- Shellcode for AArch64
===========================================================

:mod:`pwnlib.shellcraft.aarch64`
--------------------------------

.. automodule:: pwnlib.shellcraft.aarch64
   :members:

:mod:`pwnlib.shellcraft.aarch64.linux`
--------------------------------------

.. automodule:: pwnlib.shellcraft.aarch64.linux
   :members:

---

### Source Shellcraft Amd64 (`docs/source/shellcraft/amd64.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='amd64')

   # TODO: POSIX/WINDOWS shellcode test
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.amd64` --- Shellcode for AMD64
===========================================================

:mod:`pwnlib.shellcraft.amd64`
---------------------------------------

.. automodule:: pwnlib.shellcraft.amd64
   :members:

:mod:`pwnlib.shellcraft.amd64.linux`
---------------------------------------

.. automodule:: pwnlib.shellcraft.amd64.linux
   :members:

:mod:`pwnlib.shellcraft.amd64.windows`
---------------------------------------

.. automodule:: pwnlib.shellcraft.amd64.windows
   :members:

---

### Source Shellcraft Arm (`docs/source/shellcraft/arm.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='arm')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.arm` --- Shellcode for ARM
===========================================================

:mod:`pwnlib.shellcraft.arm`
-----------------------------

.. automodule:: pwnlib.shellcraft.arm
   :members:

:mod:`pwnlib.shellcraft.arm.linux`
-----------------------------------

.. automodule:: pwnlib.shellcraft.arm.linux
   :members:

---

### Source Shellcraft Common (`docs/source/shellcraft/common.rst`)

:mod:`pwnlib.shellcraft.common` --- Shellcode common to all architecture
========================================================================

.. automodule:: pwnlib.shellcraft.common
   :members:

---

### Source Shellcraft I386 (`docs/source/shellcraft/i386.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='i386')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.shellcraft.i386` --- Shellcode for Intel 80386
===========================================================

:mod:`pwnlib.shellcraft.i386`
-----------------------------

.. automodule:: pwnlib.shellcraft.i386
   :members:

:mod:`pwnlib.shellcraft.i386.linux`
-----------------------------------

.. automodule:: pwnlib.shellcraft.i386.linux
   :members:

:mod:`pwnlib.shellcraft.i386.freebsd`
-------------------------------------

.. automodule:: pwnlib.shellcraft.i386.freebsd
   :members:

---

### Source Shellcraft Loongarch64 (`docs/source/shellcraft/loongarch64.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='loongarch64')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.loongarch64` --- Shellcode for LoongArch64
==================================================================

:mod:`pwnlib.shellcraft.loongarch64`
------------------------------------

.. automodule:: pwnlib.shellcraft.loongarch64
   :members:

:mod:`pwnlib.shellcraft.loongarch64.linux`
------------------------------------------

.. automodule:: pwnlib.shellcraft.loongarch64.linux
   :members:

---

### Source Shellcraft Mips (`docs/source/shellcraft/mips.rst`)

.. testsetup:: *

   import tempfile

   from pwnlib import shellcraft

   from pwnlib.asm import asm
   from pwnlib.context import context
   from pwnlib.runner import run_assembly
   from pwnlib.util.fiddling import enhex
   from pwnlib.util.misc import write

   context.clear(arch='mips')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.mips` --- Shellcode for MIPS
===========================================================

:mod:`pwnlib.shellcraft.mips`
-----------------------------

.. automodule:: pwnlib.shellcraft.mips
   :members:

:mod:`pwnlib.shellcraft.mips.linux`
-----------------------------------

.. automodule:: pwnlib.shellcraft.mips.linux
   :members:

---

### Source Shellcraft Riscv64 (`docs/source/shellcraft/riscv64.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='riscv64')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.riscv64` --- Shellcode for RISCV64
==========================================================

:mod:`pwnlib.shellcraft.riscv64`
--------------------------------

.. automodule:: pwnlib.shellcraft.riscv64
   :members:

:mod:`pwnlib.shellcraft.riscv64.linux`
--------------------------------------

.. automodule:: pwnlib.shellcraft.riscv64.linux
   :members:

---

### Source Shellcraft Thumb (`docs/source/shellcraft/thumb.rst`)

.. testsetup:: *

   from pwn import *
   context.clear(arch='thumb')

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.shellcraft.thumb` --- Shellcode for Thumb Mode
===========================================================

:mod:`pwnlib.shellcraft.thumb`
-------------------------------

.. automodule:: pwnlib.shellcraft.thumb
   :members:

:mod:`pwnlib.shellcraft.thumb.linux`
---------------------------------------

.. automodule:: pwnlib.shellcraft.thumb.linux
   :members:

---

### Source Term Readline (`docs/source/term/readline.rst`)

.. testsetup:: *

   from pwnlib.term.readline import *
   import io

:mod:`pwnlib.term.readline` --- Terminal nice readline
======================================================

.. automodule:: pwnlib.term.readline
   :members:

---

### Source Tubes Buffer (`docs/source/tubes/buffer.rst`)

.. testsetup:: *

   from pwnlib.tubes.buffer import *

:mod:`pwnlib.tubes.buffer` --- buffer implementation for tubes
==============================================================

.. automodule:: pwnlib.tubes.buffer
   :members:

---

### Source Tubes Processes (`docs/source/tubes/processes.rst`)

.. testsetup:: *

   from pwn import *

:mod:`pwnlib.tubes.process` --- Processes
===========================================================

.. automodule:: pwnlib.tubes.process

  .. autoclass:: pwnlib.tubes.process.process
     :members:
     :show-inheritance:

---

### Source Tubes Serial (`docs/source/tubes/serial.rst`)

.. testsetup:: *

   from pwn import *

:mod:`pwnlib.tubes.serialtube` --- Serial Ports
===========================================================

.. automodule:: pwnlib.tubes.serialtube

   .. autoclass:: pwnlib.tubes.serialtube.serialtube
      :members:

---

### Source Tubes Sockets (`docs/source/tubes/sockets.rst`)

.. testsetup:: *

   from pwn import *
   from pwnlib.tubes.server import server

:mod:`pwnlib.tubes.sock` --- Sockets
===========================================================


.. automodule:: pwnlib.tubes.sock

   .. autoclass:: pwnlib.tubes.sock.sock()
      :show-inheritance:


.. automodule:: pwnlib.tubes.remote

   .. autoclass:: pwnlib.tubes.remote.remote
      :members:
      :show-inheritance:

.. automodule:: pwnlib.tubes.listen

   .. autoclass:: pwnlib.tubes.listen.listen
      :members:
      :show-inheritance:

.. automodule:: pwnlib.tubes.server

   .. autoclass:: pwnlib.tubes.server.server
      :members:
      :show-inheritance:

---

### Source Tubes Ssh (`docs/source/tubes/ssh.rst`)

.. testsetup:: *

   from pwn import *

   # TODO: Remove global POSIX flag
   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['POSIX']

:mod:`pwnlib.tubes.ssh` --- SSH
===========================================================

.. automodule:: pwnlib.tubes.ssh

   .. autoclass:: pwnlib.tubes.ssh.ssh
      :members:

   .. autoclass:: pwnlib.tubes.ssh.ssh_channel()
      :members: kill, poll, interactive
      :show-inheritance:

   .. autoclass:: pwnlib.tubes.ssh.ssh_process
      :members:
      :show-inheritance:

   .. autoclass:: pwnlib.tubes.ssh.ssh_connecter()
      :show-inheritance:

   .. autoclass:: pwnlib.tubes.ssh.ssh_listener()
      :show-inheritance:

---

### Source Util Crc (`docs/source/util/crc.rst`)

.. testsetup:: *

   from pwnlib.util.crc import *


:mod:`pwnlib.util.crc` --- Calculating CRC-sums
===============================================

.. automodule:: pwnlib.util.crc
   :members:

---

### Source Util Cyclic (`docs/source/util/cyclic.rst`)

.. testsetup:: *

   from pwn import *
   from pwnlib.util.cyclic import *


:mod:`pwnlib.util.cyclic` --- Generation of unique sequences
============================================================

.. automodule:: pwnlib.util.cyclic
   :members:

---

### Source Util Fiddling (`docs/source/util/fiddling.rst`)

.. testsetup:: *

    from pwn import *
    from pwnlib.util.fiddling import *


:mod:`pwnlib.util.fiddling` --- Utilities bit fiddling
======================================================

.. automodule:: pwnlib.util.fiddling
   :members:

---

### Source Util Getdents (`docs/source/util/getdents.rst`)

.. testsetup:: *

   from pwnlib.util.getdents import *
   from pwnlib.util.fiddling import unhex


:mod:`pwnlib.util.getdents` --- Linux binary directory listing
==============================================================

.. automodule:: pwnlib.util.getdents
   :members:

---

### Source Util Hashes (`docs/source/util/hashes.rst`)

:mod:`pwnlib.util.hashes` --- Hashing functions
===============================================

.. automodule:: pwnlib.util.hashes
   :members:

---

### Source Util Iters (`docs/source/util/iters.rst`)

.. testsetup:: *

   import string, operator
   from pwnlib.util.iters import *


:mod:`pwnlib.util.iters` --- Extension of standard module :mod:`itertools`
==========================================================================

.. automodule:: pwnlib.util.iters
   :members:
   :exclude-members:
     chain                                  ,
     combinations                           ,
     combinations_with_replacement          ,
     compress                               ,
     count                                  ,
     cycle                                  ,
     dropwhile                              ,
     filter                                 ,
     filterfalse                            ,
     groupby                                ,
     islice                                 ,
     map                                    ,
     permutations                           ,
     product                                ,
     repeat                                 ,
     starmap                                ,
     takewhile                              ,
     tee                                    ,
     zip                                    ,
     zip_longest

.. function:: chain

   Alias for :func:`itertools.chain`.

.. function:: combinations

   Alias for :func:`itertools.combinations`

.. function:: combinations_with_replacement

   Alias for :func:`itertools.combinations_with_replacement`

.. function:: compress

   Alias for :func:`itertools.compress`

.. function:: count

   Alias for :func:`itertools.count`

.. function:: cycle

   Alias for :func:`itertools.cycle`

.. function:: dropwhile

   Alias for :func:`itertools.dropwhile`

.. function:: groupby

   Alias for :func:`itertools.groupby`

.. function:: filter

   Alias for python3-style :func:`filter`

.. function:: filterfalse

   Alias for :func:`itertools.filterfalse`

.. function:: map

   Alias for python3-style :func:`map`

.. function:: islice

   Alias for :func:`itertools.islice`

.. function:: zip

   Alias for python3-style :func:`zip`

.. function:: zip_longest

   Alias for :func:`itertools.zip_longest`

.. function:: permutations

   Alias for :func:`itertools.permutations`

.. function:: product

   Alias for :func:`itertools.product`

.. function:: repeat

   Alias for :func:`itertools.repeat`

.. function:: starmap

   Alias for :func:`itertools.starmap`

.. function:: takewhile

   Alias for :func:`itertools.takewhile`

.. function:: tee

   Alias for :func:`itertools.tee`

---

### Source Util Lists (`docs/source/util/lists.rst`)

.. testsetup:: *

   from pwnlib.util.lists import *

:mod:`pwnlib.util.lists` --- Operations on lists
================================================

.. automodule:: pwnlib.util.lists
   :members:

---

### Source Util Misc (`docs/source/util/misc.rst`)

.. testsetup:: *

   from pprint import pprint
   from pwnlib.util.misc import *
   import os, subprocess

:mod:`pwnlib.util.misc` --- We could not fit it any other place
===============================================================

.. automodule:: pwnlib.util.misc
   :members:

---

### Source Util Net (`docs/source/util/net.rst`)

.. testsetup:: *

   from pwnlib.util.net import *

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']

:mod:`pwnlib.util.net` --- Networking interfaces
===================================================

.. automodule:: pwnlib.util.net
   :members:

---

### Source Util Packing (`docs/source/util/packing.rst`)

.. testsetup:: *

   from pwnlib.util.packing import *


:mod:`pwnlib.util.packing` --- Packing and unpacking of strings
===============================================================

.. automodule:: pwnlib.util.packing
   :members:

---

### Source Util Proc (`docs/source/util/proc.rst`)

.. testsetup:: *

   from pwnlib.util.proc import *
   from pwnlib.tubes.process import process
   import os, sys

   import doctest
   doctest_additional_flags = doctest.OPTIONFLAGS_BY_NAME['LINUX']


:mod:`pwnlib.util.proc` --- Working with ``/proc/``
===================================================

.. automodule:: pwnlib.util.proc
   :members:

---

### Source Util Safeeval (`docs/source/util/safeeval.rst`)

.. testsetup:: *

   from pwnlib.util.safeeval import *
   _get_opcodes = pwnlib.util.safeeval._get_opcodes


:mod:`pwnlib.util.safeeval` --- Safe evaluation of python code
==============================================================

.. automodule:: pwnlib.util.safeeval
   :members:

---

### Source Util Sh String (`docs/source/util/sh_string.rst`)

.. testsetup:: *

   from pwn import *
   test = pwnlib.util.sh_string.test

:mod:`pwnlib.util.sh_string` --- Shell Expansion is Hard
===============================================================

.. automodule:: pwnlib.util.sh_string
   :members:

---

### Source Util Web (`docs/source/util/web.rst`)

.. testsetup:: *

   import tempfile

   from pwnlib.context import context
   from pwnlib.util.web import *

:mod:`pwnlib.util.web` --- Utilities for working with the WWW
=============================================================

.. automodule:: pwnlib.util.web
   :members:

---

--- METRICS ---
- Files Extracted: 88
- Estimated Token Budget: ~16090 tokens
- Canonical Reference: https://codewiki.google/github.com/Gallopsled/pwntools
