pyx64dbg 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. pyx64dbg-0.1.0/LICENSE +21 -0
  2. pyx64dbg-0.1.0/MANIFEST.in +5 -0
  3. pyx64dbg-0.1.0/PKG-INFO +163 -0
  4. pyx64dbg-0.1.0/README.md +108 -0
  5. pyx64dbg-0.1.0/pyproject.toml +45 -0
  6. pyx64dbg-0.1.0/pyx64dbg/CLI/__init__.py +0 -0
  7. pyx64dbg-0.1.0/pyx64dbg/CLI/ipython_cli.py +83 -0
  8. pyx64dbg-0.1.0/pyx64dbg/CLI/main.py +34 -0
  9. pyx64dbg-0.1.0/pyx64dbg/GUI/__init__.py +0 -0
  10. pyx64dbg-0.1.0/pyx64dbg/GUI/assets/icon.svg +38 -0
  11. pyx64dbg-0.1.0/pyx64dbg/GUI/async_slot.py +25 -0
  12. pyx64dbg-0.1.0/pyx64dbg/GUI/breakpoints_view.py +155 -0
  13. pyx64dbg-0.1.0/pyx64dbg/GUI/debug_controls_view.py +159 -0
  14. pyx64dbg-0.1.0/pyx64dbg/GUI/debugger_state.py +18 -0
  15. pyx64dbg-0.1.0/pyx64dbg/GUI/debugger_worker.py +357 -0
  16. pyx64dbg-0.1.0/pyx64dbg/GUI/disassembly_view.py +418 -0
  17. pyx64dbg-0.1.0/pyx64dbg/GUI/extended_registers_view.py +280 -0
  18. pyx64dbg-0.1.0/pyx64dbg/GUI/interactive_console_view.py +47 -0
  19. pyx64dbg-0.1.0/pyx64dbg/GUI/main.py +44 -0
  20. pyx64dbg-0.1.0/pyx64dbg/GUI/main_window.py +440 -0
  21. pyx64dbg-0.1.0/pyx64dbg/GUI/placeholders.py +64 -0
  22. pyx64dbg-0.1.0/pyx64dbg/GUI/pty_view/index.html +67 -0
  23. pyx64dbg-0.1.0/pyx64dbg/GUI/pty_view/xterm-addon-fit.js +2 -0
  24. pyx64dbg-0.1.0/pyx64dbg/GUI/pty_view/xterm.css +209 -0
  25. pyx64dbg-0.1.0/pyx64dbg/GUI/pty_view/xterm.js +2 -0
  26. pyx64dbg-0.1.0/pyx64dbg/GUI/pty_view.py +151 -0
  27. pyx64dbg-0.1.0/pyx64dbg/GUI/registers_view.py +130 -0
  28. pyx64dbg-0.1.0/pyx64dbg/GUI/stdio_view.py +49 -0
  29. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/breakpoints_view.qss +35 -0
  30. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/disassembly_view.qss +64 -0
  31. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/extended_registers_view.qss +24 -0
  32. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/main_window.qss +9 -0
  33. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/registers_view.qss +36 -0
  34. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/symbols_view.qss +36 -0
  35. pyx64dbg-0.1.0/pyx64dbg/GUI/styles/watch_view.qss +11 -0
  36. pyx64dbg-0.1.0/pyx64dbg/GUI/symbols_view.py +141 -0
  37. pyx64dbg-0.1.0/pyx64dbg/GUI/top_menu.py +98 -0
  38. pyx64dbg-0.1.0/pyx64dbg/GUI/utils.py +36 -0
  39. pyx64dbg-0.1.0/pyx64dbg/GUI/watch_view.py +198 -0
  40. pyx64dbg-0.1.0/pyx64dbg/__init__.py +9 -0
  41. pyx64dbg-0.1.0/pyx64dbg/breakpoint.py +61 -0
  42. pyx64dbg-0.1.0/pyx64dbg/callback_list.py +32 -0
  43. pyx64dbg-0.1.0/pyx64dbg/control.py +260 -0
  44. pyx64dbg-0.1.0/pyx64dbg/debugger.py +225 -0
  45. pyx64dbg-0.1.0/pyx64dbg/get_mappings.py +186 -0
  46. pyx64dbg-0.1.0/pyx64dbg/interactive_console/__init__.py +0 -0
  47. pyx64dbg-0.1.0/pyx64dbg/interactive_console/console_aliases.py +115 -0
  48. pyx64dbg-0.1.0/pyx64dbg/interactive_console/console_functions.py +92 -0
  49. pyx64dbg-0.1.0/pyx64dbg/interactive_console/disassembly_function.py +158 -0
  50. pyx64dbg-0.1.0/pyx64dbg/interactive_console/exception_trap.py +25 -0
  51. pyx64dbg-0.1.0/pyx64dbg/interactive_console/exceptions.py +25 -0
  52. pyx64dbg-0.1.0/pyx64dbg/interactive_console/interactive_console.py +182 -0
  53. pyx64dbg-0.1.0/pyx64dbg/memory.py +381 -0
  54. pyx64dbg-0.1.0/pyx64dbg/number_types/__init__.pyi +1557 -0
  55. pyx64dbg-0.1.0/pyx64dbg/number_types/number_types.cpp +774 -0
  56. pyx64dbg-0.1.0/pyx64dbg/parse_elf.py +127 -0
  57. pyx64dbg-0.1.0/pyx64dbg/process_exited_error.py +23 -0
  58. pyx64dbg-0.1.0/pyx64dbg/ptrace/__init__.pyi +60 -0
  59. pyx64dbg-0.1.0/pyx64dbg/ptrace/ptrace.cpp +317 -0
  60. pyx64dbg-0.1.0/pyx64dbg/ptrace/utils.cpp +31 -0
  61. pyx64dbg-0.1.0/pyx64dbg/ptrace/utils.hpp +22 -0
  62. pyx64dbg-0.1.0/pyx64dbg/ptrace/xstate.cpp +219 -0
  63. pyx64dbg-0.1.0/pyx64dbg/ptrace/xstate.hpp +25 -0
  64. pyx64dbg-0.1.0/pyx64dbg/py.typed +0 -0
  65. pyx64dbg-0.1.0/pyx64dbg/registers.py +383 -0
  66. pyx64dbg-0.1.0/pyx64dbg/shared_object.py +21 -0
  67. pyx64dbg-0.1.0/pyx64dbg/stack.py +230 -0
  68. pyx64dbg-0.1.0/pyx64dbg/stdio_tube.py +135 -0
  69. pyx64dbg-0.1.0/pyx64dbg/symbols.py +145 -0
  70. pyx64dbg-0.1.0/pyx64dbg/vector_register.py +436 -0
  71. pyx64dbg-0.1.0/pyx64dbg.egg-info/PKG-INFO +163 -0
  72. pyx64dbg-0.1.0/pyx64dbg.egg-info/SOURCES.txt +76 -0
  73. pyx64dbg-0.1.0/pyx64dbg.egg-info/dependency_links.txt +1 -0
  74. pyx64dbg-0.1.0/pyx64dbg.egg-info/entry_points.txt +3 -0
  75. pyx64dbg-0.1.0/pyx64dbg.egg-info/requires.txt +11 -0
  76. pyx64dbg-0.1.0/pyx64dbg.egg-info/top_level.txt +1 -0
  77. pyx64dbg-0.1.0/setup.cfg +4 -0
  78. pyx64dbg-0.1.0/setup.py +34 -0
pyx64dbg-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yoav Shamay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include LICENSE
2
+ include README.md
3
+
4
+ recursive-include pyx64dbg *.cpp
5
+ recursive-include pyx64dbg *.hpp
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyx64dbg
3
+ Version: 0.1.0
4
+ Summary: A debugger implemented in Python
5
+ Author-email: Yoav Shamay <yoavsh97@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Yoav Shamay
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/yoav-shamay/pyx64dbg
28
+ Project-URL: Repository, https://github.com/yoav-shamay/pyx64dbg
29
+ Keywords: debugger,ptrace,x86-64,linux
30
+ Classifier: Operating System :: POSIX :: Linux
31
+ Classifier: Development Status :: 3 - Alpha
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Programming Language :: Python :: 3.13
39
+ Classifier: Programming Language :: Python :: 3.14
40
+ Classifier: Topic :: Software Development :: Debuggers
41
+ Requires-Python: >=3.10
42
+ Description-Content-Type: text/markdown
43
+ License-File: LICENSE
44
+ Requires-Dist: capstone
45
+ Requires-Dist: pyelftools
46
+ Requires-Dist: ipython
47
+ Requires-Dist: prompt_toolkit
48
+ Requires-Dist: pyside6
49
+ Requires-Dist: nest_asyncio
50
+ Provides-Extra: dev
51
+ Requires-Dist: black; extra == "dev"
52
+ Requires-Dist: jinja2; extra == "dev"
53
+ Requires-Dist: pytest; extra == "dev"
54
+ Dynamic: license-file
55
+
56
+ # PyX64Dbg
57
+
58
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)
59
+ ![Platform](https://img.shields.io/badge/platform-Linux_x86__64-lightgrey.svg)
60
+ ![License](https://img.shields.io/badge/license-MIT-green.svg)
61
+
62
+ **PyX64Dbg** is a Python-based debugger for x86-64 Linux binaries.
63
+
64
+ PyX64Dbg utilizes the Linux `ptrace` system call and the `/proc` filesystem (`procfs`) to trace and introspect ELF processes. These low-level operating system primitives are abstracted into an intuitive Python object model, enabling direct manipulation of process memory, CPU registers, and execution flow.
65
+
66
+ The tool features through three primary interfaces: a **Python API** designed for automated reverse engineering and binary analysis, a **Graphical User Interface (GUI)** for visual debugging, and a robust **IPython-based CLI** for debugging from the terminal.
67
+
68
+ ## Key Features
69
+
70
+ - **Python API:** Automate reverse engineering, exploit development, or testing using a clean, object-oriented interface. Unlike GDB, PyX64Dbg acts as a standard Python library you can import and use anywhere.
71
+ - **Graphical Interface (GUI):** Built with PySide6, featuring disassembly views, memory watches, register panels, and an embedded interactive terminal.
72
+ - **Command Line Interface (CLI):** An interactive IPython REPL that supports live Python syntax, auto-completion, and inline evaluation.
73
+ - **Advanced Target Support:** Native handling of PIE (Position Independent Executables), ASLR, shared libraries (`ld.so`), and dynamic symbols.
74
+ - **C-Like Type System:** A custom extension providing native types (`Int32`, `UInt64`, `Float80`, etc.) that strictly follow C promotion, overflow, and truncation rules.
75
+ - **Extended Registers (AVX/SSE):** Supports CPU `xstate`, including `XMM`, `YMM`, and FPU (`st`) vector registers. The API allows you to seamlessly treat vector data as a C-style union across all possible integer and floating-point array representations.
76
+
77
+ ## Prerequisites
78
+
79
+ - **Operating System**: Linux (x86-64 architecture only)
80
+ - **Python**: 3.10 or later
81
+ - **C++ Compiler**: A C++20 compatible compiler (e.g., `g++` or `clang`) and Python development headers are required to compile the `ptrace` and numeric type extensions during installation.
82
+
83
+ ## Installation
84
+
85
+ ### From PyPI (Recommended)
86
+ ```bash
87
+ pip install pyx64dbg
88
+ ```
89
+
90
+ ### From Source (Development)
91
+ Clone the repository and install it in editable mode:
92
+ ```bash
93
+ git clone https://github.com/yoav-shamay/pyx64dbg.git
94
+ cd pyx64dbg
95
+ pip install -e .
96
+ ```
97
+
98
+ ## Usage
99
+
100
+ ### Graphical Interface (GUI)
101
+ Start the visual debugger (requires a desktop session like X11 or Wayland):
102
+ ```bash
103
+ pyx64dbg-gui
104
+ ```
105
+ *Tip: The full IPython CLI is embedded directly into the GUI and is available via the "Interactive Console" tab at the bottom.*
106
+
107
+ ### Command Line Interface (CLI)
108
+ Launch the interactive IPython console:
109
+ ```bash
110
+ pyx64dbg [/path/to/binary]
111
+ ```
112
+ Once inside, simply type `help` to see a list of available commands and aliases (e.g., `run`, `step`, `bps`, `dis`).
113
+
114
+ ## Python API Showcase
115
+
116
+ PyX64Dbg is built to be scripted. You can easily interact with binaries directly from Python.
117
+
118
+ ```python
119
+ from pyx64dbg import Debugger
120
+ from pyx64dbg.number_types import UInt64
121
+
122
+ # 1. Spawn process and attach debugger
123
+ dbg = Debugger.start_and_debug("./target_binary")
124
+
125
+ # 2. Set a breakpoint at the 'main' function
126
+ main_addr = dbg.symbols["main"]
127
+ dbg.breakpoints.add_breakpoint(main_addr)
128
+
129
+ # 3. Run until the breakpoint is hit
130
+ dbg.control.continue_execution()
131
+
132
+ # 4. Read memory and native vector registers
133
+ rip = dbg.registers.rip
134
+ rsp_val = dbg.memory.read_number(dbg.registers.rsp, UInt64)
135
+ ymm0_floats = dbg.registers.ymm0.f32 # Access YMM0 as an array of 32-bit floats
136
+
137
+ print(f"[+] Halted at RIP: 0x{rip:x}")
138
+ print(f"[+] Stack pointer value: 0x{rsp_val:x}")
139
+ print(f"[+] YMM0 state: {ymm0_floats}")
140
+
141
+ # 5. Clean up - kill the process
142
+ dbg.control.kill_process()
143
+ ```
144
+
145
+ ## Limitations
146
+
147
+ - Supported exclusively on Linux ELF binaries running on `x86-64`.
148
+ - Relies on the `ptrace` system call and the `/proc` filesystem. It will not function in hardened environments where these features are disabled.
149
+
150
+ ## Testing
151
+
152
+ The repository includes a suite of integration tests that run against provided pre-compiled C binaries to verify register states, memory reading, and edge cases.
153
+
154
+ To run the tests:
155
+ ```bash
156
+ pytest test/
157
+ ```
158
+
159
+ *Note: If you wish to rebuild the test executables from source, a `Makefile` is provided in `test/executables/`. Rebuilding may cause certain tests to fail if the compiler generates different instruction offsets.*
160
+
161
+ ## License
162
+
163
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,108 @@
1
+ # PyX64Dbg
2
+
3
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)
4
+ ![Platform](https://img.shields.io/badge/platform-Linux_x86__64-lightgrey.svg)
5
+ ![License](https://img.shields.io/badge/license-MIT-green.svg)
6
+
7
+ **PyX64Dbg** is a Python-based debugger for x86-64 Linux binaries.
8
+
9
+ PyX64Dbg utilizes the Linux `ptrace` system call and the `/proc` filesystem (`procfs`) to trace and introspect ELF processes. These low-level operating system primitives are abstracted into an intuitive Python object model, enabling direct manipulation of process memory, CPU registers, and execution flow.
10
+
11
+ The tool features through three primary interfaces: a **Python API** designed for automated reverse engineering and binary analysis, a **Graphical User Interface (GUI)** for visual debugging, and a robust **IPython-based CLI** for debugging from the terminal.
12
+
13
+ ## Key Features
14
+
15
+ - **Python API:** Automate reverse engineering, exploit development, or testing using a clean, object-oriented interface. Unlike GDB, PyX64Dbg acts as a standard Python library you can import and use anywhere.
16
+ - **Graphical Interface (GUI):** Built with PySide6, featuring disassembly views, memory watches, register panels, and an embedded interactive terminal.
17
+ - **Command Line Interface (CLI):** An interactive IPython REPL that supports live Python syntax, auto-completion, and inline evaluation.
18
+ - **Advanced Target Support:** Native handling of PIE (Position Independent Executables), ASLR, shared libraries (`ld.so`), and dynamic symbols.
19
+ - **C-Like Type System:** A custom extension providing native types (`Int32`, `UInt64`, `Float80`, etc.) that strictly follow C promotion, overflow, and truncation rules.
20
+ - **Extended Registers (AVX/SSE):** Supports CPU `xstate`, including `XMM`, `YMM`, and FPU (`st`) vector registers. The API allows you to seamlessly treat vector data as a C-style union across all possible integer and floating-point array representations.
21
+
22
+ ## Prerequisites
23
+
24
+ - **Operating System**: Linux (x86-64 architecture only)
25
+ - **Python**: 3.10 or later
26
+ - **C++ Compiler**: A C++20 compatible compiler (e.g., `g++` or `clang`) and Python development headers are required to compile the `ptrace` and numeric type extensions during installation.
27
+
28
+ ## Installation
29
+
30
+ ### From PyPI (Recommended)
31
+ ```bash
32
+ pip install pyx64dbg
33
+ ```
34
+
35
+ ### From Source (Development)
36
+ Clone the repository and install it in editable mode:
37
+ ```bash
38
+ git clone https://github.com/yoav-shamay/pyx64dbg.git
39
+ cd pyx64dbg
40
+ pip install -e .
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### Graphical Interface (GUI)
46
+ Start the visual debugger (requires a desktop session like X11 or Wayland):
47
+ ```bash
48
+ pyx64dbg-gui
49
+ ```
50
+ *Tip: The full IPython CLI is embedded directly into the GUI and is available via the "Interactive Console" tab at the bottom.*
51
+
52
+ ### Command Line Interface (CLI)
53
+ Launch the interactive IPython console:
54
+ ```bash
55
+ pyx64dbg [/path/to/binary]
56
+ ```
57
+ Once inside, simply type `help` to see a list of available commands and aliases (e.g., `run`, `step`, `bps`, `dis`).
58
+
59
+ ## Python API Showcase
60
+
61
+ PyX64Dbg is built to be scripted. You can easily interact with binaries directly from Python.
62
+
63
+ ```python
64
+ from pyx64dbg import Debugger
65
+ from pyx64dbg.number_types import UInt64
66
+
67
+ # 1. Spawn process and attach debugger
68
+ dbg = Debugger.start_and_debug("./target_binary")
69
+
70
+ # 2. Set a breakpoint at the 'main' function
71
+ main_addr = dbg.symbols["main"]
72
+ dbg.breakpoints.add_breakpoint(main_addr)
73
+
74
+ # 3. Run until the breakpoint is hit
75
+ dbg.control.continue_execution()
76
+
77
+ # 4. Read memory and native vector registers
78
+ rip = dbg.registers.rip
79
+ rsp_val = dbg.memory.read_number(dbg.registers.rsp, UInt64)
80
+ ymm0_floats = dbg.registers.ymm0.f32 # Access YMM0 as an array of 32-bit floats
81
+
82
+ print(f"[+] Halted at RIP: 0x{rip:x}")
83
+ print(f"[+] Stack pointer value: 0x{rsp_val:x}")
84
+ print(f"[+] YMM0 state: {ymm0_floats}")
85
+
86
+ # 5. Clean up - kill the process
87
+ dbg.control.kill_process()
88
+ ```
89
+
90
+ ## Limitations
91
+
92
+ - Supported exclusively on Linux ELF binaries running on `x86-64`.
93
+ - Relies on the `ptrace` system call and the `/proc` filesystem. It will not function in hardened environments where these features are disabled.
94
+
95
+ ## Testing
96
+
97
+ The repository includes a suite of integration tests that run against provided pre-compiled C binaries to verify register states, memory reading, and edge cases.
98
+
99
+ To run the tests:
100
+ ```bash
101
+ pytest test/
102
+ ```
103
+
104
+ *Note: If you wish to rebuild the test executables from source, a `Makefile` is provided in `test/executables/`. Rebuilding may cause certain tests to fail if the compiler generates different instruction offsets.*
105
+
106
+ ## License
107
+
108
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel", "pybind11"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pyx64dbg"
7
+ version = "0.1.0"
8
+ description = "A debugger implemented in Python"
9
+ authors = [
10
+ { name = "Yoav Shamay", email = "yoavsh97@gmail.com" }
11
+ ]
12
+ readme = "README.md"
13
+ license = { file = "LICENSE" }
14
+ requires-python = ">=3.10"
15
+ dependencies = ["capstone", "pyelftools", "ipython", "prompt_toolkit", "pyside6", "nest_asyncio"]
16
+ keywords = ["debugger", "ptrace", "x86-64", "linux"]
17
+ classifiers = [
18
+ "Operating System :: POSIX :: Linux",
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Developers",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Programming Language :: Python :: 3.14",
28
+ "Topic :: Software Development :: Debuggers"
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/yoav-shamay/pyx64dbg"
33
+ Repository = "https://github.com/yoav-shamay/pyx64dbg"
34
+
35
+ [project.optional-dependencies]
36
+ dev = ["black", "jinja2", "pytest"]
37
+
38
+ [project.scripts]
39
+ pyx64dbg = "pyx64dbg.CLI.main:main"
40
+ pyx64dbg-gui = "pyx64dbg.GUI.main:main"
41
+
42
+ [tool.setuptools.package-data]
43
+ # Include type stubs, the py.typed marker, and all GUI web/styling assets
44
+ "pyx64dbg" = ["py.typed", "**/*.pyi"]
45
+ "pyx64dbg.GUI" = ["pty_view/*", "styles/*.qss", "assets/*"]
File without changes
@@ -0,0 +1,83 @@
1
+ from __future__ import annotations
2
+ from typing import Optional
3
+ from IPython.terminal.embed import InteractiveShellEmbed
4
+ from IPython.terminal.prompts import Prompts, Token
5
+ from pyx64dbg.interactive_console.interactive_console import InteractiveConsole, banner
6
+ import atexit
7
+ import sys
8
+
9
+ class ConsolePrompt(Prompts):
10
+ """
11
+ An implementation of the IPython Prompts class to define a custom prompt for our interactive console.
12
+ We want to show "PyX64Dbg> " as the prompt for our console.
13
+ """
14
+ def in_prompt_tokens(self, cli=None):
15
+ """
16
+ Override of the in_prompt_tokens method to return our custom prompt.
17
+ """
18
+ return [(Token.Prompt, "PyX64Dbg> ")]
19
+
20
+
21
+ class IPythonCLI:
22
+ """
23
+ A class that manages the IPython CLI for the debugger.
24
+ Uses the InteractiveConsole class to manage the console state, and uses IPython for the shell itself.
25
+ """
26
+ def __init__(self, file_name: Optional[str] = None, verbose: bool = False, use_external_pty: bool = False) -> None:
27
+ self._verbose: bool = verbose
28
+ # create the interactive console object. We want stdio to appear in the terminal, so we don't redirect it to a PTY.
29
+ self.interactive_console = InteractiveConsole(
30
+ file_name,
31
+ redirect_stdio_to_pty=use_external_pty,
32
+ disable_pty_echo=False, # if we are using an external PTY, we don't disable the echo as we want to see what we are typing
33
+ )
34
+ # register our callbacks for updating aliases
35
+ self.interactive_console.update_aliases_callbacks.add(self._refresh_aliases)
36
+
37
+ def _refresh_aliases(self, aliases: dict[str, object]) -> None:
38
+ """
39
+ The callback for refreshing the aliases in the interactive console.
40
+ Moves the aliases to the IPython shell's user namespace so that they are accessible to the user.
41
+ """
42
+ self.shell.push(aliases)
43
+
44
+ def _show_simple_error(
45
+ self,
46
+ exc_tuple=None,
47
+ filename=None,
48
+ tb=None,
49
+ tb_offset=None,
50
+ exception_only=False,
51
+ running_compiled_code=False,
52
+ ):
53
+ """
54
+ Custom error handler to show only the exception type and message without the full traceback.
55
+ This is in order to simplify the error output for the user.
56
+ """
57
+ # if we are not provided exc_tuple, take it from sys.exc_info() to get the current exception
58
+ if exc_tuple is not None:
59
+ exc_type, exc_value, _ = exc_tuple
60
+ else:
61
+ exc_type, exc_value, _ = sys.exc_info()
62
+ # use the console printing error message with the name of the exception class and its msg
63
+ self.interactive_console.print_error(exc_type.__name__, exc_value)
64
+
65
+ def start_console(self) -> None:
66
+ """
67
+ Starts the IPython interactive console.
68
+ """
69
+ atexit.register(self.interactive_console.handle_exit) # register the console exit handler using atexit
70
+ # create the InteractiveShellEmbed object for the console, with linux colors and no banner (we have our own banner that we print separately)
71
+ self.shell = InteractiveShellEmbed(colors="linux", display_banner=False)
72
+ # define custom prompt (PyX64Dbg>) for the console
73
+ self.shell.prompts = ConsolePrompt(self.shell)
74
+ # if verbose mode is disabled, use the custom simple error handler that shows reduced error information to simplify console output
75
+ if not self._verbose:
76
+ self.shell.showtraceback = self._show_simple_error
77
+ # allow to call functions without parentheses, e. g. "s" instead of "s()"
78
+ self.shell.autocall = 2
79
+ # Disable the kernel from printing the autocall expansion to keep the CLI cleaner
80
+ self.shell.show_rewritten_input = False
81
+ print(banner, end='') # banner already has a newline at the end
82
+ # start the shell with the initial aliases from the interactive console
83
+ self.shell(local_ns=self.interactive_console.get_aliases())
@@ -0,0 +1,34 @@
1
+ """
2
+ The entry point for the CLI tool.
3
+ Parses command line arguments and starts the IPython CLI for the debugger.
4
+ """
5
+ from __future__ import annotations
6
+ import argparse
7
+ from pyx64dbg.CLI.ipython_cli import IPythonCLI
8
+
9
+
10
+ def parse_arguments() -> argparse.Namespace:
11
+ """
12
+ Parses the command line arguments for the CLI tool.
13
+ Returns an argparse.Namespace object containing the parsed arguments.
14
+ """
15
+ parser = argparse.ArgumentParser(prog='pyx64dbg',
16
+ description='A debugger for x64 Linux binaries, written in Python')
17
+ # optional filename argument
18
+ parser.add_argument("filename", nargs="?", default=None, help="The file to debug")
19
+ # verbose option (full tracebacks)
20
+ parser.add_argument("-v", "--verbose", action="store_true", help="Print verbose output in case of errors, including full traceback")
21
+ args = parser.parse_args()
22
+ return args
23
+
24
+ def main():
25
+ """
26
+ The entry point for the CLI tool.
27
+ """
28
+ args = parse_arguments()
29
+ file_name = args.filename
30
+ console = IPythonCLI(file_name, verbose=args.verbose)
31
+ console.start_console()
32
+
33
+ if __name__ == "__main__":
34
+ main()
File without changes
@@ -0,0 +1,38 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
2
+ <!-- Refined Handle - Slightly larger, still anchored to boundary -->
3
+ <rect x="78.3" y="78.3" width="18" height="7" transform="rotate(45 78.3 78.3)" fill="black" rx="3.5" />
4
+
5
+ <!-- Centered Magnifying Glass Frame -->
6
+ <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2.5" fill="none" />
7
+
8
+ <!-- Organic Bug Design - Centered and contained -->
9
+ <g transform="translate(50, 46) scale(1.1)" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
10
+ <!-- Hollow Head -->
11
+ <path d="M -5.5,-8.5 C -7,-17 7,-17 5.5,-8.5" />
12
+
13
+ <!-- Antennae -->
14
+ <path d="M -2.5,-14 C -4,-18 -7,-19 -9,-18" />
15
+ <path d="M 2.5,-14 C 4,-18 7,-19 9,-18" />
16
+
17
+ <!-- Natural Curved Body -->
18
+ <path d="M -5.5,-8.5
19
+ C -10,-8.5 -13,0 -11,8
20
+ C -9,18 -5,26 0,26
21
+ C 5,26 9,18 11,8
22
+ C 13,0 10,-8.5 5.5,-8.5
23
+ Z" />
24
+
25
+ <!-- Curved Wing Split -->
26
+ <path d="M 0,-8.5 Q 0,10 0,26" stroke-width="1.2" />
27
+
28
+ <!-- Organic Curved Legs -->
29
+ <path d="M -9,0 C -13,-2 -15,0 -16,4" />
30
+ <path d="M 9,0 C 13,-2 15,0 16,4" />
31
+
32
+ <path d="M -11,9 C -15,9 -17,13 -17,17" />
33
+ <path d="M 11,9 C 15,9 17,13 17,17" />
34
+
35
+ <path d="M -9,18 C -11,21 -12,27 -11,31" />
36
+ <path d="M 9,18 C 11,21 12,27 11,31" />
37
+ </g>
38
+ </svg>
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+ import asyncio
3
+ from functools import wraps
4
+ from typing import Any, Callable, ParamSpec, Awaitable
5
+
6
+ P = ParamSpec("P") # parameter specifications of the callables
7
+
8
+ # save a reference to all background tasks created so they aren't discarded by the garbage collecotr.
9
+ background_tasks: set[asyncio.Task[Any]] = set()
10
+
11
+ def async_slot(func: Callable[P, Awaitable[Any]]) -> Callable[P, None]:
12
+ """
13
+ Decorator to connect async methods to standard Qt signals.
14
+ Automatically schedules the coroutine on the active asyncio event loop.
15
+ """
16
+ # define the wrapper function
17
+ @wraps(func)
18
+ def wrapper(*args: P.args, **kwargs: P.kwargs):
19
+ # Catch any arguments the signal emits and pass them to the async function
20
+ task = asyncio.create_task(func(*args, **kwargs))
21
+ # save a reference to the task to prevent it from getting garbage collected, and remove it once the task is done
22
+ background_tasks.add(task)
23
+ task.add_done_callback(background_tasks.discard)
24
+
25
+ return wrapper