Skip to content

Commit 76d7e21

Browse files
authored
Merge branch 'dev' into checksec-forgive-dir
2 parents 02c08c9 + 6748a78 commit 76d7e21

24 files changed

+80
-220
lines changed

.github/ISSUE_TEMPLATE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Thanks for contributing to Pwntools!
44

55
When reporting an issue, be sure that you are running the latest released version of pwntools (`pip install --upgrade pwntools`).
66

7-
Please verify that your issue occurs on 64-bit Ubuntu 14.04. You can use the Dockerfile on `docker.io` for quick testing.
7+
Please verify that your issue occurs on 64-bit Ubuntu 22.04. You can use the Dockerfile on `docker.io` for quick testing.
88

99
```
1010
$ docker pull pwntools/pwntools:stable

.github/workflows/ci.yml

-28
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ jobs:
77
matrix:
88
python_version: ['3.10', '3.12']
99
os: [ubuntu-latest]
10-
include:
11-
- python_version: '2.7'
12-
os: ubuntu-22.04
1310
runs-on: ${{ matrix.os }}
1411
timeout-minutes: 30
1512
services:
@@ -66,17 +63,8 @@ jobs:
6663
sudo apt-get update && sudo apt-get install -y python3-pip gdb gdbserver
6764
/usr/bin/python -m pip install --break-system-packages rpyc || /usr/bin/python -m pip install rpyc
6865
gdb --batch --quiet --nx --nh --ex 'py import rpyc; print(rpyc.version.version)'
69-
70-
- name: Cache for pip
71-
uses: actions/cache@v4
72-
if: matrix.python_version == '2.7'
73-
with:
74-
path: ~/.cache/pip
75-
key: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-${{ hashFiles('**/pyproject.toml', '**/requirements*.txt') }}
76-
restore-keys: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-
7766
7867
- name: Set up Python ${{ matrix.python_version }}
79-
if: matrix.python_version != '2.7'
8068
uses: actions/setup-python@v5
8169
with:
8270
python-version: ${{ matrix.python_version }}
@@ -85,17 +73,6 @@ jobs:
8573
**/pyproject.toml
8674
**/requirements*.txt
8775
88-
- name: Set up Python 2.7
89-
if: matrix.python_version == '2.7'
90-
run: |
91-
sudo apt-get update
92-
sudo apt-get install -y \
93-
python2.7 python2.7-dev python2-pip-whl
94-
sudo ln -sf python2.7 /usr/bin/python
95-
export PYTHONPATH=`echo /usr/share/python-wheels/pip-*py2*.whl`
96-
sudo --preserve-env=PYTHONPATH python -m pip install --upgrade pip setuptools wheel
97-
sudo chown -R $USER /usr/local/lib/python2.7
98-
9976
10077
- name: Verify tag against version
10178
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
@@ -155,10 +132,6 @@ jobs:
155132
- name: Install documentation dependencies
156133
run: pip install -r docs/requirements.txt
157134

158-
- name: Manually install non-broken Unicorn
159-
if: matrix.python_version == '2.7'
160-
run: pip install unicorn==2.0.0rc7
161-
162135
- name: Disable yama ptrace_scope
163136
run: |
164137
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # required by some gdb doctests
@@ -244,7 +217,6 @@ jobs:
244217
pwn libcdb hash b229d1da1e161f95e839cf90cded5f719e5de308
245218
246219
- name: Build source and wheel distributions
247-
if: matrix.python_version != '2.7'
248220
run: |
249221
python -m build
250222

CHANGELOG.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,26 @@ The table below shows which release corresponds to each branch, and what date th
7474

7575
## 5.0.0 (`dev`)
7676

77-
- [#2530][2530] Do NOT error when passing directory arguments in `checksec`.
77+
- [#2519][2519] Drop Python 2.7 support / Require Python 3.10
7878
- [#2507][2507] Add `+LINUX` and `+WINDOWS` doctest options and start proper testing on Windows
7979
- [#2522][2522] Support starting a kitty debugging window with the 'kitten' command
8080
- [#2524][2524] Raise EOFError during `process.recv` when stdout closes on Windows
8181
- [#2526][2526] Properly make use of extra arguments in `packing` utilities. `sign` parameter requires keyword syntax to specify it.
8282
- [#2517][2517] Allow to passthru kwargs on `ssh.__getattr__` convenience function to fix SSH motd problems
83+
- [#2527][2527] Allow setting debugger path via `context.gdb_binary`
84+
- [#2530][2530] Do NOT error when passing directory arguments in `checksec` commandline tool.
8385

86+
[2519]: https://github.com/Gallopsled/pwntools/pull/2519
8487
[2507]: https://github.com/Gallopsled/pwntools/pull/2507
8588
[2522]: https://github.com/Gallopsled/pwntools/pull/2522
8689
[2524]: https://github.com/Gallopsled/pwntools/pull/2524
8790
[2526]: https://github.com/Gallopsled/pwntools/pull/2526
8891
[2517]: https://github.com/Gallopsled/pwntools/pull/2517
92+
[2527]: https://github.com/Gallopsled/pwntools/pull/2527
93+
[2530]: https://github.com/Gallopsled/pwntools/pull/2530
8994

9095
## 4.15.0 (`beta`)
96+
9197
- [#2508][2508] Ignore a warning when compiling with asm on nix
9298
- [#2471][2471] Properly close spawned kitty window
9399
- [#2358][2358] Cache output of `asm()`

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ To get you started, we've provided some example solutions for past CTF challenge
3232

3333
# Installation
3434

35-
Pwntools is best supported on 64-bit Ubuntu LTS releases (18.04, 20.04, 22.04, and 24.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).
35+
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.).
3636

37-
Python3 is suggested, but Pwntools still works with Python 2.7. Most of the functionality of pwntools is self-contained and Python-only. You should be able to get running quickly with
37+
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
3838

3939
```sh
4040
sudo apt-get update

TESTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Pwntools makes extensive use of unit tests and integration tests to ensure every
44

55
## Test Suite
66

7-
To run the test suite, it is best to use Ubuntu 12.04 or 14.04, and run the following commands. **Be aware** that this will add a user to the machine, and create a public key for SSH login!
7+
To run the test suite, it is best to use Ubuntu 22.04 or 24.04, and run the following commands. **Be aware** that this will add a user to the machine, and create a public key for SSH login!
88

99
```sh
1010
bash travis/install.sh
@@ -15,7 +15,7 @@ PWNLIB_NOTERM=1 make -C docs doctest
1515

1616
## Testing in Docker
1717

18-
A `Dockerfile` has been provided which has a clean testing environment with Ubuntu Xenial. It is very similar to the online Travis CI testing environment, but uses a more modern version of Ubuntu.
18+
A `Dockerfile` has been provided which has a clean testing environment with Ubuntu Jammy. It is very similar to the online Github Actions CI testing environment, but uses a more modern version of Ubuntu.
1919

2020
See `travis/docker/README.md` for more information.
2121

docs/requirements.txt

+3-6
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@ capstone
22
coverage[toml]
33
python-dateutil
44
doc2dash
5-
docutils<0.18; python_version<'3'
6-
docutils>=0.18; python_version>='3'
5+
docutils>=0.18
76
intervaltree
87
isort
98
mako>=1.0.0
109
paramiko>=1.15.2
1110
pip>=6.0.8
12-
pyelftools>=0.29, <0.30; python_version<'3'
13-
pyelftools>=0.29; python_version>='3'
11+
pyelftools>=0.29
1412
pygments>=2.0
1513
pypandoc
1614
pyserial>=2.7
1715
pysocks
1816
psutil
1917
requests>=2.5.1
2018
ropgadget>=5.3
21-
sphinx==1.8.6; python_version<'3'
22-
sphinx>=8.1.3, <9; python_version>='3'
19+
sphinx>=8.1.3, <9
2320
sphinx_rtd_theme
2421
sphinxcontrib-autoprogram<=0.1.5

docs/source/conf.py

+8-47
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ def __setattr__(self, name, value):
9999
travis_ci = os.environ.get('USER') == 'travis'
100100
local_doctest = os.environ.get('USER') == 'pwntools'
101101
skip_android = True
102-
is_python2 = six.PY2
103102
'''
104103

105104
autoclass_content = 'both'
@@ -388,16 +387,13 @@ def linkcode_resolve(domain, info):
388387

389388

390389
# -- Customization to Sphinx autodoc generation --------------------------------------------
391-
import sphinx.ext.autodoc
392390

393391
# Test hidden members (e.g. def _foo(...))
394392
def dont_skip_any_doctests(app, what, name, obj, skip, options):
395393
return None
396394

397395
autodoc_default_options = {'special-members': None, 'private-members': None}
398396

399-
class _DummyClass(object): pass
400-
401397
# doctest optionflags for platform-specific tests
402398
# they are skipped on other platforms
403399
WINDOWS = doctest.register_optionflag('WINDOWS')
@@ -407,33 +403,6 @@ class _DummyClass(object): pass
407403
# doctest optionflag for tests that haven't been looked at yet
408404
TODO = doctest.register_optionflag('TODO')
409405

410-
class Py2OutputChecker(_DummyClass, doctest.OutputChecker):
411-
def check_output(self, want, got, optionflags):
412-
sup = super(Py2OutputChecker, self).check_output
413-
if sup(want, got, optionflags):
414-
return True
415-
try:
416-
rly_want = pwnlib.util.safeeval.const(want)
417-
if sup(repr(rly_want), got, optionflags):
418-
return True
419-
rly_got = pwnlib.util.safeeval.const(got)
420-
if rly_want == rly_got:
421-
return True
422-
except ValueError:
423-
pass
424-
rly_want = ' '.join(x[:2].replace('b"','"').replace("b'","'")+x[2:] for x in want.replace('\n','\n ').split(' ')).replace('\n ','\n')
425-
if sup(rly_want, got, optionflags):
426-
return True
427-
rly_want = ' '.join(x[:2].replace('b"',' "').replace("b'"," '")+x[2:] for x in want.replace('\n','\n ').split(' ')).replace('\n ','\n')
428-
if sup(rly_want, got, optionflags):
429-
return True
430-
for wantl, gotl in six.moves.zip_longest(want.splitlines(), got.splitlines(), fillvalue=''):
431-
rly_want1 = '['.join(x[:2].replace('b"','"').replace("b'","'")+x[2:] for x in wantl.split('['))
432-
rly_want2 = ' '.join(x[:2].replace('b"',' "').replace("b'"," '")+x[2:] for x in wantl.split(' '))
433-
if not sup(rly_want1, gotl, optionflags) and not sup(rly_want2, gotl, optionflags):
434-
return False
435-
return True
436-
437406
import sphinx.ext.doctest
438407

439408
class PlatformDocTestRunner(sphinx.ext.doctest.SphinxDocTestRunner):
@@ -471,24 +440,16 @@ def test_runner(self):
471440
def test_runner(self, value):
472441
self._test_runner = PlatformDocTestRunner(value._checker, value._verbose, value.optionflags)
473442

474-
def py2_doctest_init(self, checker=None, verbose=None, optionflags=0):
475-
if checker is None:
476-
checker = Py2OutputChecker()
477-
doctest.DocTestRunner.__init__(self, checker, verbose, optionflags)
478-
479443
if 'doctest' in sys.argv:
444+
def setup(app):
445+
app.add_builder(PlatformDocTestBuilder, override=True)
446+
# app.connect('autodoc-skip-member', dont_skip_any_doctests)
447+
# monkey patching paramiko due to https://github.com/paramiko/paramiko/pull/1661
448+
import paramiko.client
449+
import binascii
450+
paramiko.client.hexlify = lambda x: binascii.hexlify(x).decode()
451+
paramiko.util.safe_string = lambda x: '' # function result never *actually used*
480452

481-
if sys.version_info[:1] < (3,):
482-
sphinx.ext.doctest.SphinxDocTestRunner.__init__ = py2_doctest_init
483-
else:
484-
def setup(app):
485-
app.add_builder(PlatformDocTestBuilder, override=True)
486-
# app.connect('autodoc-skip-member', dont_skip_any_doctests)
487-
# monkey patching paramiko due to https://github.com/paramiko/paramiko/pull/1661
488-
import paramiko.client
489-
import binascii
490-
paramiko.client.hexlify = lambda x: binascii.hexlify(x).decode()
491-
paramiko.util.safe_string = lambda x: '' # function result never *actually used*
492453
class EndlessLoop(Exception): pass
493454
if hasattr(signal, 'alarm'):
494455
def alrm_handler(sig, frame):

docs/source/install.rst

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Installation
22
============
33

4-
Pwntools is best supported on 64-bit Ubuntu LTS releases (14.04, 16.04, 18.04, and 20.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).
4+
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.).
55

66
Prerequisites
77
-------------
@@ -21,11 +21,13 @@ Note: For Mac OS X you will need to have cmake ``brew install cmake`` and pkg-co
2121
Released Version
2222
-----------------
2323

24-
pwntools is available as a ``pip`` package for both Python2 and Python3.
24+
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.
2525

2626
Python3
2727
^^^^^^^
2828

29+
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.
30+
2931
.. code-block:: bash
3032
3133
$ sudo apt-get update
@@ -37,6 +39,8 @@ Python3
3739
Python2 (Deprecated)
3840
^^^^^^^^^^^^^^^^^^^^
3941

42+
Python2 support has been removed in Pwntools v5.0.0. The last version to support Python2 was v4.15.0.
43+
4044
NOTE: Pwntools maintainers STRONGLY recommend using Python3 for all future Pwntools-based scripts and projects.
4145

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

extra/docker/base/Dockerfile

-5
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ RUN apt-get update \
2020
git \
2121
libssl-dev \
2222
libffi-dev \
23-
python2.7 \
24-
python2.7-dev \
25-
python2-pip-whl \
2623
python3 \
2724
python3-pip \
2825
python3-dev \
@@ -40,8 +37,6 @@ RUN apt-get update \
4037
patchelf \
4138
&& locale-gen en_US.UTF-8 \
4239
&& update-locale LANG=en_US.UTF-8 \
43-
&& PYTHONPATH=`echo /usr/share/python-wheels/pip-*.whl` python2.7 -m pip install --no-cache-dir --upgrade pip setuptools wheel \
44-
&& python2.7 -m pip install --no-cache-dir --upgrade pwntools \
4540
&& python3 -m pip install --no-cache-dir --upgrade pip \
4641
&& python3 -m pip install --no-cache-dir --upgrade pwntools \
4742
&& PWNLIB_NOTERM=1 pwn update \

extra/docker/beta/Dockerfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
FROM pwntools/pwntools:stable
22

33
USER root
4-
RUN python2.7 -m pip install --no-cache-dir --upgrade git+https://github.com/Gallopsled/pwntools@beta \
5-
&& python3 -m pip install --no-cache-dir --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@beta
4+
RUN python3 -m pip install --no-cache-dir --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@beta
65
RUN PWNLIB_NOTERM=1 pwn update
76
USER pwntools

extra/docker/buster/Dockerfile

-8
This file was deleted.

extra/docker/dev/Dockerfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
FROM pwntools/pwntools:stable
22

33
USER root
4-
RUN python2.7 -m pip install --upgrade git+https://github.com/Gallopsled/pwntools@dev \
5-
&& python3 -m pip install --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@dev
4+
RUN python3 -m pip install --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@dev
65
RUN PWNLIB_NOTERM=1 pwn update
76
USER pwntools

extra/docker/develop/Dockerfile

+3-7
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ ENV HISTFILE=/home/pwntools/.history
55

66
# Uninstall existing versions of pwntools
77
USER root
8-
RUN python2.7 -m pip uninstall -q -y pwntools \
9-
&& python3 -m pip uninstall -q -y pwntools
8+
RUN python3 -m pip uninstall -q -y pwntools
109

1110
# Switch back to the pwntools user from here forward
1211
USER pwntools
@@ -18,17 +17,14 @@ ENV PATH="/home/pwntools/.local/bin:${PATH}"
1817

1918
# Install Pwntools to the home directory, make it an editable install
2019
RUN git clone https://github.com/Gallopsled/pwntools \
21-
&& python2.7 -m pip install --upgrade --editable pwntools \
2220
&& python3 -m pip install --upgrade --editable pwntools \
2321
&& PWNLIB_NOTERM=1 pwn version
2422

2523
# Requirements for running the tests
26-
RUN python2.7 -m pip install --upgrade --requirement pwntools/docs/requirements.txt \
27-
&& python3 -m pip install --upgrade --requirement pwntools/docs/requirements.txt
24+
RUN python3 -m pip install --upgrade --requirement pwntools/docs/requirements.txt
2825

2926
# Python niceties for debugging
30-
RUN python2.7 -m pip install -U ipython ipdb \
31-
&& python3 -m pip install -U ipython ipdb
27+
RUN python3 -m pip install -U ipython ipdb
3228

3329
# Dependencies from .travis.yml addons -> apt -> packages
3430
ARG DEBIAN_FRONTEND=noninteractive

extra/docker/stable/Dockerfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
FROM pwntools/pwntools:base
22

33
USER root
4-
RUN python2.7 -m pip install --no-cache-dir --upgrade git+https://github.com/Gallopsled/pwntools@stable \
5-
&& python3 -m pip install --no-cache-dir --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@stable
4+
RUN python3 -m pip install --no-cache-dir --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@stable
65
RUN PWNLIB_NOTERM=1 pwn update
76
USER pwntools

pwnlib/context/__init__.py

+15
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ class ContextType(object):
363363
'encoding': 'auto',
364364
'endian': 'little',
365365
'gdbinit': "",
366+
'gdb_binary': "",
366367
'kernel': None,
367368
'local_libcdb': "/var/lib/libc-database",
368369
'log_level': logging.INFO,
@@ -1546,6 +1547,20 @@ def gdbinit(self, value):
15461547
"""
15471548
return str(value)
15481549

1550+
@_validator
1551+
def gdb_binary(self, value):
1552+
"""Path to the binary that is used when running GDB locally.
1553+
1554+
This is useful when you have multiple versions of gdb installed or the gdb binary is
1555+
called something different.
1556+
1557+
If set to an empty string, pwntools will try to search for a reasonable gdb binary from
1558+
the path.
1559+
1560+
Default value is ``""``.
1561+
"""
1562+
return str(value)
1563+
15491564
@_validator
15501565
def cyclic_alphabet(self, alphabet):
15511566
"""Cyclic alphabet.

0 commit comments

Comments
 (0)