GDB Refactor [18/N]: Move proc to gdblib/proc.py (#1247)

pull/1242/head
Gulshan Singh 3 years ago committed by GitHub
parent 29c9d74f9b
commit bb342a9286
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,7 +22,7 @@ Feel free to update the list below!
* Memory accesses should be done through `pwndbg/memory.py` functions
* Process properties can be retrieved thx to `pwndbg/proc.py` - e.g. using `pwndbg.proc.pid` will give us current process pid
* Process properties can be retrieved thx to `pwndbg/gdblib/proc.py` - e.g. using `pwndbg.gdblib.proc.pid` will give us current process pid
* We have a wrapper for handling exceptions that are thrown by commands - defined in `pwndbg/exception.py` - current approach seems to work fine - by using `set exception-verbose on` - we get a stacktrace. If we want to debug stuff we can always do `set exception-debugger on`.

@ -1,5 +1,5 @@
:mod:`pwndbg.proc` --- pwndbg.proc
:mod:`pwndbg.gdblib.proc` --- pwndbg.gdblib.proc
=============================================
.. automodule:: pwndbg.proc
.. automodule:: pwndbg.gdblib.proc
:members:

@ -210,7 +210,7 @@ def format_args(instruction):
# Enhance args display
if arg.name == "fd" and isinstance(value, int):
path = pwndbg.file.readlink("/proc/%d/fd/%d" % (pwndbg.proc.pid, value))
path = pwndbg.file.readlink("/proc/%d/fd/%d" % (pwndbg.gdblib.proc.pid, value))
if path:
pretty += " (%s)" % path

@ -202,7 +202,7 @@ def fix_int_reraise(*a, **kw):
def OnlyWithFile(function):
@functools.wraps(function)
def _OnlyWithFile(*a, **kw):
if pwndbg.proc.exe:
if pwndbg.gdblib.proc.exe:
return function(*a, **kw)
else:
if pwndbg.gdblib.qemu.is_qemu():
@ -216,7 +216,7 @@ def OnlyWithFile(function):
def OnlyWhenRunning(function):
@functools.wraps(function)
def _OnlyWhenRunning(*a, **kw):
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
return function(*a, **kw)
else:
print("%s: The program is not being run." % function.__name__)

@ -3,7 +3,7 @@ import argparse
import gdb
import pwndbg.commands
import pwndbg.proc
import pwndbg.gdblib.proc
import pwndbg.vmmap
from pwndbg.color import message
@ -30,7 +30,7 @@ def aslr(state=None):
if state:
gdb.execute("set disable-randomization %s" % options[state], from_tty=False, to_string=True)
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
print("Change will take effect when the process restarts")
aslr, method = pwndbg.vmmap.check_aslr()

@ -26,11 +26,11 @@ def comm(addr=None, comment=None):
print(message.error("Invalid Address %#x" % target))
else:
f.write("file:%s=" % pwndbg.proc.exe)
f.write("file:%s=" % pwndbg.gdblib.proc.exe)
f.write("%#x:%s\n" % (target, comment))
if pwndbg.proc.exe not in file_lists.keys():
file_lists[pwndbg.proc.exe] = {}
file_lists[pwndbg.proc.exe][hex(target)] = comment
if pwndbg.gdblib.proc.exe not in file_lists.keys():
file_lists[pwndbg.gdblib.proc.exe] = {}
file_lists[pwndbg.gdblib.proc.exe][hex(target)] = comment
except Exception:
print(message.error("Permission denied to create file"))

@ -7,7 +7,7 @@ from pwndbg.color import message
@pwndbg.commands.ArgparsedCommand("Prints the section mappings contained in the ELF header.")
@pwndbg.commands.OnlyWithFile
def elfheader():
local_path = pwndbg.file.get_file(pwndbg.proc.exe)
local_path = pwndbg.file.get_file(pwndbg.gdblib.proc.exe)
with open(local_path, "rb") as f:
elffile = ELFFile(f)
@ -41,7 +41,7 @@ def plt():
def get_section_bounds(section_name):
local_path = pwndbg.file.get_file(pwndbg.proc.exe)
local_path = pwndbg.file.get_file(pwndbg.gdblib.proc.exe)
with open(local_path, "rb") as f:
elffile = ELFFile(f)

@ -188,7 +188,7 @@ def nearpc(pc=None, lines=None, to_string=False, emulate=False):
# For Comment Function
try:
line += " " * 10 + C.comment(
pwndbg.commands.comments.file_lists[pwndbg.proc.exe][hex(instr.address)]
pwndbg.commands.comments.file_lists[pwndbg.gdblib.proc.exe][hex(instr.address)]
)
except Exception:
pass

@ -49,7 +49,7 @@ def nextret():
def stepret():
"""Breaks at next return-like instruction by 'stepping' to it"""
while (
pwndbg.proc.alive
pwndbg.gdblib.proc.alive
and not pwndbg.gdblib.next.break_next_ret()
and pwndbg.gdblib.next.break_next_branch()
):
@ -58,7 +58,7 @@ def stepret():
gdb.execute("si")
continue
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
pwndbg.commands.context.context()
@ -92,13 +92,13 @@ def nextsyscall():
Breaks at the next syscall not taking branches.
"""
while (
pwndbg.proc.alive
pwndbg.gdblib.proc.alive
and not pwndbg.gdblib.next.break_next_interrupt()
and pwndbg.gdblib.next.break_next_branch()
):
continue
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
pwndbg.commands.context.context()
@ -111,7 +111,7 @@ def stepsyscall():
Breaks at the next syscall by taking branches.
"""
while (
pwndbg.proc.alive
pwndbg.gdblib.proc.alive
and not pwndbg.gdblib.next.break_next_interrupt()
and pwndbg.gdblib.next.break_next_branch()
):
@ -120,5 +120,5 @@ def stepsyscall():
gdb.execute("si")
continue
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
pwndbg.commands.context.context()

@ -7,7 +7,7 @@ import pwndbg.color.message as message
import pwndbg.commands
import pwndbg.commands.context
import pwndbg.commands.telescope
import pwndbg.proc
import pwndbg.gdblib.proc
@pwndbg.commands.ArgparsedCommand("Gets the current file.")
@ -19,7 +19,7 @@ def getfile():
@pwndbg.commands.ArgparsedCommand("Get the pid.")
@pwndbg.commands.OnlyWhenRunning
def getpid():
print(pwndbg.proc.pid)
print(pwndbg.gdblib.proc.pid)
parser = argparse.ArgumentParser(description="Continue execution until an address or function.")
@ -46,7 +46,7 @@ def xuntil(target):
spec = target
b = gdb.Breakpoint(spec, temporary=True)
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
gdb.execute("continue", from_tty=False)
else:
gdb.execute("run", from_tty=False)

@ -37,7 +37,7 @@ def get_exe_name():
# We want just 'a.out'
return os.path.normpath(real_path)
return pwndbg.proc.exe
return pwndbg.gdblib.proc.exe
def translate_addr(offset, module):

@ -3,9 +3,9 @@ import string
import pwndbg.auxv
import pwndbg.commands
import pwndbg.file
import pwndbg.gdblib.proc
import pwndbg.lib.memoize
import pwndbg.lib.net
import pwndbg.proc
"""
PEDA prints it out like this:
@ -64,9 +64,9 @@ capabilities = {
class Process:
def __init__(self, pid=None, tid=None):
if pid is None:
pid = pwndbg.proc.pid
pid = pwndbg.gdblib.proc.pid
if tid is None:
tid = pwndbg.proc.tid
tid = pwndbg.gdblib.proc.tid
if not tid:
tid = pid
self.pid = pid
@ -144,7 +144,7 @@ class Process:
fds = {}
for i in range(self.fdsize):
link = pwndbg.file.readlink("/proc/%i/fd/%i" % (pwndbg.proc.pid, i))
link = pwndbg.file.readlink("/proc/%i/fd/%i" % (pwndbg.gdblib.proc.pid, i))
if link:
fds[i] = link
@ -181,7 +181,7 @@ class Process:
@pwndbg.commands.ArgparsedCommand("Gets the pid.")
@pwndbg.commands.OnlyWhenRunning
def pid():
print(pwndbg.proc.pid)
print(pwndbg.gdblib.proc.pid)
@pwndbg.commands.ArgparsedCommand("Display information about the running process.")

@ -18,12 +18,12 @@ parser.add_argument("arguments", nargs="*", type=str, help="Arguments to pass to
@pwndbg.commands.ArgparsedCommand(parser, aliases=["radare2"])
@pwndbg.commands.OnlyWithFile
def r2(arguments, no_seek=False, no_rebase=False):
filename = pwndbg.file.get_file(pwndbg.proc.exe)
filename = pwndbg.file.get_file(pwndbg.gdblib.proc.exe)
# Build up the command line to run
cmd = ["radare2"]
flags = ["-e", "io.cache=true"]
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
addr = pwndbg.gdblib.regs.pc
if pwndbg.elf.get_elf_info(filename).is_pie:
if no_rebase:

@ -22,11 +22,11 @@ def rop(grep, argument):
with tempfile.NamedTemporaryFile() as corefile:
# If the process is running, dump a corefile so we get actual addresses.
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
filename = corefile.name
gdb.execute("gcore %s" % filename)
else:
filename = pwndbg.proc.exe
filename = pwndbg.gdblib.proc.exe
# Build up the command line to run
cmd = ["ROPgadget", "--binary", filename]

@ -20,11 +20,11 @@ def ropper(argument):
with tempfile.NamedTemporaryFile() as corefile:
# If the process is running, dump a corefile so we get actual addresses.
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
filename = corefile.name
gdb.execute("gcore %s" % filename)
else:
filename = pwndbg.proc.exe
filename = pwndbg.gdblib.proc.exe
# Build up the command line to run
cmd = ["ropper", "--file", filename]

@ -137,7 +137,7 @@ parser.add_argument(
@pwndbg.commands.ArgparsedCommand(parser)
def vmmap_load(filename):
if filename is None:
filename = pwndbg.file.get_file(pwndbg.proc.exe)
filename = pwndbg.file.get_file(pwndbg.gdblib.proc.exe)
print('Load "%s" ...' % filename)

@ -21,9 +21,9 @@ import pwndbg.gdblib.arch
import pwndbg.gdblib.events
import pwndbg.gdblib.info
import pwndbg.gdblib.memory
import pwndbg.gdblib.proc
import pwndbg.lib.elftypes
import pwndbg.lib.memoize
import pwndbg.proc
# ELF constants
PF_X, PF_W, PF_R = 1, 2, 4
@ -170,7 +170,7 @@ def get_containing_sections(elf_filepath, elf_loadaddr, vaddr):
return sections
@pwndbg.proc.OnlyWhenRunning
@pwndbg.gdblib.proc.OnlyWhenRunning
@pwndbg.lib.memoize.reset_on_start
def exe():
"""
@ -182,7 +182,7 @@ def exe():
return load(e)
@pwndbg.proc.OnlyWhenRunning
@pwndbg.gdblib.proc.OnlyWhenRunning
@pwndbg.lib.memoize.reset_on_start
def entry():
"""

@ -1,7 +1,7 @@
import gdb
import pwnlib
import pwndbg.proc
import pwndbg.gdblib.proc
from pwndbg.gdblib import typeinfo
from pwndbg.lib.arch import Arch
@ -31,7 +31,7 @@ def _get_arch(ptrsize):
else:
endian = "big"
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
arch = gdb.newest_frame().architecture().name()
else:
arch = gdb.execute("show architecture", to_string=True).strip()

@ -8,7 +8,7 @@ import functools
import gdb
import pwndbg.proc
import pwndbg.gdblib.proc
functions = []
@ -31,7 +31,7 @@ class _GdbFunction(gdb.Function):
self.__doc__ = func.__doc__
def invoke(self, *args):
if self.only_when_running and not pwndbg.proc.alive:
if self.only_when_running and not pwndbg.gdblib.proc.alive:
# Returning empty string is a workaround that we can't stop e.g. `break *$rebase(offset)`
# Thx to that, gdb will print out 'evaluation of this expression requires the target program to be active'
return ""

@ -10,8 +10,8 @@ import gdb
import pwndbg.disasm
import pwndbg.gdblib.events
import pwndbg.gdblib.proc
import pwndbg.gdblib.regs
import pwndbg.proc
from pwndbg.color import message
jumps = set((capstone.CS_GRP_CALL, capstone.CS_GRP_JUMP, capstone.CS_GRP_RET, capstone.CS_GRP_IRET))
@ -21,7 +21,7 @@ interrupts = set((capstone.CS_GRP_INT,))
@pwndbg.gdblib.events.exit
def clear_temp_breaks():
if not pwndbg.proc.alive:
if not pwndbg.gdblib.proc.alive:
breakpoints = gdb.breakpoints()
if breakpoints:
for bp in breakpoints:
@ -90,7 +90,7 @@ def break_next_interrupt(address=None):
def break_next_call(symbol_regex=None):
while pwndbg.proc.alive:
while pwndbg.gdblib.proc.alive:
ins = break_next_branch()
if not ins:
@ -114,7 +114,7 @@ def break_next_call(symbol_regex=None):
def break_next_ret(address=None):
while pwndbg.proc.alive:
while pwndbg.gdblib.proc.alive:
ins = break_next_branch(address)
if not ins:
@ -129,7 +129,7 @@ def break_on_program_code():
Breaks on next instruction that belongs to process' objfile code.
:return: True for success, False when process ended or when pc is at the code.
"""
exe = pwndbg.proc.exe
exe = pwndbg.gdblib.proc.exe
binary_exec_page_ranges = [
(p.start, p.end) for p in pwndbg.vmmap.get() if p.objfile == exe and p.execute
]
@ -140,7 +140,7 @@ def break_on_program_code():
print(message.error("The pc is already at the binary objfile code. Not stepping."))
return False
while pwndbg.proc.alive:
while pwndbg.gdblib.proc.alive:
gdb.execute("si", from_tty=False, to_string=False)
pc = pwndbg.gdblib.regs.pc

@ -19,7 +19,7 @@ import pwndbg.lib.memoize
class module(ModuleType):
@property
def pid(self):
# QEMU usermode emualtion always returns 42000 for some reason.
# QEMU usermode emulation always returns 42000 for some reason.
# In any case, we can't use the info.
if pwndbg.gdblib.qemu.is_qemu_usermode():
return pwndbg.gdblib.qemu.pid()
@ -64,10 +64,10 @@ class module(ModuleType):
On remote targets, this may be prefixed with "target:" string.
See this by executing those in two terminals:
1. gdbserver 127.0.0.1:1234 /bin/ls
2. gdb -ex "target remote :1234" -ex "pi pwndbg.proc.exe"
2. gdb -ex "target remote :1234" -ex "pi pwndbg.gdblib.proc.exe"
If you need to process the debugged file use:
`pwndbg.file.get_file(pwndbg.proc.exe)`
`pwndbg.file.get_file(pwndbg.gdblib.proc.exe)`
"""
return gdb.current_progspace().filename

@ -60,7 +60,7 @@ def prompt_hook(*a):
pwndbg.gdblib.events.after_reload(start=cur is None)
cur = new
if pwndbg.proc.alive and pwndbg.proc.thread_is_stopped and not context_shown:
if pwndbg.gdblib.proc.alive and pwndbg.gdblib.proc.thread_is_stopped and not context_shown:
pwndbg.commands.context.context()
context_shown = True

@ -11,18 +11,18 @@ import gdb
import pwndbg.gdblib.arch
import pwndbg.gdblib.events
import pwndbg.gdblib.proc
import pwndbg.gdblib.remote
import pwndbg.lib.memoize
import pwndbg.proc
from pwndbg.lib.regs import reg_sets
@pwndbg.proc.OnlyWhenRunning
@pwndbg.gdblib.proc.OnlyWhenRunning
def gdb77_get_register(name):
return gdb.parse_and_eval("$" + name)
@pwndbg.proc.OnlyWhenRunning
@pwndbg.gdblib.proc.OnlyWhenRunning
def gdb79_get_register(name):
return gdb.selected_frame().read_register(name)

@ -29,7 +29,9 @@ def decompile(func=None):
if not func:
func = (
hex(pwndbg.gdblib.regs[pwndbg.gdblib.regs.current.pc]) if pwndbg.proc.alive else "main"
hex(pwndbg.gdblib.regs[pwndbg.gdblib.regs.current.pc])
if pwndbg.gdblib.proc.alive
else "main"
)
src = r2.cmdj("pdgj @" + func)
@ -40,7 +42,7 @@ def decompile(func=None):
source = src.get("code", "")
# If not running there is no current pc to mark
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
pc = pwndbg.gdblib.regs[pwndbg.gdblib.regs.current.pc]
closest = 0

@ -7,9 +7,9 @@ import re
import pwndbg.config
import pwndbg.gdblib.memory
import pwndbg.gdblib.proc
import pwndbg.heap
import pwndbg.lib.memoize
import pwndbg.proc
import pwndbg.search
import pwndbg.symbol
@ -20,7 +20,7 @@ safe_lnk = pwndbg.config.Parameter(
glibc_version = pwndbg.config.Parameter("glibc", "", "GLIBC version for heuristics", scope="heap")
@pwndbg.proc.OnlyWhenRunning
@pwndbg.gdblib.proc.OnlyWhenRunning
def get_version():
if glibc_version.value:
ret = re.search(r"(\d+)\.(\d+)", glibc_version.value)
@ -34,7 +34,7 @@ def get_version():
return _get_version()
@pwndbg.proc.OnlyWhenRunning
@pwndbg.gdblib.proc.OnlyWhenRunning
@pwndbg.lib.memoize.reset_on_start
@pwndbg.lib.memoize.reset_on_objfile
def _get_version():

@ -53,7 +53,7 @@ def resolve_heap(is_first_run=False):
global current
if resolve_heap_via_heuristic:
current = pwndbg.heap.ptmalloc.HeuristicHeap()
if not is_first_run and pwndbg.proc.alive and current.libc_has_debug_syms():
if not is_first_run and pwndbg.gdblib.proc.alive and current.libc_has_debug_syms():
print(
message.warn(
"You are going to resolve the heap via heuristic even though you have libc debug symbols."

@ -15,13 +15,13 @@ import pwndbg.file
import pwndbg.gdblib.abi
import pwndbg.gdblib.events
import pwndbg.gdblib.memory
import pwndbg.gdblib.proc
import pwndbg.gdblib.qemu
import pwndbg.gdblib.regs
import pwndbg.gdblib.remote
import pwndbg.gdblib.stack
import pwndbg.gdblib.typeinfo
import pwndbg.lib.memoize
import pwndbg.proc
# List of manually-explored pages which were discovered
# by analyzing the stack or register context.
@ -59,7 +59,7 @@ def is_corefile():
@pwndbg.lib.memoize.reset_on_stop
def get():
# Note: debugging a coredump does still show proc.alive == True
if not pwndbg.proc.alive:
if not pwndbg.gdblib.proc.alive:
return tuple()
pages = []
pages.extend(proc_pid_maps())
@ -329,7 +329,7 @@ def proc_pid_maps():
# 7fff3c1e8000-7fff3c1ea000 r-xp 00000000 00:00 0 [vdso]
# ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
pid = pwndbg.proc.pid
pid = pwndbg.gdblib.proc.pid
locations = [
"/proc/%s/maps" % pid,
"/proc/%s/map" % pid,
@ -631,9 +631,9 @@ def check_aslr():
print("Could not check ASLR: can't read randomize_va_space")
# Check the personality of the process
if pwndbg.proc.alive:
if pwndbg.gdblib.proc.alive:
try:
data = pwndbg.file.get("/proc/%i/personality" % pwndbg.proc.pid)
data = pwndbg.file.get("/proc/%i/personality" % pwndbg.gdblib.proc.pid)
personality = int(data, 16)
return (personality & 0x40000 == 0), "read status from process' personality"
except Exception:

@ -11,7 +11,7 @@ cmd_pwntools = ["pwn", "checksec"]
@pwndbg.wrappers.OnlyWithCommand(cmd_name, cmd_pwntools)
@pwndbg.lib.memoize.reset_on_objfile
def get_raw_out():
local_path = pwndbg.file.get_file(pwndbg.proc.exe)
local_path = pwndbg.file.get_file(pwndbg.gdblib.proc.exe)
try:
return pwndbg.wrappers.call_cmd(get_raw_out.cmd + ["--file=" + local_path])
except CalledProcessError:

@ -5,7 +5,7 @@ cmd_name = "readelf"
@pwndbg.wrappers.OnlyWithCommand(cmd_name)
def get_jmpslots():
local_path = pwndbg.file.get_file(pwndbg.proc.exe)
local_path = pwndbg.file.get_file(pwndbg.gdblib.proc.exe)
cmd = get_jmpslots.cmd + ["--relocs", local_path]
readelf_out = pwndbg.wrappers.call_cmd(cmd)

@ -8,8 +8,8 @@ REFERENCE_BINARY = tests.binaries.get("reference-binary.out")
def test_command_procinfo(start_binary):
start_binary(REFERENCE_BINARY)
bin_path = gdb.execute("pi pwndbg.proc.exe", to_string=True).strip("\n")
pid = gdb.execute("pi pwndbg.proc.pid", to_string=True).strip("\n")
bin_path = gdb.execute("pi pwndbg.gdblib.proc.exe", to_string=True).strip("\n")
pid = gdb.execute("pi pwndbg.gdblib.proc.pid", to_string=True).strip("\n")
result = gdb.execute("procinfo", to_string=True)
res_list = result.split("\n")

@ -71,7 +71,7 @@ def test_telescope_command_with_address_as_count(start_binary):
assert len(out) == 2
assert out[0] == "00:0000│ rsp %#x ◂— 0x1" % rsp
expected = r"01:0008│ %#x —▸ 0x[0-9a-f]+ ◂— '%s'" % (rsp + 8, pwndbg.proc.exe)
expected = r"01:0008│ %#x —▸ 0x[0-9a-f]+ ◂— '%s'" % (rsp + 8, pwndbg.gdblib.proc.exe)
assert re.search(expected, out[1])

@ -25,7 +25,7 @@ def get_proc_maps():
# Note: info proc mappings may not have permissions information,
# so we get it here and fill from `perms`
with open("/proc/%d/maps" % pwndbg.proc.pid, "r") as f:
with open("/proc/%d/maps" % pwndbg.gdblib.proc.pid, "r") as f:
for line in f.read().splitlines():
addrs, perms, offset, _inode, size, objfile = line.split(maxsplit=6)
start, end = map(lambda v: int(v, 16), addrs.split("-"))

@ -21,7 +21,9 @@ def test_command_nextproginstr(start_binary):
assert out == "The pc is already at the binary objfile code. Not stepping.\n"
# Sanity check
exec_bin_pages = [p for p in pwndbg.vmmap.get() if p.objfile == pwndbg.proc.exe and p.execute]
exec_bin_pages = [
p for p in pwndbg.vmmap.get() if p.objfile == pwndbg.gdblib.proc.exe and p.execute
]
assert any(pwndbg.gdblib.regs.pc in p for p in exec_bin_pages)
main_page = pwndbg.vmmap.find(pwndbg.gdblib.regs.pc)

Loading…
Cancel
Save