Name | libdebug JSON |
Version |
0.7.0
JSON |
| download |
home_page | None |
Summary | A Python library for the debugging of binary executables. |
upload_time | 2024-10-14 16:09:41 |
maintainer | None |
docs_url | None |
author | JinBlack, Io-no, MrIndeciso, Frank01001 |
requires_python | >=3.10 |
license | MIT License Copyright (c) 2023 - 2024 Mario Polino, Gabriele Digregorio, Roberto Bertolini, Francesco Panebianco. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
libdebug
debugger
elf
ptrace
gdb
debug
ctf
reverse-engineering
reverse
rev
scriptable
script
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
![logo](https://github.com/libdebug/libdebug/blob/dev/media/libdebug_header.png?raw=true)
# libdebug [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13151549.svg)](https://doi.org/10.5281/zenodo.13151549)
libdebug is an open source Python library to automate the debugging of a binary executable.
With libdebug you have full control of the flow of your debugged executable. With it you can:
- Access process memory and registers
- Control the execution flow of the process
- Handle and hijack syscalls
- Catch and hijack signals
- Debug multithreaded applications with ease
- Seamlessly switch to GDB for interactive analysis
- Multiarch: currently supports Linux AMD64 and AArch64 and i386 (both native and in 32-bit compatibility mode)
When running the same executable multiple times, choosing efficient implementations can make the difference. For this reason, libdebug prioritizes performance.
## Project Links
Homepage: https://libdebug.org \
Documentation: https://docs.libdebug.org
### Installation Requirements:
Ubuntu: \
`sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg` \
Debian: \
`sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg` \
Arch Linux: \
`sudo pacman -S python libelf libdwarf gcc make debuginfod` \
Fedora: \
`sudo dnf install -y python3 python3-devel kernel-devel binutils-devel libdwarf-devel`
## Installation
```bash
python3 -m pip install libdebug
```
PyPy3 is supported but not recommended, as it performs worse on most of our tests.
If you want to stay up to date with the most cutting-edge features (and you don't mind being on an unstable branch) you can install from a different branch (e.g., dev).
```bash
python3 -m pip install git+https://github.com/libdebug/libdebug.git@dev
```
## Your first script
Now that you have libdebug installed, you can start using it in your scripts. Here is a simple example of how to use libdebug to debug a binary:
```python
from libdebug import debugger
d = debugger("./test")
# Start debugging from the entry point
d.run()
my_breakpoint = d.breakpoint("function")
# Continue the execution until the breakpoint is hit
d.cont()
# Print RAX
print(f"RAX is {hex(d.regs.rax)}")
# Write to memory
d.memory[0x10ad, 8, "binary"] = b"Hello!\x00\x00"
# Continue the execution
d.cont()
```
The above script will run the binary `test` in the working directory and stop at the function corresponding to the symbol "function". It will then print the value of the RAX register and kill the process.
There is so much more that can be done with libdebug. Please read the [documentation](https://docs.libdebug.org/) to find out more.
## The cool stuff
libdebug offers many advanced features. Take a look at this script doing magic with signals:
```python
from libdebug import debugger, libcontext
libcontext.terminal = ['tmux', 'splitw', '-h']
# Define signal catchers
def catcher_SIGUSR1(t: ThreadContext, catcher: SignalCatcher) -> None:
t.signal = 0x0
print(f"SIGUSR1: Signal number {catcher}")
def catcher_SIGINT(t: ThreadContext, catcher: SignalCatcher) -> None:
print(f"SIGINT: Signal number {catcher}")
def catcher_SIGPIPE(t: ThreadContext, catcher: SignalCatcher) -> None:
print(f"SIGPIPE: Signal number {catcher}")
def handler_geteuid(t: ThreadContext, handler: SyscallHandler) -> None:
t.regs.rax = 0x0
# Initialize the debugger
d = debugger('/path/to/executable', continue_to_binary_entrypoint=False, aslr=False)
# Register signal catchers
catcher1 = d.catch_signal("SIGUSR1", callback=catcher_SIGUSR1)
catcher2 = d.catch_signal("SIGINT", callback=catcher_SIGINT)
catcher3 = d.catch_signal("SIGPIPE", callback=catcher_SIGPIPE)
# Register signal hijackings
d.hijack_signal("SIGQUIT", "SIGTERM")
d.hijack_signal("SIGINT", "SIGPIPE", recursive=True)
# Define which signals to block
d.signals_to_block = ["SIGPOLL", "SIGIO", "SIGALRM"]
d.handle_syscall("geteuid", on_exit=handler_geteuid)
# Continue execution
d.cont()
# Disable the catchers after execution
catcher1.disable()
catcher2.disable()
catcher3.disable()
bp = d.breakpoint(0xdeadc0de, hardware=True)
d.cont()
d.wait()
d.gdb()
```
## Auto Interrupt on Command
libdebug also allows you to make all commands execute as soon as possible, without having to wait for a stopping event. To enable this mode, you can use the `auto_interrupt_on_command=True`
```python
from libdebug import debugger
d = debugger("/path/to/executable", auto_interrupt_on_command=True)
pipes = d.run()
bp = d.breakpoint("function")
d.cont()
# Read shortly after the cont is issued
# The process is forcibly stopped to read the register
value = d.regs.rax
print(f"RAX is {hex(value)}")
system_offset = d.symbols.filter("system")[0].start
libc_base = d.maps.filter("libc")[0].base
system_address = libc_base + system_offset
d.memory[0x12ebe, 8, "libc"] = int.to_bytes(system_address, 8, "little")
d.cont()
d.wait()
# Here we should be at the breakpoint
# This value is read while the process is stopped at the breakpoint
ip_value = d.regs.rip
print(f"RIP is {hex(ip_value)}")
d.kill()
```
## Attribution
If you intend to use libdebug in your work, please cite this repository using the following biblatex:
```biblatex
@software{libdebug_2024,
title = {libdebug: {Build} {Your} {Own} {Debugger}},
copyright = {MIT Licence},
url = {https://libdebug.org},
publisher = {libdebug.org},
author = {Digregorio, Gabriele and Bertolini, Roberto Alessandro and Panebianco, Francesco and Polino, Mario},
year = {2024},
doi = {10.5281/zenodo.13151549},
}
```
Raw data
{
"_id": null,
"home_page": null,
"name": "libdebug",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "libdebug, debugger, elf, ptrace, gdb, debug, ctf, reverse-engineering, reverse, rev, scriptable, script",
"author": "JinBlack, Io-no, MrIndeciso, Frank01001",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/84/ed/178bb9e787f0cb4673209c3e565adea70aea6824b8f420d2d3fec49e5164/libdebug-0.7.0.tar.gz",
"platform": null,
"description": "![logo](https://github.com/libdebug/libdebug/blob/dev/media/libdebug_header.png?raw=true)\n# libdebug [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13151549.svg)](https://doi.org/10.5281/zenodo.13151549)\n\nlibdebug is an open source Python library to automate the debugging of a binary executable.\n\nWith libdebug you have full control of the flow of your debugged executable. With it you can:\n- Access process memory and registers \n- Control the execution flow of the process\n- Handle and hijack syscalls\n- Catch and hijack signals\n- Debug multithreaded applications with ease\n- Seamlessly switch to GDB for interactive analysis\n- Multiarch: currently supports Linux AMD64 and AArch64 and i386 (both native and in 32-bit compatibility mode)\n\nWhen running the same executable multiple times, choosing efficient implementations can make the difference. For this reason, libdebug prioritizes performance.\n\n## Project Links\nHomepage: https://libdebug.org \\\nDocumentation: https://docs.libdebug.org\n\n### Installation Requirements:\nUbuntu: \\\n`sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg` \\\nDebian: \\\n`sudo apt install -y python3 python3-dev libdwarf-dev libelf-dev libiberty-dev linux-headers-generic libc6-dbg` \\\nArch Linux: \\\n`sudo pacman -S python libelf libdwarf gcc make debuginfod` \\\nFedora: \\\n`sudo dnf install -y python3 python3-devel kernel-devel binutils-devel libdwarf-devel`\n\n## Installation\n```bash\npython3 -m pip install libdebug\n```\n\nPyPy3 is supported but not recommended, as it performs worse on most of our tests.\n\nIf you want to stay up to date with the most cutting-edge features (and you don't mind being on an unstable branch) you can install from a different branch (e.g., dev).\n\n```bash\npython3 -m pip install git+https://github.com/libdebug/libdebug.git@dev\n```\n\n## Your first script\n\nNow that you have libdebug installed, you can start using it in your scripts. Here is a simple example of how to use libdebug to debug a binary:\n\n```python\n\nfrom libdebug import debugger\n\nd = debugger(\"./test\")\n\n# Start debugging from the entry point\nd.run()\n\nmy_breakpoint = d.breakpoint(\"function\")\n\n# Continue the execution until the breakpoint is hit\nd.cont()\n\n# Print RAX\nprint(f\"RAX is {hex(d.regs.rax)}\")\n\n# Write to memory\nd.memory[0x10ad, 8, \"binary\"] = b\"Hello!\\x00\\x00\"\n\n# Continue the execution\nd.cont()\n```\n\nThe above script will run the binary `test` in the working directory and stop at the function corresponding to the symbol \"function\". It will then print the value of the RAX register and kill the process.\n\nThere is so much more that can be done with libdebug. Please read the [documentation](https://docs.libdebug.org/) to find out more.\n\n## The cool stuff\n\nlibdebug offers many advanced features. Take a look at this script doing magic with signals:\n\n```python\nfrom libdebug import debugger, libcontext\n\nlibcontext.terminal = ['tmux', 'splitw', '-h']\n\n# Define signal catchers\ndef catcher_SIGUSR1(t: ThreadContext, catcher: SignalCatcher) -> None:\n t.signal = 0x0\n print(f\"SIGUSR1: Signal number {catcher}\")\n\ndef catcher_SIGINT(t: ThreadContext, catcher: SignalCatcher) -> None:\n print(f\"SIGINT: Signal number {catcher}\")\n\ndef catcher_SIGPIPE(t: ThreadContext, catcher: SignalCatcher) -> None:\n print(f\"SIGPIPE: Signal number {catcher}\")\n\ndef handler_geteuid(t: ThreadContext, handler: SyscallHandler) -> None:\n\tt.regs.rax = 0x0\n\n# Initialize the debugger\nd = debugger('/path/to/executable', continue_to_binary_entrypoint=False, aslr=False)\n\n# Register signal catchers\ncatcher1 = d.catch_signal(\"SIGUSR1\", callback=catcher_SIGUSR1)\ncatcher2 = d.catch_signal(\"SIGINT\", callback=catcher_SIGINT)\ncatcher3 = d.catch_signal(\"SIGPIPE\", callback=catcher_SIGPIPE)\n\n# Register signal hijackings\nd.hijack_signal(\"SIGQUIT\", \"SIGTERM\")\nd.hijack_signal(\"SIGINT\", \"SIGPIPE\", recursive=True)\n\n# Define which signals to block\nd.signals_to_block = [\"SIGPOLL\", \"SIGIO\", \"SIGALRM\"]\n\nd.handle_syscall(\"geteuid\", on_exit=handler_geteuid)\n\n# Continue execution\nd.cont()\n\n# Disable the catchers after execution\ncatcher1.disable()\ncatcher2.disable()\ncatcher3.disable()\n\nbp = d.breakpoint(0xdeadc0de, hardware=True)\n\nd.cont()\nd.wait()\n\nd.gdb()\n```\n\n## Auto Interrupt on Command\nlibdebug also allows you to make all commands execute as soon as possible, without having to wait for a stopping event. To enable this mode, you can use the `auto_interrupt_on_command=True` \n\n```python\nfrom libdebug import debugger\n\nd = debugger(\"/path/to/executable\", auto_interrupt_on_command=True)\n\npipes = d.run()\n\nbp = d.breakpoint(\"function\")\n\nd.cont()\n\n# Read shortly after the cont is issued\n# The process is forcibly stopped to read the register\nvalue = d.regs.rax\nprint(f\"RAX is {hex(value)}\")\n\nsystem_offset = d.symbols.filter(\"system\")[0].start\nlibc_base = d.maps.filter(\"libc\")[0].base\n\nsystem_address = libc_base + system_offset\n\nd.memory[0x12ebe, 8, \"libc\"] = int.to_bytes(system_address, 8, \"little\")\n\nd.cont()\nd.wait()\n\n# Here we should be at the breakpoint\n\n# This value is read while the process is stopped at the breakpoint\nip_value = d.regs.rip\n\nprint(f\"RIP is {hex(ip_value)}\")\n\nd.kill()\n```\n\n## Attribution\nIf you intend to use libdebug in your work, please cite this repository using the following biblatex:\n\n```biblatex\n@software{libdebug_2024,\n\ttitle = {libdebug: {Build} {Your} {Own} {Debugger}},\n\tcopyright = {MIT Licence},\n\turl = {https://libdebug.org},\n\tpublisher = {libdebug.org},\n\tauthor = {Digregorio, Gabriele and Bertolini, Roberto Alessandro and Panebianco, Francesco and Polino, Mario},\n\tyear = {2024},\n\tdoi = {10.5281/zenodo.13151549},\n}\n```\n",
"bugtrack_url": null,
"license": "MIT License Copyright (c) 2023 - 2024 Mario Polino, Gabriele Digregorio, Roberto Bertolini, Francesco Panebianco. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"summary": "A Python library for the debugging of binary executables.",
"version": "0.7.0",
"project_urls": {
"homepage": "https://libdebug.org",
"issues": "https://github.com/libdebug/libdebug/issues",
"repository": "https://github.com/libdebug/libdebug/"
},
"split_keywords": [
"libdebug",
" debugger",
" elf",
" ptrace",
" gdb",
" debug",
" ctf",
" reverse-engineering",
" reverse",
" rev",
" scriptable",
" script"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "84ed178bb9e787f0cb4673209c3e565adea70aea6824b8f420d2d3fec49e5164",
"md5": "e59b859caa4ce06f4aa7c2d7deee4017",
"sha256": "e3df44e06b9bc880e583e48f81d63f8b3adbbbfb363722e06467c5f1269df332"
},
"downloads": -1,
"filename": "libdebug-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "e59b859caa4ce06f4aa7c2d7deee4017",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 98384,
"upload_time": "2024-10-14T16:09:41",
"upload_time_iso_8601": "2024-10-14T16:09:41.233321Z",
"url": "https://files.pythonhosted.org/packages/84/ed/178bb9e787f0cb4673209c3e565adea70aea6824b8f420d2d3fec49e5164/libdebug-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-14 16:09:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "libdebug",
"github_project": "libdebug",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "libdebug"
}