diff --git a/pwndbg/aglib/disasm/__init__.py b/pwndbg/aglib/disasm/__init__.py index 2819d4e30..ea896ee8e 100644 --- a/pwndbg/aglib/disasm/__init__.py +++ b/pwndbg/aglib/disasm/__init__.py @@ -300,19 +300,9 @@ def can_run_first_emulate() -> bool: first_time_emulate = False try: - from mmap import mmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE # isort:skip - - access_mode = PROT_WRITE | PROT_READ | PROT_EXEC - if sys.platform == "darwin": - # On macOS (Darwin), creating mmap with 'rwx' permissions is blocked - # by System Integrity Protection (SIP), which prevents execution of code - # from writable and readable memory regions. Therefore, we restrict - # the access mode to 'rw' (read and write only). - access_mode = PROT_WRITE | PROT_READ - - mm = mmap( # novm - -1, 1024 * 1024 * 1024, MAP_PRIVATE | MAP_ANON, access_mode - ) + from mmap import mmap + + mm = mmap(-1, 1024 * 1024 * 1024) mm.close() except OSError: print( diff --git a/pwndbg/dbg/lldb/repl/readline.py b/pwndbg/dbg/lldb/repl/readline.py index c3eee9263..f25ddd64f 100644 --- a/pwndbg/dbg/lldb/repl/readline.py +++ b/pwndbg/dbg/lldb/repl/readline.py @@ -9,11 +9,20 @@ from __future__ import annotations import contextlib import functools import os.path +import sys from typing import Callable from typing import ParamSpec from typing import TypeVar -import gnureadline as readline +if sys.platform != "win32": + import gnureadline as readline +else: + import readline + + # pyreadline3 doesn't implement `set_completion_display_matches_hook` + if not hasattr(readline, "set_completion_display_matches_hook"): + readline.set_completion_display_matches_hook = lambda *args: None + import lldb from pwndbg.color import message diff --git a/pwndbg/ui.py b/pwndbg/ui.py index 83e8845e9..616687a05 100644 --- a/pwndbg/ui.py +++ b/pwndbg/ui.py @@ -4,11 +4,8 @@ A few helpers for making things print pretty-like. from __future__ import annotations -import fcntl import os -import struct import sys -import termios import pwndbg.color.context as C import pwndbg.dbg @@ -70,19 +67,22 @@ def get_window_size(target=sys.stdout): fallback = (int(os.environ.get("LINES", 20)), int(os.environ.get("COLUMNS", 80))) if not target.isatty(): return fallback + if os.environ.get("PWNDBG_IN_TEST") is not None: + return fallback + if target in (sys.stdout, sys.stdin): # We can ask the debugger for the window size rows, cols = get_cmd_window_size() if rows is not None and cols is not None: return rows, cols - if os.environ.get("PWNDBG_IN_TEST") is not None: - return fallback + try: - # get terminal size and force ret buffer len of 4 bytes for safe unpacking by passing equally long arg - rows, cols = struct.unpack("hh", fcntl.ioctl(target.fileno(), termios.TIOCGWINSZ, b"1234")) + term = os.get_terminal_size(target.fileno()) + return term.lines, term.columns except Exception: - rows, cols = fallback - return rows, cols + pass + + return fallback def get_cmd_window_size(): diff --git a/pyproject.toml b/pyproject.toml index 647233002..bd775e679 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,8 @@ dependencies = [ [project.optional-dependencies] lldb = [ # The LLDB REPL requires readline. - "gnureadline>=8.2.10,<9" + 'gnureadline>=8.2.10,<9; sys_platform != "win32"', + 'pyreadline3>=3.5.4,<4; sys_platform == "win32"' ] gdb = [] diff --git a/uv.lock b/uv.lock index 7c9dae61c..97890bf13 100644 --- a/uv.lock +++ b/uv.lock @@ -1145,7 +1145,8 @@ dependencies = [ [package.optional-dependencies] lldb = [ - { name = "gnureadline" }, + { name = "gnureadline", marker = "sys_platform != 'win32'" }, + { name = "pyreadline3", marker = "sys_platform == 'win32'" }, ] [package.dev-dependencies] @@ -1185,13 +1186,14 @@ tests = [ [package.metadata] requires-dist = [ { name = "capstone", specifier = ">=5.0.3,<6" }, - { name = "gnureadline", marker = "extra == 'lldb'", specifier = ">=8.2.10,<9" }, + { name = "gnureadline", marker = "sys_platform != 'win32' and extra == 'lldb'", specifier = ">=8.2.10,<9" }, { name = "ipython", specifier = ">=8.27.0,<9" }, { name = "pt", git = "https://github.com/martinradev/gdb-pt-dump?rev=50227bda0b6332e94027f811a15879588de6d5cb" }, { name = "pwntools", specifier = ">=4.14.0,<5" }, { name = "pycparser", specifier = "~=2.22" }, { name = "pyelftools", specifier = ">=0.29,<0.30" }, { name = "pygments", specifier = ">=2.18.0,<3" }, + { name = "pyreadline3", marker = "sys_platform == 'win32' and extra == 'lldb'", specifier = ">=3.5.4,<4" }, { name = "requests", specifier = ">=2.32.3,<3" }, { name = "rich", specifier = ">=13.7.1,<14" }, { name = "ropgadget", specifier = "==7.3" }, @@ -1328,6 +1330,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5e/22/d3db169895faaf3e2eda892f005f433a62db2decbcfbc2f61e6517adfa87/PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", size = 212141 }, ] +[[package]] +name = "pyreadline3" +version = "3.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178 }, +] + [[package]] name = "pyserial" version = "3.5"