From 2b62259d7e5bcd01b0ff56ac742328dad68ff6e9 Mon Sep 17 00:00:00 2001 From: Gulshan Singh Date: Mon, 5 Sep 2022 04:23:20 -0700 Subject: [PATCH] GDB Refactor [2/N]: move some modules to lib/ (#1118) * Don't exclude pwndbg/lib in .gitignore * Move which.py to lib/which.py * move funcparser.py and functions.py to lib/ * moved version.py to lib/ * Move tips.py to lib/ * Update pwndbg/lib/version.py Co-authored-by: Disconnect3d --- .gitignore | 2 ++ docs/source/api/which.rst | 4 ++-- pwndbg/__init__.py | 4 ++-- pwndbg/arguments.py | 14 ++++++++------ pwndbg/commands/checksec.py | 2 +- pwndbg/commands/got.py | 2 +- pwndbg/commands/mprotect.py | 2 +- pwndbg/commands/nearpc.py | 2 +- pwndbg/commands/shell.py | 6 +++--- pwndbg/{ => lib}/funcparser.py | 0 pwndbg/{ => lib}/functions.py | 0 pwndbg/lib/tips.py | 28 ++++++++++++++++++++++++++++ pwndbg/{ => lib}/version.py | 0 pwndbg/{ => lib}/which.py | 0 pwndbg/prompt.py | 2 +- pwndbg/wrappers/__init__.py | 4 ++-- 16 files changed, 52 insertions(+), 20 deletions(-) rename pwndbg/{ => lib}/funcparser.py (100%) rename pwndbg/{ => lib}/functions.py (100%) create mode 100644 pwndbg/lib/tips.py rename pwndbg/{ => lib}/version.py (100%) rename pwndbg/{ => lib}/which.py (100%) diff --git a/.gitignore b/.gitignore index baedfb988..526015485 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ var/ .installed.cfg *.egg +!/pwndbg/lib/ + # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. diff --git a/docs/source/api/which.rst b/docs/source/api/which.rst index bb06a4feb..85a3510ba 100644 --- a/docs/source/api/which.rst +++ b/docs/source/api/which.rst @@ -1,5 +1,5 @@ -:mod:`pwndbg.which` --- pwndbg.which +:mod:`pwndbg.lib.which` --- pwndbg.lib.which ============================================= -.. automodule:: pwndbg.which +.. automodule:: pwndbg.lib.which :members: diff --git a/pwndbg/__init__.py b/pwndbg/__init__.py index 48b0c94fc..b40b5e75a 100755 --- a/pwndbg/__init__.py +++ b/pwndbg/__init__.py @@ -71,6 +71,7 @@ import pwndbg.gdblib.hooks import pwndbg.gdblib.typeinfo import pwndbg.gdbutils.functions import pwndbg.heap +import pwndbg.lib.version import pwndbg.memory import pwndbg.net import pwndbg.proc @@ -79,13 +80,12 @@ import pwndbg.regs import pwndbg.stack import pwndbg.tls import pwndbg.ui -import pwndbg.version import pwndbg.vmmap import pwndbg.wrappers import pwndbg.wrappers.checksec import pwndbg.wrappers.readelf -__version__ = pwndbg.version.__version__ +__version__ = pwndbg.lib.version.__version__ version = __version__ try: diff --git a/pwndbg/arguments.py b/pwndbg/arguments.py index 4f60ee5ab..7b338b813 100644 --- a/pwndbg/arguments.py +++ b/pwndbg/arguments.py @@ -11,11 +11,11 @@ import pwndbg.chain import pwndbg.color.nearpc as N import pwndbg.constants import pwndbg.disasm -import pwndbg.funcparser -import pwndbg.functions import pwndbg.gdblib.arch import pwndbg.gdblib.typeinfo import pwndbg.ida +import pwndbg.lib.funcparser +import pwndbg.lib.functions import pwndbg.memory import pwndbg.regs import pwndbg.symbol @@ -118,11 +118,11 @@ def get(instruction): # If we have particular `XXX_chk` function in our database, we use it. # Otherwise, we show args for its unchecked version. # We also lstrip `_` in here, as e.g. `__printf_chk` needs the underscores. - if name not in pwndbg.functions.functions: + if name not in pwndbg.lib.functions.functions: name = name.replace("_chk", "") name = name.strip().lstrip("_") # _malloc - func = pwndbg.functions.functions.get(name, None) + func = pwndbg.lib.functions.functions.get(name, None) # Try to extract the data from GDB. # Note that this is currently broken, pending acceptance of @@ -146,12 +146,14 @@ def get(instruction): for k, v in ida_replacements.items(): typename = typename.replace(k, v) - func = pwndbg.funcparser.ExtractFuncDeclFromSource(typename + ";") + func = pwndbg.lib.funcparser.ExtractFuncDeclFromSource(typename + ";") if func: args = func.args else: - args = (pwndbg.functions.Argument("int", 0, argname(i, abi)) for i in range(n_args_default)) + args = ( + pwndbg.lib.functions.Argument("int", 0, argname(i, abi)) for i in range(n_args_default) + ) for i, arg in enumerate(args): result.append((arg, argument(i, abi))) diff --git a/pwndbg/commands/checksec.py b/pwndbg/commands/checksec.py index de53bba93..795c24efa 100755 --- a/pwndbg/commands/checksec.py +++ b/pwndbg/commands/checksec.py @@ -1,5 +1,5 @@ import pwndbg.commands -import pwndbg.which +import pwndbg.lib.which import pwndbg.wrappers.checksec diff --git a/pwndbg/commands/got.py b/pwndbg/commands/got.py index 06a81deeb..759714bfb 100644 --- a/pwndbg/commands/got.py +++ b/pwndbg/commands/got.py @@ -4,7 +4,7 @@ import pwndbg.chain import pwndbg.commands import pwndbg.enhance import pwndbg.file -import pwndbg.which +import pwndbg.lib.which import pwndbg.wrappers.checksec import pwndbg.wrappers.readelf from pwndbg.color import message diff --git a/pwndbg/commands/mprotect.py b/pwndbg/commands/mprotect.py index c80c6c994..1fc7e6377 100644 --- a/pwndbg/commands/mprotect.py +++ b/pwndbg/commands/mprotect.py @@ -6,7 +6,7 @@ import pwndbg.chain import pwndbg.commands import pwndbg.enhance import pwndbg.file -import pwndbg.which +import pwndbg.lib.which import pwndbg.wrappers.checksec import pwndbg.wrappers.readelf from pwndbg.color import message diff --git a/pwndbg/commands/nearpc.py b/pwndbg/commands/nearpc.py index 7f55f023f..9e7bd67ec 100644 --- a/pwndbg/commands/nearpc.py +++ b/pwndbg/commands/nearpc.py @@ -12,8 +12,8 @@ import pwndbg.color.theme import pwndbg.commands.comments import pwndbg.config import pwndbg.disasm -import pwndbg.functions import pwndbg.ida +import pwndbg.lib.functions import pwndbg.regs import pwndbg.strings import pwndbg.symbol diff --git a/pwndbg/commands/shell.py b/pwndbg/commands/shell.py index 36ec1997d..70a867c32 100644 --- a/pwndbg/commands/shell.py +++ b/pwndbg/commands/shell.py @@ -7,7 +7,7 @@ import os import gdb import pwndbg.commands -import pwndbg.which +import pwndbg.lib.which pwncmds = ["asm", "constgrep", "cyclic", "disasm", "pwn", "unhex"] shellcmd_names = [ @@ -62,8 +62,8 @@ shellcmd_names = [ "zsh", ] -pwncmds = filter(pwndbg.which.which, pwncmds) -shellcmds = filter(pwndbg.which.which, shellcmd_names) +pwncmds = filter(pwndbg.lib.which.which, pwncmds) +shellcmds = filter(pwndbg.lib.which.which, shellcmd_names) def register_shell_function(cmd, deprecated=False): diff --git a/pwndbg/funcparser.py b/pwndbg/lib/funcparser.py similarity index 100% rename from pwndbg/funcparser.py rename to pwndbg/lib/funcparser.py diff --git a/pwndbg/functions.py b/pwndbg/lib/functions.py similarity index 100% rename from pwndbg/functions.py rename to pwndbg/lib/functions.py diff --git a/pwndbg/lib/tips.py b/pwndbg/lib/tips.py new file mode 100644 index 000000000..8b9a4c80a --- /dev/null +++ b/pwndbg/lib/tips.py @@ -0,0 +1,28 @@ +from random import choice + +TIPS = [ + # GDB hints + "GDB's `apropos ` command displays all registered commands that are related to the given ", + "GDB's `follow-fork-mode` parameter can be used to set whether to trace parent or child after fork() calls", + 'Use GDB\'s `dprintf` command to print all calls to given function. E.g. `dprintf malloc, "malloc(%p)\\n", (void*)$rdi` will print all malloc calls', + "Use GDB's `pi` command to run an interactive Python console where you can use Pwndbg APIs like `pwndbg.gdb.memory.read(addr, len)`, `pwndbg.gdb.memory.write(addr, data)`, `pwndbg.gdb.vmmap.get()` and so on!", + "GDB's `set directories ` parameter can be used to debug e.g. glibc sources like the malloc/free functions!", + # Pwndbg hints + "GDB and Pwndbg parameters can be shown or set with `show ` and `set ` GDB commands", + "Use Pwndbg's `config` and `theme` commands to tune its configuration and theme colors!", + "Pwndbg mirrors some of Windbg commands like `eq`, `ew`, `ed`, `eb`, `es`, `dq`, `dw`, `dd`, `db`, `ds` for writing and reading memory", + "Pwndbg resolves kernel memory maps by parsing page tables (default) or via `monitor info mem` QEMU gdbstub command (use `set kernel-vmmap-via-page-tables off` for that)", + "Use the `vmmap` instruction for a better & colored memory maps display (than the GDB's `info proc mappings`)", + "Use the `telescope` command to dereference a given address/pointer multiple times (if the dereferenced value is a valid ptr; see `config telescope` to configure its behavior)", + "Use the `context` (or `ctx`) command to display the context once again. You can reconfigure the context layout with `set context-section ` or forward the output to a file/tty via `set context-output `. See also `config context` to configure it further!", + "Disable Pwndbg context information display with `set context-sections ''`", + "Pwndbg context displays where the program branches to thanks to emulating few instructions into the future. You can disable this with `set emulate off` which may also speed up debugging", + "Use the `canary` command to see all stack canary/cookie values on the stack (based on the *usual* stack canary value initialized by glibc)", + "Use the `procinfo` command for better process introspection (than the GDB's `info proc` command)", + "Want to display each context panel in a separate tmux window? See https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md#splitting--layouting-context", + "The $heap_base GDB variable can be used to refer to the starting address of the heap after running the `heap` command", +] + + +def get_tip_of_the_day() -> str: + return choice(TIPS) diff --git a/pwndbg/version.py b/pwndbg/lib/version.py similarity index 100% rename from pwndbg/version.py rename to pwndbg/lib/version.py diff --git a/pwndbg/which.py b/pwndbg/lib/which.py similarity index 100% rename from pwndbg/which.py rename to pwndbg/lib/which.py diff --git a/pwndbg/prompt.py b/pwndbg/prompt.py index 6dc8c478d..9f5caab19 100644 --- a/pwndbg/prompt.py +++ b/pwndbg/prompt.py @@ -8,7 +8,7 @@ import pwndbg.gdbutils import pwndbg.lib.memoize from pwndbg.color import disable_colors from pwndbg.color import message -from pwndbg.tips import get_tip_of_the_day +from pwndbg.lib.tips import get_tip_of_the_day funcs_list_str = ", ".join( message.notice("$" + f.name) for f in pwndbg.gdbutils.functions.functions diff --git a/pwndbg/wrappers/__init__.py b/pwndbg/wrappers/__init__.py index 2cd07f2c7..63b1e7727 100644 --- a/pwndbg/wrappers/__init__.py +++ b/pwndbg/wrappers/__init__.py @@ -3,7 +3,7 @@ import subprocess from subprocess import STDOUT import pwndbg.commands -import pwndbg.which +import pwndbg.lib.which class OnlyWithCommand: @@ -11,7 +11,7 @@ class OnlyWithCommand: self.all_cmds = list(map(lambda cmd: cmd[0] if isinstance(cmd, list) else cmd, commands)) for command in commands: self.cmd = command if isinstance(command, list) else [command] - self.cmd_path = pwndbg.which.which(self.cmd[0]) + self.cmd_path = pwndbg.lib.which.which(self.cmd[0]) if self.cmd_path: break