Port a handful of commands to the Debugger-agnostic interfaces (#2416)

* Port a handful of commands to LLDB

* Update pwndbg/commands/elf.py

---------

Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
pull/2434/head
Matt. 1 year ago committed by GitHub
parent c80793f41e
commit 94f82fff79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -694,28 +694,14 @@ def load_commands() -> None:
import pwndbg.commands.binder
import pwndbg.commands.binja
import pwndbg.commands.branch
import pwndbg.commands.canary
import pwndbg.commands.checksec
import pwndbg.commands.comments
import pwndbg.commands.config
import pwndbg.commands.context
import pwndbg.commands.cpsr
import pwndbg.commands.cyclic
import pwndbg.commands.cymbol
import pwndbg.commands.dev
import pwndbg.commands.distance
import pwndbg.commands.dt
import pwndbg.commands.dumpargs
import pwndbg.commands.elf
import pwndbg.commands.flags
import pwndbg.commands.gdt
import pwndbg.commands.ghidra
import pwndbg.commands.godbg
import pwndbg.commands.got
import pwndbg.commands.got_tracking
import pwndbg.commands.heap
import pwndbg.commands.heap_tracking
import pwndbg.commands.hexdump
import pwndbg.commands.ida
import pwndbg.commands.ignore
import pwndbg.commands.integration
@ -726,42 +712,57 @@ def load_commands() -> None:
import pwndbg.commands.kconfig
import pwndbg.commands.killthreads
import pwndbg.commands.kversion
import pwndbg.commands.leakfind
import pwndbg.commands.linkmap
import pwndbg.commands.memoize
import pwndbg.commands.misc
import pwndbg.commands.mmap
import pwndbg.commands.mprotect
import pwndbg.commands.nearpc
import pwndbg.commands.next
import pwndbg.commands.onegadget
import pwndbg.commands.p2p
import pwndbg.commands.patch
import pwndbg.commands.pcplist
import pwndbg.commands.peda
import pwndbg.commands.pie
import pwndbg.commands.plist
import pwndbg.commands.probeleak
import pwndbg.commands.procinfo
import pwndbg.commands.radare2
import pwndbg.commands.reload
import pwndbg.commands.retaddr
import pwndbg.commands.rizin
import pwndbg.commands.rop
import pwndbg.commands.ropper
import pwndbg.commands.search
import pwndbg.commands.segments
import pwndbg.commands.shell
import pwndbg.commands.sigreturn
import pwndbg.commands.slab
import pwndbg.commands.spray
import pwndbg.commands.start
import pwndbg.commands.telescope
import pwndbg.commands.tips
import pwndbg.commands.tls
import pwndbg.commands.valist
import pwndbg.commands.version
import pwndbg.commands.vmmap
import pwndbg.commands.windbg
import pwndbg.commands.xinfo
import pwndbg.commands.xor
import pwndbg.commands.canary
import pwndbg.commands.checksec
import pwndbg.commands.comments
import pwndbg.commands.config
import pwndbg.commands.context
import pwndbg.commands.cpsr
import pwndbg.commands.cyclic
import pwndbg.commands.dev
import pwndbg.commands.distance
import pwndbg.commands.dumpargs
import pwndbg.commands.elf
import pwndbg.commands.flags
import pwndbg.commands.heap
import pwndbg.commands.hexdump
import pwndbg.commands.leakfind
import pwndbg.commands.nearpc
import pwndbg.commands.p2p
import pwndbg.commands.patch
import pwndbg.commands.pie
import pwndbg.commands.probeleak
import pwndbg.commands.retaddr
import pwndbg.commands.search
import pwndbg.commands.sigreturn
import pwndbg.commands.spray
import pwndbg.commands.telescope
import pwndbg.commands.valist
import pwndbg.commands.vmmap
import pwndbg.commands.windbg
import pwndbg.commands.xinfo
import pwndbg.commands.xor

@ -2,11 +2,12 @@ from __future__ import annotations
import argparse
import pwndbg.aglib.memory
import pwndbg.aglib.regs
import pwndbg.aglib.stack
import pwndbg.auxv
import pwndbg.commands
import pwndbg.commands.telescope
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.search
from pwndbg.color import message
from pwndbg.commands import CommandCategory
@ -19,10 +20,10 @@ def canary_value():
if at_random is None:
return None, None
global_canary = pwndbg.gdblib.memory.pvoid(at_random)
global_canary = pwndbg.aglib.memory.pvoid(at_random)
# masking canary value as canaries on the stack has last byte = 0
global_canary &= pwndbg.gdblib.arch.ptrmask ^ 0xFF
global_canary &= pwndbg.aglib.arch.ptrmask ^ 0xFF
return global_canary, at_random
@ -51,8 +52,8 @@ def canary(all) -> None:
print(message.notice("Canary = 0x%x (may be incorrect on != glibc)" % global_canary))
found_canaries = False
global_canary_packed = pwndbg.gdblib.arch.pack(global_canary)
thread_stacks = pwndbg.gdblib.stack.get()
global_canary_packed = pwndbg.aglib.arch.pack(global_canary)
thread_stacks = pwndbg.aglib.stack.get()
for thread in thread_stacks:
thread_stack = thread_stacks[thread]

@ -2,9 +2,9 @@ from __future__ import annotations
import argparse
import pwndbg.aglib.file
import pwndbg.color
import pwndbg.commands
import pwndbg.gdblib.file
import pwndbg.wrappers.checksec
parser = argparse.ArgumentParser(
@ -17,5 +17,5 @@ parser.add_argument("-f", "--file", type=str, help="Specify the file to run `che
@pwndbg.commands.ArgparsedCommand(parser, command_name="checksec")
@pwndbg.commands.OnlyWithFile
def checksec(file: str) -> None:
local_path = file or pwndbg.gdblib.file.get_proc_exe_file()
local_path = file or pwndbg.aglib.file.get_proc_exe_file()
print(pwndbg.wrappers.checksec.get_raw_out(local_path))

@ -19,20 +19,20 @@ file_lists: Dict[str, Dict[str, str]] = {} # This saves all comments.
@pwndbg.commands.OnlyWhenRunning
def comm(addr=None, comment=None) -> None:
if addr is None:
addr = hex(pwndbg.gdblib.regs.pc)
addr = hex(pwndbg.aglib.regs.pc)
try:
with open(".gdb_comments", "a+") as f:
target = int(addr, 0)
if not pwndbg.gdblib.memory.peek(target):
if not pwndbg.aglib.memory.peek(target):
print(message.error("Invalid Address %#x" % target))
else:
f.write(f"file:{pwndbg.gdblib.proc.exe}=")
f.write(f"file:{pwndbg.aglib.proc.exe}=")
f.write(f"{target:#x}:{comment}\n")
if pwndbg.gdblib.proc.exe not in file_lists:
file_lists[pwndbg.gdblib.proc.exe] = {}
file_lists[pwndbg.gdblib.proc.exe][hex(target)] = comment
if pwndbg.aglib.proc.exe not in file_lists:
file_lists[pwndbg.aglib.proc.exe] = {}
file_lists[pwndbg.aglib.proc.exe][hex(target)] = comment
except Exception:
print(message.error("Permission denied to create file"))

@ -8,7 +8,6 @@ import argparse
import pwndbg
import pwndbg.commands
import pwndbg.gdblib.config
import pwndbg.lib.config
from pwndbg.color import generateColorFunction
from pwndbg.color import ljust_colored
@ -16,6 +15,9 @@ from pwndbg.color import strip
from pwndbg.color.message import hint
from pwndbg.commands import CommandCategory
if pwndbg.dbg.is_gdblib_available():
import pwndbg.gdblib.config
def print_row(
name: str,
@ -134,9 +136,11 @@ def theme(filter_pattern) -> None:
display_config(filter_pattern, "theme")
@pwndbg.commands.ArgparsedCommand(configfile_parser, category=CommandCategory.PWNDBG)
def configfile(show_all=False) -> None:
configfile_print_scope("config", show_all)
if pwndbg.dbg.is_gdblib_available():
@pwndbg.commands.ArgparsedCommand(configfile_parser, category=CommandCategory.PWNDBG)
def configfile(show_all=False) -> None:
configfile_print_scope("config", show_all)
themefile_parser = argparse.ArgumentParser(
@ -147,9 +151,11 @@ themefile_parser.add_argument(
)
@pwndbg.commands.ArgparsedCommand(themefile_parser, category=CommandCategory.PWNDBG)
def themefile(show_all=False) -> None:
configfile_print_scope("theme", show_all)
if pwndbg.dbg.is_gdblib_available():
@pwndbg.commands.ArgparsedCommand(themefile_parser, category=CommandCategory.PWNDBG)
def themefile(show_all=False) -> None:
configfile_print_scope("theme", show_all)
def configfile_print_scope(scope: str, show_all: bool = False) -> None:

@ -11,10 +11,11 @@ from typing import Dict
from typing import List
from typing import Tuple
import gdb
import pwndbg
import pwndbg.aglib.arch
import pwndbg.aglib.disasm
import pwndbg.aglib.nearpc
import pwndbg.aglib.regs
import pwndbg.arguments
import pwndbg.chain
import pwndbg.color
@ -23,20 +24,21 @@ import pwndbg.color.memory as M
import pwndbg.color.syntax_highlight as H
import pwndbg.commands
import pwndbg.commands.telescope
import pwndbg.gdblib.heap_tracking
import pwndbg.gdblib.nearpc
import pwndbg.gdblib.regs
import pwndbg.gdblib.symbol
import pwndbg.gdblib.vmmap
import pwndbg.ghidra
import pwndbg.integration
import pwndbg.ui
from pwndbg.aglib.arch import get_thumb_mode_string
from pwndbg.color import ColorConfig
from pwndbg.color import ColorParamSpec
from pwndbg.color import message
from pwndbg.color import theme
from pwndbg.commands import CommandCategory
from pwndbg.gdblib.arch import get_thumb_mode_string
if pwndbg.dbg.is_gdblib_available():
import gdb
import pwndbg.gdblib.heap_tracking
import pwndbg.gdblib.symbol
import pwndbg.ghidra
theme.add_param("backtrace-prefix", "", "prefix for current backtrace label")
@ -557,26 +559,26 @@ def get_regs(regs: List[str] = None):
regs = []
if len(regs) == 0:
regs += pwndbg.gdblib.regs.gpr
regs += pwndbg.aglib.regs.gpr
regs.append(pwndbg.gdblib.regs.frame)
regs.append(pwndbg.gdblib.regs.stack)
regs.append(pwndbg.aglib.regs.frame)
regs.append(pwndbg.aglib.regs.stack)
if pwndbg.config.show_retaddr_reg:
regs += pwndbg.gdblib.regs.retaddr
regs += pwndbg.aglib.regs.retaddr
regs.append(pwndbg.gdblib.regs.current.pc)
regs.append(pwndbg.aglib.regs.current.pc)
if pwndbg.config.show_flags:
regs += pwndbg.gdblib.regs.flags.keys()
regs += pwndbg.aglib.regs.flags.keys()
changed = pwndbg.gdblib.regs.changed
changed = pwndbg.aglib.regs.changed
for reg in regs:
if reg is None:
continue
value = pwndbg.gdblib.regs[reg]
value = pwndbg.aglib.regs[reg]
if value is None:
print(message.warn("Unknown register: %r" % reg))
continue
@ -591,13 +593,13 @@ def get_regs(regs: List[str] = None):
m = " " * len(change_marker) if reg not in changed else C.register_changed(change_marker)
bit_flags = None
if reg in pwndbg.gdblib.regs.flags:
bit_flags = pwndbg.gdblib.regs.flags[reg]
elif reg in pwndbg.gdblib.regs.extra_flags:
bit_flags = pwndbg.gdblib.regs.extra_flags[reg]
if reg in pwndbg.aglib.regs.flags:
bit_flags = pwndbg.aglib.regs.flags[reg]
elif reg in pwndbg.aglib.regs.extra_flags:
bit_flags = pwndbg.aglib.regs.extra_flags[reg]
if bit_flags:
desc = C.format_flags(value, bit_flags, pwndbg.gdblib.regs.last.get(reg, 0))
desc = C.format_flags(value, bit_flags, pwndbg.aglib.regs.last.get(reg, 0))
else:
desc = pwndbg.chain.format(value)
@ -612,14 +614,7 @@ disasm_lines = pwndbg.config.add_param(
def context_disasm(target=sys.stdout, with_banner=True, width=None):
try:
flavor = gdb.execute("show disassembly-flavor", to_string=True).lower().split('"')[1]
except gdb.error as e:
if str(e).find("disassembly-flavor") > -1:
flavor = "intel"
else:
raise
flavor = pwndbg.dbg.x86_disassembly_flavor()
syntax = pwndbg.aglib.disasm.CapstoneSyntax[flavor]
# Get the Capstone object to set disassembly syntax
@ -629,7 +624,7 @@ def context_disasm(target=sys.stdout, with_banner=True, width=None):
if cs is not None and cs.syntax != syntax:
pwndbg.lib.cache.clear_caches()
result = pwndbg.gdblib.nearpc.nearpc(
result = pwndbg.aglib.nearpc.nearpc(
lines=disasm_lines // 2,
emulate=bool(not pwndbg.config.emulate == "off"),
use_cache=True,
@ -641,10 +636,10 @@ def context_disasm(target=sys.stdout, with_banner=True, width=None):
thumb_mode_str = get_thumb_mode_string()
if thumb_mode_str is not None:
info = " / {} / {} mode / set emulate {}".format(
pwndbg.gdblib.arch.current, thumb_mode_str, pwndbg.config.emulate
pwndbg.aglib.arch.current, thumb_mode_str, pwndbg.config.emulate
)
else:
info = " / {} / set emulate {}".format(pwndbg.gdblib.arch.current, pwndbg.config.emulate)
info = " / {} / set emulate {}".format(pwndbg.aglib.arch.current, pwndbg.config.emulate)
banner = [pwndbg.ui.banner("disasm", target=target, width=width, extra=info)]
# If we didn't disassemble backward, try to make sure
@ -684,23 +679,22 @@ def get_filename_and_formatted_source():
Returns formatted, lines limited and highlighted source as list
or if it isn't there - an empty list
"""
sal = gdb.selected_frame().find_sal() # gdb.Symtab_and_line
sal = pwndbg.dbg.selected_frame().sal()
# Check if source code is available
if sal.symtab is None:
return "", []
if sal is None:
return "", [], 0
# Get the full source code
closest_line = sal.line
filename = sal.symtab.fullname()
filename, closest_line = sal
try:
source = get_highlight_source(filename)
except OSError:
return "", []
return "", [], closest_line
if not source:
return "", []
return "", [], closest_line
n = int(source_disasm_lines)
@ -734,7 +728,7 @@ def get_filename_and_formatted_source():
)
formatted_source.append(line)
return filename, formatted_source
return filename, formatted_source, closest_line
should_decompile = pwndbg.config.add_param(
@ -745,24 +739,18 @@ should_decompile = pwndbg.config.add_param(
def context_code(target=sys.stdout, with_banner=True, width=None):
filename, formatted_source = get_filename_and_formatted_source()
filename, formatted_source, line = get_filename_and_formatted_source()
# Try getting source from files
if formatted_source:
bannerline = (
[pwndbg.ui.banner("Source (code)", target=target, width=width)] if with_banner else []
)
return (
bannerline
+ ["In file: %s:%d" % (filename, gdb.selected_frame().find_sal().line)]
+ formatted_source
)
return bannerline + ["In file: %s:%d" % (filename, line)] + formatted_source
if should_decompile:
# Will be None if decompilation fails
code = pwndbg.integration.provider.decompile(
pwndbg.gdblib.regs.pc, int(source_disasm_lines)
)
code = pwndbg.integration.provider.decompile(pwndbg.aglib.regs.pc, int(source_disasm_lines))
if code:
bannerline = (
@ -781,7 +769,7 @@ stack_lines = pwndbg.config.add_param(
def context_stack(target=sys.stdout, with_banner=True, width=None):
result = [pwndbg.ui.banner("stack", target=target, width=width)] if with_banner else []
telescope = pwndbg.commands.telescope.telescope(
pwndbg.gdblib.regs.sp, to_string=True, count=stack_lines
pwndbg.aglib.regs.sp, to_string=True, count=stack_lines
)
if telescope:
result.extend(telescope)
@ -802,15 +790,15 @@ def context_backtrace(with_banner=True, target=sys.stdout, width=None):
if with_banner:
result.append(pwndbg.ui.banner("backtrace", target=target, width=width))
this_frame = gdb.selected_frame()
this_frame = pwndbg.dbg.selected_frame()
newest_frame = this_frame
oldest_frame = this_frame
for i in range(backtrace_lines - 1):
try:
candidate = oldest_frame.older()
# We catch gdb.error in case of a `gdb.error: PC not saved` case
except (gdb.MemoryError, gdb.error):
candidate = oldest_frame.parent()
# We catch an error in case of a `gdb.error: PC not saved` case
except pwndbg.dbg_mod.Error:
break
if not candidate:
@ -818,7 +806,7 @@ def context_backtrace(with_banner=True, target=sys.stdout, width=None):
oldest_frame = candidate
for i in range(backtrace_lines - 1):
candidate = newest_frame.newer()
candidate = newest_frame.child()
if not candidate:
break
newest_frame = candidate
@ -830,7 +818,7 @@ def context_backtrace(with_banner=True, target=sys.stdout, width=None):
prefix = bt_prefix if frame == this_frame else " " * len(bt_prefix)
prefix = f" {c.prefix(prefix)}"
addrsz = c.address(pwndbg.ui.addrsz(frame.pc()))
symbol = c.symbol(pwndbg.gdblib.symbol.get(int(frame.pc())))
symbol = c.symbol(pwndbg.dbg.selected_inferior().symbol_name_at_address(int(frame.pc())))
if symbol:
addrsz = addrsz + " " + symbol
line = map(str, (prefix, c.frame_label("%s%i" % (backtrace_frame_label, i)), addrsz))
@ -840,7 +828,7 @@ def context_backtrace(with_banner=True, target=sys.stdout, width=None):
if frame == oldest_frame:
break
frame = frame.older()
frame = frame.parent()
i += 1
return result
@ -973,7 +961,7 @@ def save_signal(signal) -> None:
# we can't access $_siginfo, so lets just show current pc
# see also issue 476
if _is_rr_present():
msg += " (current pc: %#x)" % pwndbg.gdblib.regs.pc
msg += " (current pc: %#x)" % pwndbg.aglib.regs.pc
else:
try:
si_addr = gdb.parse_and_eval("$_siginfo._sifields._sigfault.si_addr")
@ -987,9 +975,10 @@ def save_signal(signal) -> None:
result.append(message.breakpoint(f"Breakpoint {(bkpt.location)}"))
gdb.events.cont.connect(save_signal)
gdb.events.stop.connect(save_signal)
gdb.events.exited.connect(save_signal)
if pwndbg.dbg.is_gdblib_available():
gdb.events.cont.connect(save_signal)
gdb.events.stop.connect(save_signal)
gdb.events.exited.connect(save_signal)
def context_signal():
@ -997,19 +986,26 @@ def context_signal():
context_sections = {
"a": context_args,
"r": context_regs,
"d": context_disasm,
"a": context_args,
"c": context_code,
"s": context_stack,
"b": context_backtrace,
"e": context_expressions,
"g": context_ghidra,
"h": context_heap_tracker,
"t": context_threads,
"c": context_code,
}
if pwndbg.dbg.is_gdblib_available():
# Add the sections that need gdblib.
context_sections = {
**context_sections,
"e": context_expressions,
"g": context_ghidra,
"h": context_heap_tracker,
"t": context_threads,
}
@pwndbg.lib.cache.cache_until("forever")
def _is_rr_present() -> bool:
"""

@ -2,9 +2,9 @@ from __future__ import annotations
import argparse
import pwndbg.aglib.arch
import pwndbg.aglib.regs
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.regs
from pwndbg.color import context
from pwndbg.commands import CommandCategory
@ -23,12 +23,12 @@ parser.add_argument(
@pwndbg.commands.OnlyWithArch(["arm", "armcm", "aarch64"])
@pwndbg.commands.OnlyWhenRunning
def cpsr(cpsr_value=None) -> None:
reg = "xpsr" if pwndbg.gdblib.arch.name == "armcm" else "cpsr"
reg_flags = pwndbg.gdblib.regs.flags[reg]
reg = "xpsr" if pwndbg.aglib.arch.name == "armcm" else "cpsr"
reg_flags = pwndbg.aglib.regs.flags[reg]
if cpsr_value is not None:
reg_val = cpsr_value
else:
reg_val = getattr(pwndbg.gdblib.regs, reg)
reg_val = getattr(pwndbg.aglib.regs, reg)
print(f"{reg} {context.format_flags(reg_val, reg_flags)}")

@ -7,8 +7,8 @@ from typing import Optional
from pwnlib.util.cyclic import cyclic
from pwnlib.util.cyclic import cyclic_find
import pwndbg.aglib.arch
import pwndbg.commands
import pwndbg.gdblib.arch
from pwndbg.color import message
parser = argparse.ArgumentParser(description="Cyclic pattern creator/finder.")
@ -63,13 +63,13 @@ parser.add_argument(
@pwndbg.commands.ArgparsedCommand(parser, command_name="cyclic")
def cyclic_cmd(alphabet, length: Optional[int], lookup, count=100, filename="") -> None:
if length is None:
length = pwndbg.gdblib.arch.ptrsize
length = pwndbg.aglib.arch.ptrsize
if lookup:
lookup = pwndbg.commands.fix(lookup, sloppy=True)
if isinstance(lookup, (pwndbg.dbg_mod.Value, int)):
lookup = int(lookup).to_bytes(length, pwndbg.gdblib.arch.endian)
lookup = int(lookup).to_bytes(length, pwndbg.aglib.arch.endian)
elif isinstance(lookup, str):
lookup = bytes(lookup, "utf-8")

@ -6,7 +6,6 @@ import logging
import pwndbg.aglib.disasm
import pwndbg.color.message as MessageColor
import pwndbg.commands
import pwndbg.gdblib.nearpc
from pwndbg.commands import CommandCategory
parser = argparse.ArgumentParser(description="Dump internal PwndbgInstruction attributes.")
@ -58,7 +57,7 @@ def dev_dump_instruction(address=None, force_emulate=False, no_emulate=False) ->
)
instructions, index_of_pc = pwndbg.aglib.disasm.near(
pwndbg.gdblib.regs.pc, 1, emulate=use_emulation, show_prev_insns=False, use_cache=False
pwndbg.aglib.regs.pc, 1, emulate=use_emulation, show_prev_insns=False, use_cache=False
)
if instructions:

@ -2,9 +2,9 @@ from __future__ import annotations
import argparse
import pwndbg.aglib.arch
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.arch
from pwndbg.commands import CommandCategory
parser = argparse.ArgumentParser(
@ -19,7 +19,7 @@ def distance(a, b) -> None:
"""Print the distance between the two arguments"""
if b is None:
page = pwndbg.gdblib.vmmap.find(a)
page = pwndbg.aglib.vmmap.find(a)
if not page:
print("%#x does not belong to a mapped page in memory" % (a))
@ -31,17 +31,17 @@ def distance(a, b) -> None:
page.vaddr,
a,
distance,
distance // pwndbg.gdblib.arch.ptrsize,
distance // pwndbg.aglib.arch.ptrsize,
)
print(M.get(page.vaddr, text=display_text))
else:
a = int(a) & pwndbg.gdblib.arch.ptrmask
b = int(b) & pwndbg.gdblib.arch.ptrmask
a = int(a) & pwndbg.aglib.arch.ptrmask
b = int(b) & pwndbg.aglib.arch.ptrmask
distance = b - a
print(
"%#x->%#x is %#x bytes (%#x words)"
% (a, b, distance, distance // pwndbg.gdblib.arch.ptrsize)
% (a, b, distance, distance // pwndbg.aglib.arch.ptrsize)
)

@ -3,12 +3,12 @@ from __future__ import annotations
import argparse
from typing import List
import pwndbg.aglib.arch
import pwndbg.aglib.disasm
import pwndbg.arguments
import pwndbg.chain
import pwndbg.commands
import pwndbg.commands.telescope
import pwndbg.gdblib.arch
parser = argparse.ArgumentParser(description="Prints determined arguments for call instruction.")
parser.add_argument("-f", "--force", action="store_true", help="Force displaying of all arguments.")
@ -24,7 +24,7 @@ def dumpargs(force: bool = False) -> None:
else:
print("Couldn't resolve call arguments from registers.")
print(
f"Detected ABI: {pwndbg.gdblib.arch.name} ({pwndbg.gdblib.arch.ptrsize * 8} bit) either doesn't pass arguments through registers or is not implemented. Maybe they are passed on the stack?"
f"Detected ABI: {pwndbg.aglib.arch.name} ({pwndbg.aglib.arch.ptrsize * 8} bit) either doesn't pass arguments through registers or is not implemented. Maybe they are passed on the stack?"
)

@ -12,7 +12,7 @@ from pwndbg.commands import CommandCategory
)
@pwndbg.commands.OnlyWithFile
def elfsections() -> None:
local_path = pwndbg.gdblib.file.get_proc_exe_file()
local_path = pwndbg.aglib.file.get_proc_exe_file()
with open(local_path, "rb") as f:
elffile = ELFFile(f)
@ -51,7 +51,7 @@ def plt() -> None:
def get_section_bounds(section_name):
local_path = pwndbg.gdblib.file.get_proc_exe_file()
local_path = pwndbg.aglib.file.get_proc_exe_file()
with open(local_path, "rb") as f:
elffile = ELFFile(f)
@ -74,8 +74,8 @@ def print_symbols_in_section(section_name, filter_text="") -> None:
return
# If we started the binary and it has PIE, rebase it
if pwndbg.gdblib.proc.alive:
bin_base_addr = pwndbg.gdblib.proc.binary_base_addr
if pwndbg.aglib.proc.alive:
bin_base_addr = pwndbg.aglib.proc.binary_base_addr
# Rebase the start and end addresses if needed
if start < bin_base_addr:
@ -95,11 +95,11 @@ def print_symbols_in_section(section_name, filter_text="") -> None:
def get_symbols_in_region(start, end, filter_text=""):
symbols = []
ptr_size = pwndbg.gdblib.typeinfo.pvoid.sizeof
ptr_size = pwndbg.aglib.typeinfo.pvoid.sizeof
addr = start
while addr < end:
name = pwndbg.gdblib.symbol.get(addr, gdb_only=True)
if name != "" and "+" not in name and filter_text in name:
name = pwndbg.dbg.selected_inferior().symbol_name_at_address(addr)
if name and "+" not in name and filter_text in name:
symbols.append((name, addr))
addr += ptr_size

@ -35,7 +35,7 @@ parser.add_argument(
@pwndbg.commands.ArgparsedCommand(parser, aliases=["flag"], category=CommandCategory.REGISTER)
def setflag(flag: str, value: int) -> None:
register_set = pwndbg.gdblib.regs.current
register_set = pwndbg.aglib.regs.current
flag = flag.upper()
for flag_reg, flags in register_set.flags.items():
@ -54,14 +54,14 @@ def setflag(flag: str, value: int) -> None:
print(f"Maximum value for flag is {max_val} (size={size})")
return
old_val = int(pwndbg.gdblib.regs[flag_reg])
old_val = int(pwndbg.aglib.regs[flag_reg])
mask = max_val << bit
bit_value = value << bit
cleared_val = old_val & ~mask
new_val = cleared_val | bit_value
setattr(pwndbg.gdblib.regs, flag_reg, new_val)
setattr(pwndbg.aglib.regs, flag_reg, new_val)
print(
f"Set flag {flag}={value} in flag register {flag_reg} (old val={old_val:#x}, new val={new_val:#x})"
)

@ -107,7 +107,7 @@ def format_bin(bins: Bins, verbose: bool = False, offset: int | None = None) ->
if bins_type == BinType.LARGE:
start_size, end_size = allocator.largebin_size_range_from_index(size)
size = hex(start_size) + "-"
if end_size != pwndbg.gdblib.arch.ptrmask:
if end_size != pwndbg.aglib.arch.ptrmask:
size += hex(end_size)
else:
size += "\u221e" # Unicode "infinity"
@ -245,14 +245,14 @@ def hi(addr: int, verbose: bool = False, simple: bool = False, fake: bool = Fals
if addr in chunk:
malloc_chunk(chunk.address, verbose=verbose, simple=simple)
if verbose:
start = chunk.address + (pwndbg.gdblib.arch.ptrsize if chunk.prev_inuse else 0x00)
start = chunk.address + (pwndbg.aglib.arch.ptrsize if chunk.prev_inuse else 0x00)
print(f"Your address: {hex(addr)}")
print(f"Head offset: {hex(addr - start)}")
if chunk.is_top_chunk is False and chunk.real_size is not None:
end = (
start
+ chunk.real_size
+ (pwndbg.gdblib.arch.ptrsize if chunk.prev_inuse is False else 0x00)
+ (pwndbg.aglib.arch.ptrsize if chunk.prev_inuse is False else 0x00)
)
print(f"Tail offset: {hex(end - addr)}")
break
@ -547,7 +547,7 @@ def malloc_chunk(
if dump:
print(C.banner("hexdump"))
ptr_size = pwndbg.gdblib.arch.ptrsize
ptr_size = pwndbg.aglib.arch.ptrsize
pwndbg.commands.hexdump.hexdump(chunk.address, chunk.real_size + ptr_size)
if next:
@ -908,7 +908,7 @@ def find_fake_fast(
candidate = search_region[i : i + size_field_width]
if len(candidate) == size_field_width:
size_field = pwndbg.gdblib.arch.unpack_size(candidate, size_field_width)
size_field = pwndbg.aglib.arch.unpack_size(candidate, size_field_width)
size_field &= ~(allocator.malloc_align_mask)
if size_field < min_chunk_size or size_field > max_candidate_size:
@ -991,7 +991,7 @@ def vis_heap_chunks(
addr = count
count = pwndbg.config.default_visualize_chunk_number
if addr is not None and not pwndbg.gdblib.memory.is_readable_address(int(addr)):
if addr is not None and not pwndbg.aglib.memory.is_readable_address(int(addr)):
print(message.error("The provided address is not readable."))
return
@ -1117,7 +1117,7 @@ def vis_heap_chunks(
out += "\n0x%x" % cursor
data = pwndbg.aglib.memory.read(cursor, ptr_size)
cell = pwndbg.gdblib.arch.unpack(data)
cell = pwndbg.aglib.arch.unpack(data)
cell_hex = f"\t0x{cell:0{ptr_size * 2}x}"
out += color_func(cell_hex)
@ -1220,7 +1220,7 @@ def try_free(addr: str | int) -> None:
malloc_align_mask = allocator.malloc_align_mask
chunk_minsize = allocator.minsize
ptr_size = pwndbg.gdblib.arch.ptrsize
ptr_size = pwndbg.aglib.arch.ptrsize
def unsigned_size(size: int):
# read_chunk()['size'] is signed in pwndbg ;/

@ -2,13 +2,11 @@ from __future__ import annotations
import argparse
import gdb
import pwndbg
import pwndbg.aglib.arch
import pwndbg.aglib.memory
import pwndbg.aglib.regs
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.hexdump
from pwndbg.color import message
from pwndbg.commands import CommandCategory
@ -29,18 +27,17 @@ pwndbg.config.add_param(
)
def address_or_module_name(s):
gdbval_or_str = pwndbg.commands.sloppy_gdb_parse(s)
if isinstance(gdbval_or_str, str):
module_name = gdbval_or_str
pages = list(filter(lambda page: module_name in page.objfile, pwndbg.gdblib.vmmap.get()))
def address_or_module_name(s) -> int:
addr_or_str: int | str = pwndbg.commands.sloppy_gdb_parse(s)
if isinstance(addr_or_str, str):
module_name = addr_or_str
pages = list(filter(lambda page: module_name in page.objfile, pwndbg.aglib.vmmap.get()))
if pages:
return pages[0].vaddr
else:
raise argparse.ArgumentTypeError(f"Could not find pages for module {module_name}")
elif isinstance(gdbval_or_str, (int, gdb.Value)):
addr = gdbval_or_str
return addr
elif isinstance(addr_or_str, int):
return addr_or_str
else:
raise argparse.ArgumentTypeError("Unknown hexdump argument type.")
@ -69,8 +66,8 @@ def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
hexdump.offset = 0
address = int(address)
if address > pwndbg.gdblib.arch.ptrmask:
new_address = address & pwndbg.gdblib.arch.ptrmask
if address > pwndbg.aglib.arch.ptrmask:
new_address = address & pwndbg.aglib.arch.ptrmask
print(
message.warn("0x%x is larger than the maximum address, truncating to 0x%x instead"),
address,
@ -82,11 +79,11 @@ def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
width = int(pwndbg.config.hexdump_width)
group_width = int(pwndbg.config.hexdump_group_width)
group_width = pwndbg.gdblib.typeinfo.ptrsize if group_width == -1 else group_width
group_width = pwndbg.aglib.typeinfo.ptrsize if group_width == -1 else group_width
# TODO: What if arch endian is big, and use_big_endian is false?
flip_group_endianness = (
bool(pwndbg.config.hexdump_group_use_big_endian) and pwndbg.gdblib.arch.endian == "little"
bool(pwndbg.config.hexdump_group_use_big_endian) and pwndbg.aglib.arch.endian == "little"
)
# The user may have input the start and end range to dump instead of the
@ -97,9 +94,9 @@ def hexdump(address, count=pwndbg.config.hexdump_bytes) -> None:
count -= address
try:
data = pwndbg.gdblib.memory.read(address, count, partial=True)
data = pwndbg.aglib.memory.read(address, count, partial=True)
hexdump.last_address = address + count
except gdb.error as e:
except pwndbg.dbg_mod.Error as e:
print(e)
return

@ -9,12 +9,10 @@ import queue
from typing import Dict
from typing import List
import gdb
import pwndbg
import pwndbg.aglib.vmmap
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.vmmap
from pwndbg.chain import c as C
from pwndbg.color import message
from pwndbg.commands import CommandCategory
@ -24,7 +22,7 @@ from pwndbg.commands import CommandCategory
# addr is a pointer. It is taken to be a child pointer.
# visited_map is a map of children -> (parent,parent_start)
def get_rec_addr_string(addr, visited_map):
page = pwndbg.gdblib.vmmap.find(addr)
page = pwndbg.aglib.vmmap.find(addr)
arrow_right = C.arrow(" %s " % pwndbg.config.chain_arrow_right)
if page is not None:
@ -122,12 +120,15 @@ def leakfind(
):
if address is None:
raise argparse.ArgumentTypeError("No starting address provided.")
foundPages = pwndbg.gdblib.vmmap.find(address)
address = int(address)
foundPages = pwndbg.aglib.vmmap.find(address)
if not foundPages:
raise argparse.ArgumentTypeError("Starting address is not mapped.")
if not pwndbg.gdblib.memory.peek(address):
if not pwndbg.aglib.memory.peek(address):
raise argparse.ArgumentTypeError("Unable to read from starting address.")
# Just warn the user that a large depth might be slow.
@ -136,7 +137,6 @@ def leakfind(
print(message.warn("leakfind may take a while to run on larger depths."))
stride = step
address = int(address)
# The below map stores a map of child address->(parent_address,parent_start_address)
# In the above tuple, parent_address is the exact address with a pointer to the child address.
@ -150,8 +150,8 @@ def leakfind(
time_to_depth_increase = 0
# Run a bfs
# TODO look into performance gain from checking if an address is mapped before calling pwndbg.gdblib.memory.pvoid()
# TODO also check using pwndbg.gdblib.memory.read for possible performance boosts.
# TODO look into performance gain from checking if an address is mapped before calling pwndbg.aglib.memory.pvoid()
# TODO also check using pwndbg.aglib.memory.read for possible performance boosts.
while address_queue.qsize() > 0 and depth < max_depth:
if time_to_depth_increase == 0:
depth = depth + 1
@ -162,8 +162,8 @@ def leakfind(
cur_start_addr - negative_offset, cur_start_addr + max_offset, stride
):
try:
cur_addr &= pwndbg.gdblib.arch.ptrmask
result = int(pwndbg.gdblib.memory.pvoid(cur_addr))
cur_addr &= pwndbg.aglib.arch.ptrmask
result = int(pwndbg.aglib.memory.pvoid(cur_addr))
if result in visited_map or result in visited_set:
continue
visited_map[result] = (
@ -172,7 +172,7 @@ def leakfind(
) # map is of form child->(parent,parent_start)
address_queue.put(result)
visited_set.add(result)
except gdb.error:
except pwndbg.dbg_mod.Error:
# That means the memory was unmapped. Just skip it if we can't read it.
break
@ -181,7 +181,7 @@ def leakfind(
arrow_right = C.arrow(" %s " % pwndbg.config.chain_arrow_right)
for child in visited_map:
child_page = pwndbg.gdblib.vmmap.find(child)
child_page = pwndbg.aglib.vmmap.find(child)
if child_page is not None:
if page_name is not None and page_name not in child_page.objfile:
continue
@ -202,5 +202,5 @@ def leakfind(
for line in lines:
print(line)
if pwndbg.gdblib.qemu.is_qemu():
if pwndbg.aglib.qemu.is_qemu():
print("\n[QEMU target detected - leakfind result might not be accurate; see `help vmmap`]")

@ -2,7 +2,7 @@ from __future__ import annotations
import argparse
import pwndbg.gdblib.nearpc
import pwndbg.aglib.nearpc
from pwndbg.commands import CommandCategory
parser = argparse.ArgumentParser(description="Disassemble near a specified address.")
@ -36,7 +36,7 @@ def nearpc(pc=None, lines=None, emulate=False, use_cache=False, linear=True) ->
"""
print(
"\n".join(
pwndbg.gdblib.nearpc.nearpc(
pwndbg.aglib.nearpc.nearpc(
pc, lines, emulate, nearpc.repeat, use_cache=use_cache, linear=linear
)
)

@ -4,12 +4,12 @@ import argparse
from typing import List
from typing import Tuple
import pwndbg.aglib.arch
import pwndbg.aglib.memory
import pwndbg.aglib.vmmap
import pwndbg.color
import pwndbg.commands
import pwndbg.commands.telescope
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.vmmap
from pwndbg.commands import CommandCategory
ts = pwndbg.commands.telescope.telescope
@ -25,7 +25,7 @@ class AddrRange:
def get_addrrange_any_named() -> List[AddrRange]:
return [AddrRange(page.start, page.end) for page in pwndbg.gdblib.vmmap.get()]
return [AddrRange(page.start, page.end) for page in pwndbg.aglib.vmmap.get()]
def address_range_explicit(section: str) -> AddrRange:
@ -42,14 +42,14 @@ def address_range_explicit(section: str) -> AddrRange:
def address_range(section: str) -> List[AddrRange] | Tuple[int, int] | None:
if section in ("*", "any"):
return (0, pwndbg.gdblib.arch.ptrmask)
return (0, pwndbg.aglib.arch.ptrmask)
# User can use syntax: "begin:end" to specify explicit address range instead of named page.
# TODO: handle page names that contains ':'.
if ":" in section:
return [address_range_explicit(section)]
pages = list(filter(lambda page: section in page.objfile, pwndbg.gdblib.vmmap.get()))
pages = list(filter(lambda page: section in page.objfile, pwndbg.aglib.vmmap.get()))
if pages:
return [AddrRange(page.start, page.end) for page in pages]
@ -69,7 +69,7 @@ parser.add_argument("mapping_names", type=address_range, nargs="+", help="Mappin
def maybe_points_to_ranges(ptr: int, rs: List[AddrRange]):
try:
pointee = pwndbg.gdblib.memory.pvoid(ptr)
pointee = pwndbg.aglib.memory.pvoid(ptr)
except Exception:
return None

@ -7,11 +7,11 @@ from typing import Tuple
from pwnlib.asm import asm
from pwnlib.asm import disasm
import pwndbg.aglib.memory
import pwndbg.color.context
import pwndbg.color.memory
import pwndbg.color.syntax_highlight
import pwndbg.commands
import pwndbg.gdblib.memory
import pwndbg.lib.cache
from pwndbg.color import message
@ -30,11 +30,11 @@ parser.add_argument("-q", "--quiet", action="store_true", help="don't print anyt
def patch(address: int, ins: str, quiet: bool) -> None:
new_mem = asm(ins)
old_mem = pwndbg.gdblib.memory.read(address, len(new_mem))
old_mem = pwndbg.aglib.memory.read(address, len(new_mem))
patches[address] = (old_mem, new_mem)
pwndbg.gdblib.memory.write(address, new_mem)
pwndbg.aglib.memory.write(address, new_mem)
pwndbg.lib.cache.clear_caches()
@ -56,12 +56,12 @@ def patch_revert(address: int) -> None:
if address == -1:
for addr, (old, _new) in patches.items():
pwndbg.gdblib.memory.write(addr, old)
pwndbg.aglib.memory.write(addr, old)
print(message.notice("Reverted patch at %#x" % addr))
patches.clear()
elif address in patches:
old, _new = patches.pop(address)
pwndbg.gdblib.memory.write(address, old)
pwndbg.aglib.memory.write(address, old)
print(message.notice("Reverted patch at %#x" % address))
else:
print(message.error("Address %#x not found in patch list" % address))

@ -3,14 +3,15 @@ from __future__ import annotations
import argparse
import os
import gdb
import pwndbg.aglib.vmmap
import pwndbg.auxv
import pwndbg.commands
import pwndbg.gdblib.vmmap
from pwndbg.color import message
from pwndbg.commands import CommandCategory
if pwndbg.dbg.is_gdblib_available():
import gdb
def get_exe_name():
"""
@ -29,7 +30,7 @@ def get_exe_name():
# On the other hand, the vmmap, if taken from /proc/pid/maps will contain
# the absolute and real path of the binary (after symlinks).
# And so we have to read this path here.
real_path = pwndbg.gdblib.file.readlink(path)
real_path = pwndbg.aglib.file.readlink(path)
if real_path == "": # the `path` was not a symlink
real_path = path
@ -40,12 +41,12 @@ def get_exe_name():
# We want just 'a.out'
return os.path.normpath(real_path)
return pwndbg.gdblib.proc.exe
return pwndbg.aglib.proc.exe
def translate_addr(offset, module):
mod_filter = lambda page: module in page.objfile
pages = list(filter(mod_filter, pwndbg.gdblib.vmmap.get()))
pages = list(filter(mod_filter, pwndbg.aglib.vmmap.get()))
if not pages:
print(
@ -86,7 +87,7 @@ parser.add_argument(
def piebase(offset=None, module=None) -> None:
offset = int(offset)
if not module:
# Note: we do not use `pwndbg.gdblib.file.get_file(module)` here as it is not needed.
# Note: we do not use `pwndbg.aglib.file.get_file(module)` here as it is not needed.
# (as we do need the actual path that is in vmmap, not the file itself)
module = get_exe_name()
@ -98,30 +99,30 @@ def piebase(offset=None, module=None) -> None:
print(message.error("Could not calculate VA on current target."))
parser = argparse.ArgumentParser()
parser.description = "Break at RVA from PIE base."
parser.add_argument("offset", nargs="?", default=0, help="Offset to add.")
parser.add_argument(
"module",
type=str,
nargs="?",
default="",
help="Module to choose as base. Defaults to the target executable.",
)
@pwndbg.commands.ArgparsedCommand(parser, aliases=["brva"], category=CommandCategory.BREAKPOINT)
@pwndbg.commands.OnlyWhenRunning
def breakrva(offset=0, module=None) -> None:
offset = int(offset)
if not module:
# Note: we do not use `pwndbg.gdblib.file.get_file(module)` here as it is not needed.
# (as we do need the actual path that is in vmmap, not the file itself)
module = get_exe_name()
addr = translate_addr(offset, module)
if addr is not None:
spec = "*%#x" % (addr)
gdb.Breakpoint(spec)
else:
print(message.error("Could not determine rebased breakpoint address on current target"))
if pwndbg.dbg.is_gdblib_available():
parser = argparse.ArgumentParser()
parser.description = "Break at RVA from PIE base."
parser.add_argument("offset", nargs="?", default=0, help="Offset to add.")
parser.add_argument(
"module",
type=str,
nargs="?",
default="",
help="Module to choose as base. Defaults to the target executable.",
)
@pwndbg.commands.ArgparsedCommand(parser, aliases=["brva"], category=CommandCategory.BREAKPOINT)
@pwndbg.commands.OnlyWhenRunning
def breakrva(offset=0, module=None) -> None:
offset = int(offset)
if not module:
# Note: we do not use `pwndbg.aglib.file.get_file(module)` here as it is not needed.
# (as we do need the actual path that is in vmmap, not the file itself)
module = get_exe_name()
addr = translate_addr(offset, module)
if addr is not None:
spec = "*%#x" % (addr)
gdb.Breakpoint(spec)
else:
print(message.error("Could not determine rebased breakpoint address on current target"))

@ -4,25 +4,23 @@ import argparse
import math
import os
import gdb
import pwndbg.aglib.arch
import pwndbg.aglib.elf
import pwndbg.aglib.vmmap
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.elf
import pwndbg.gdblib.vmmap
from pwndbg.color import message
from pwndbg.commands import CommandCategory
def find_module(addr, max_distance):
mod_filter = lambda page: page.start <= addr < page.end
pages = list(filter(mod_filter, pwndbg.gdblib.vmmap.get()))
pages = list(filter(mod_filter, pwndbg.aglib.vmmap.get()))
if not pages:
if max_distance != 0:
mod_filter = lambda page: page.start - max_distance <= addr < page.end + max_distance
pages = list(filter(mod_filter, pwndbg.gdblib.vmmap.get()))
pages = list(filter(mod_filter, pwndbg.aglib.vmmap.get()))
if not pages:
return None
@ -87,8 +85,8 @@ def probeleak(
address=None, count=0x40, max_distance=0x0, point_to=None, max_ptrs=0, flags=None
) -> None:
address = int(address)
address &= pwndbg.gdblib.arch.ptrmask
ptrsize = pwndbg.gdblib.arch.ptrsize
address &= pwndbg.aglib.arch.ptrmask
ptrsize = pwndbg.aglib.arch.ptrsize
count = max(int(count), ptrsize)
off_zeros = int(math.ceil(math.log(count, 2) / 4))
if flags is not None:
@ -104,8 +102,8 @@ def probeleak(
count -= address
try:
data = pwndbg.gdblib.memory.read(address, count, partial=True)
except gdb.error as e:
data = pwndbg.aglib.memory.read(address, count, partial=True)
except pwndbg.dbg_mod.Error as e:
print(message.error(str(e)))
return
@ -120,7 +118,7 @@ def probeleak(
found = False
find_cnt = 0
for i in range(0, len(data) - ptrsize + 1):
p = pwndbg.gdblib.arch.unpack(data[i : i + ptrsize])
p = pwndbg.aglib.arch.unpack(data[i : i + ptrsize])
page = find_module(p, max_distance)
if page:
if point_to is not None and point_to not in page.objfile:
@ -155,7 +153,7 @@ def probeleak(
p_text = "0x%0*x" % (int(ptrsize * 2), p)
text = f"{offset_text}: {M.get(p, text=p_text)} = {M.get(p, text=right_text)}"
symbol = pwndbg.gdblib.symbol.get(p)
symbol = pwndbg.dbg.selected_inferior().symbol_name_at_address(p)
if symbol:
text += f" ({symbol})"
print(text)

@ -1,10 +1,10 @@
from __future__ import annotations
import pwndbg.aglib.arch
import pwndbg.aglib.regs
import pwndbg.aglib.vmmap
import pwndbg.chain
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.regs
import pwndbg.gdblib.vmmap
from pwndbg.commands import CommandCategory
@ -13,20 +13,20 @@ from pwndbg.commands import CommandCategory
)
@pwndbg.commands.OnlyWhenRunning
def retaddr() -> None:
addresses = pwndbg.gdblib.stack.callstack()
addresses = pwndbg.aglib.stack.callstack()
sp = pwndbg.gdblib.regs.sp
stack = pwndbg.gdblib.vmmap.find(sp)
sp = pwndbg.aglib.regs.sp
stack = pwndbg.aglib.vmmap.find(sp)
# Find all return addresses on the stack
start = stack.vaddr
stop = start + stack.memsz
while addresses and start < sp < stop:
value = pwndbg.gdblib.memory.u(sp)
value = pwndbg.aglib.memory.u(sp)
if value in addresses:
index = addresses.index(value)
del addresses[:index]
print(pwndbg.chain.format(sp))
sp += pwndbg.gdblib.arch.ptrsize
sp += pwndbg.aglib.arch.ptrsize

@ -7,20 +7,22 @@ import os
import struct
from typing import Set
import gdb
import pwnlib
import pwndbg
import pwndbg.aglib.arch
import pwndbg.aglib.disasm
import pwndbg.aglib.vmmap
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.enhance
import pwndbg.gdblib.arch
import pwndbg.gdblib.vmmap
import pwndbg.search
from pwndbg.color import message
from pwndbg.commands import CommandCategory
if pwndbg.dbg.is_gdblib_available():
import gdb
saved: Set[int] = set()
@ -33,7 +35,7 @@ def print_search_hit(address) -> None:
if not address:
return
vmmap = pwndbg.gdblib.vmmap.find(address)
vmmap = pwndbg.aglib.vmmap.find(address)
if vmmap:
region = os.path.basename(vmmap.objfile)
else:
@ -206,7 +208,7 @@ def search(
# Adjust pointer sizes to the local architecture
if type == "pointer":
type = {4: "dword", 8: "qword"}[pwndbg.gdblib.arch.ptrsize]
type = {4: "dword", 8: "qword"}[pwndbg.aglib.arch.ptrsize]
if save is None:
save = bool(pwndbg.config.auto_save_search)
@ -229,8 +231,8 @@ def search(
# Convert to an integer if needed, and pack to bytes
if type not in ("string", "bytes", "asm"):
value = pwndbg.commands.fix_int(value)
value &= pwndbg.gdblib.arch.ptrmask
fmt = {"little": "<", "big": ">"}[pwndbg.gdblib.arch.endian] + {
value &= pwndbg.aglib.arch.ptrmask
fmt = {"little": "<", "big": ">"}[pwndbg.aglib.arch.endian] + {
"byte": "B",
"short": "H",
"word": "H",
@ -254,7 +256,7 @@ def search(
value = pwnlib.asm.asm(value, arch=arch, bits=bits_for_arch)
# Find the mappings that we're looking for
mappings = pwndbg.gdblib.vmmap.get()
mappings = pwndbg.aglib.vmmap.get()
if mapping_name:
mappings = [m for m in mappings if mapping_name in m.objfile]
@ -276,7 +278,7 @@ def search(
i = 0
for addr in saved:
try:
val = pwndbg.gdblib.memory.read(addr, val_len)
val = pwndbg.aglib.memory.read(addr, val_len)
except Exception:
continue
if val == value:
@ -307,8 +309,13 @@ def search(
if save:
saved.add(address)
if asmbp:
# set breakpoint on the instruction
gdb.Breakpoint("*%#x" % address, temporary=False)
if pwndbg.dbg.is_gdblib_available():
# set breakpoint on the instruction
gdb.Breakpoint("*%#x" % address, temporary=False)
else:
print(
f"breakpoints are not supported outside of GDB yet, would be set at {address:#x}"
)
if not trunc_out or i < 20:
print_search_hit(address)

@ -8,13 +8,13 @@ from typing import Tuple
import pwnlib.rop.srop
import pwndbg.aglib.arch
import pwndbg.aglib.memory
import pwndbg.aglib.regs
import pwndbg.color.context as C
import pwndbg.color.memory as M
import pwndbg.color.message
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
from pwndbg.lib.regs import aarch64
from pwndbg.lib.regs import amd64
from pwndbg.lib.regs import arm
@ -67,12 +67,12 @@ parser.add_argument(
@pwndbg.commands.OnlyWhenRunning
@pwndbg.commands.OnlyWithArch(["x86-64", "i386", "aarch64", "arm"])
def sigreturn(address: int = None, display_all=False, print_address=False) -> None:
address = pwndbg.gdblib.regs.sp if address is None else address
address = pwndbg.aglib.regs.sp if address is None else address
ptr_size = pwndbg.gdblib.arch.ptrsize
ptr_size = pwndbg.aglib.arch.ptrsize
frame_layout = SIGRETURN_FRAME_LAYOUTS[pwndbg.gdblib.arch.name]
core_registers = SIGRETURN_CORE_REGISTER[pwndbg.gdblib.arch.name]
frame_layout = SIGRETURN_FRAME_LAYOUTS[pwndbg.aglib.arch.name]
core_registers = SIGRETURN_CORE_REGISTER[pwndbg.aglib.arch.name]
# Offset to the stack pointer where the frame values really begins. Start reading memory there.
# Can be negative, 0, or positive
@ -80,22 +80,22 @@ def sigreturn(address: int = None, display_all=False, print_address=False) -> No
read_size = frame_layout[-1][0] - frame_start_offset + ptr_size
mem = pwndbg.gdblib.memory.read(address + frame_start_offset, read_size)
mem = pwndbg.aglib.memory.read(address + frame_start_offset, read_size)
for stack_offset, reg in frame_layout:
# Subtract the offset of start of frame, to get the correct offset into "mem"
mem_offset = stack_offset - frame_start_offset
regname = C.register(reg.ljust(4).upper())
value = pwndbg.gdblib.arch.unpack(mem[mem_offset : mem_offset + ptr_size])
value = pwndbg.aglib.arch.unpack(mem[mem_offset : mem_offset + ptr_size])
if reg in core_registers:
desc = pwndbg.chain.format(value)
print_value(f"{regname} {desc}", address + stack_offset, print_address)
elif reg in pwndbg.gdblib.regs.flags: # eflags or cpsr
reg_flags = pwndbg.gdblib.regs.flags[reg]
elif reg in pwndbg.aglib.regs.flags: # eflags or cpsr
reg_flags = pwndbg.aglib.regs.flags[reg]
desc = C.format_flags(value, reg_flags)
print_value(f"{regname} {desc}", address + stack_offset, print_address)

@ -2,7 +2,6 @@ from __future__ import annotations
import argparse
import gdb
from pwnlib.util.cyclic import cyclic
import pwndbg.color.message as M
@ -34,8 +33,9 @@ parser.add_argument(
@pwndbg.commands.ArgparsedCommand(parser)
@pwndbg.commands.OnlyWhenRunning
def spray(addr, length, value, only_funcptrs) -> None:
addr = int(addr)
if length == 0:
page = pwndbg.gdblib.vmmap.find(addr)
page = pwndbg.aglib.vmmap.find(addr)
if page is None:
print(
M.error(
@ -59,22 +59,22 @@ def spray(addr, length, value, only_funcptrs) -> None:
if length % value_length != 0:
value_bytes += value_bytes[: (length % value_length)]
else:
value_bytes = cyclic(length, n=pwndbg.gdblib.arch.ptrsize)
value_bytes = cyclic(length, n=pwndbg.aglib.arch.ptrsize)
try:
if only_funcptrs:
mem = pwndbg.gdblib.memory.read(addr, length)
mem = pwndbg.aglib.memory.read(addr, length)
addresses_written = 0
ptrsize = pwndbg.gdblib.arch.ptrsize
ptrsize = pwndbg.aglib.arch.ptrsize
for i in range(0, len(mem) - (length % ptrsize), ptrsize):
ptr_candidate = pwndbg.gdblib.arch.unpack(mem[i : i + ptrsize])
page = pwndbg.gdblib.vmmap.find(ptr_candidate)
ptr_candidate = pwndbg.aglib.arch.unpack(mem[i : i + ptrsize])
page = pwndbg.aglib.vmmap.find(ptr_candidate)
if page is not None and page.execute:
pwndbg.gdblib.memory.write(addr + i, value_bytes[i : i + ptrsize])
pwndbg.aglib.memory.write(addr + i, value_bytes[i : i + ptrsize])
addresses_written += 1
print(M.notice(f"Overwritten {addresses_written} function pointers"))
else:
pwndbg.gdblib.memory.write(addr, value_bytes)
except gdb.MemoryError as e:
pwndbg.aglib.memory.write(addr, value_bytes)
except pwndbg.dbg_mod.Error as e:
print(M.error(e))

@ -14,13 +14,14 @@ from typing import Dict
from typing import List
import pwndbg
import pwndbg.aglib.arch
import pwndbg.aglib.memory
import pwndbg.aglib.regs
import pwndbg.aglib.typeinfo
import pwndbg.aglib.vmmap
import pwndbg.chain
import pwndbg.color.telescope as T
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.gdblib.typeinfo
from pwndbg.color import theme
from pwndbg.commands import CommandCategory
@ -103,28 +104,28 @@ def telescope(
Recursively dereferences pointers starting at the specified address
($sp by default)
"""
ptrsize = pwndbg.gdblib.typeinfo.ptrsize
ptrsize = pwndbg.aglib.typeinfo.ptrsize
if telescope.repeat:
address = telescope.last_address + ptrsize
telescope.offset += 1
else:
telescope.offset = 0
address = address if address else pwndbg.gdblib.regs.sp
address = address if address else pwndbg.aglib.regs.sp
if address is None:
print("Cannot display stack frame because stack pointer is unavailable")
return
address = int(address) & pwndbg.gdblib.arch.ptrmask
address = int(address) & pwndbg.aglib.arch.ptrmask
input_address = address
count = max(int(count), 1) & pwndbg.gdblib.arch.ptrmask
count = max(int(count), 1) & pwndbg.aglib.arch.ptrmask
delimiter = T.delimiter(offset_delimiter)
separator = T.separator(offset_separator)
# Allow invocation of "telescope 20" to dump 20 bytes at the stack pointer
if address < pwndbg.gdblib.memory.MMAP_MIN_ADDR and not pwndbg.gdblib.memory.peek(address):
if address < pwndbg.aglib.memory.MMAP_MIN_ADDR and not pwndbg.aglib.memory.peek(address):
count = address
address = pwndbg.gdblib.regs.sp
address = pwndbg.aglib.regs.sp
# Allow invocation of telescope -r to dump previous addresses
if reverse:
@ -132,13 +133,13 @@ def telescope(
# Allow invocation of telescope -f (--frame) to dump all addresses in a frame
if frame:
sp = pwndbg.gdblib.regs.sp
bp = pwndbg.gdblib.regs[pwndbg.gdblib.regs.frame]
sp = pwndbg.aglib.regs.sp
bp = pwndbg.aglib.regs[pwndbg.aglib.regs.frame]
if sp > bp:
print("Cannot display stack frame because base pointer is below stack pointer")
return
for page in pwndbg.gdblib.vmmap.get():
for page in pwndbg.aglib.vmmap.get():
if sp in page and bp not in page:
print(
"Cannot display stack frame because base pointer is not on the same page with stack pointer"
@ -157,8 +158,8 @@ def telescope(
# Map of address to register string
reg_values: DefaultDict[int, List[str]] = collections.defaultdict(list)
for reg in pwndbg.gdblib.regs.common:
reg_values[pwndbg.gdblib.regs[reg]].append(reg)
for reg in pwndbg.aglib.regs.common:
reg_values[pwndbg.aglib.regs[reg]].append(reg)
if not inverse:
start = address
@ -175,7 +176,7 @@ def telescope(
values = list(reg_values[i])
# Find all regs that point to somewhere in the current ptrsize step
for width in range(1, pwndbg.gdblib.arch.ptrsize):
for width in range(1, pwndbg.aglib.arch.ptrsize):
values.extend("%s-%i" % (r, width) for r in reg_values[i + width])
regs[i] = " ".join(values)
@ -216,12 +217,12 @@ def telescope(
collapse_buffer.clear()
bp = None
if print_framepointer_offset and pwndbg.gdblib.regs.frame is not None:
if print_framepointer_offset and pwndbg.aglib.regs.frame is not None:
# regs.frame can be None on aarch64
bp = pwndbg.gdblib.regs[pwndbg.gdblib.regs.frame]
bp = pwndbg.aglib.regs[pwndbg.aglib.regs.frame]
for i, addr in enumerate(range(start, stop, step)):
if not pwndbg.gdblib.memory.peek(addr):
if not pwndbg.aglib.memory.peek(addr):
collapse_repeating_values()
result.append("<Could not read memory at %#x>" % addr)
break
@ -248,7 +249,7 @@ def telescope(
# Buffer repeating values.
if skip_repeating_values:
value = pwndbg.gdblib.memory.pvoid(addr)
value = pwndbg.aglib.memory.pvoid(addr)
if last == value and addr != input_address:
collapse_buffer.append(line)
continue
@ -311,10 +312,10 @@ parser.add_argument(
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.STACK)
@pwndbg.commands.OnlyWhenRunning
def stack(count, offset, frame, inverse) -> None:
ptrsize = pwndbg.gdblib.typeinfo.ptrsize
ptrsize = pwndbg.aglib.typeinfo.ptrsize
telescope.repeat = stack.repeat
telescope(
address=pwndbg.gdblib.regs.sp + offset * ptrsize, count=count, frame=frame, inverse=inverse
address=pwndbg.aglib.regs.sp + offset * ptrsize, count=count, frame=frame, inverse=inverse
)
@ -334,9 +335,9 @@ parser.add_argument(
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.STACK)
@pwndbg.commands.OnlyWhenRunning
def stackf(count, offset) -> None:
ptrsize = pwndbg.gdblib.typeinfo.ptrsize
ptrsize = pwndbg.aglib.typeinfo.ptrsize
telescope.repeat = stack.repeat
telescope(address=pwndbg.gdblib.regs.sp + offset * ptrsize, count=count, frame=True)
telescope(address=pwndbg.aglib.regs.sp + offset * ptrsize, count=count, frame=True)
telescope.last_address = 0

@ -25,11 +25,11 @@ def valist(addr: int, count: int) -> None:
# } va_list[1];
# ```
gp_offset = pwndbg.gdblib.memory.u32(addr)
gp_offset = pwndbg.aglib.memory.u32(addr)
gp_index = gp_offset / 8
overflow_arg_area = pwndbg.gdblib.memory.u64(addr + 8)
reg_save_area = pwndbg.gdblib.memory.u64(addr + 16)
overflow_arg_area = pwndbg.aglib.memory.u64(addr + 8)
reg_save_area = pwndbg.aglib.memory.u64(addr + 16)
indent = " " * len("gp_offset => ")
print(f"{C.blue('reg_save_area')}")

@ -7,22 +7,23 @@ from __future__ import annotations
import argparse
from typing import Tuple
import gdb
from elftools.elf.constants import SH_FLAGS
from elftools.elf.elffile import ELFFile
import pwndbg.aglib.arch
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.elf
import pwndbg.gdblib.vmmap
from pwndbg.color import cyan
from pwndbg.color import green
from pwndbg.color import red
from pwndbg.commands import CommandCategory
from pwndbg.gdblib import gdb_version
from pwndbg.lib.memory import Page
integer_types = (int, gdb.Value)
if pwndbg.dbg.is_gdblib_available():
import pwndbg.gdblib.elf
import pwndbg.gdblib.vmmap
integer_types = (int, pwndbg.dbg_mod.Value)
def pages_filter(gdbval_or_str):
@ -45,7 +46,7 @@ def print_vmmap_table_header() -> None:
Prints the table header for the vmmap command.
"""
print(
f"{'Start':>{2 + 2 * pwndbg.gdblib.arch.ptrsize}} {'End':>{2 + 2 * pwndbg.gdblib.arch.ptrsize}} {'Perm'} {'Size':>8} {'Offset':>6} {'File'}"
f"{'Start':>{2 + 2 * pwndbg.aglib.arch.ptrsize}} {'End':>{2 + 2 * pwndbg.aglib.arch.ptrsize}} {'Perm'} {'Size':>8} {'Offset':>6} {'File'}"
)
@ -54,12 +55,12 @@ def print_vmmap_gaps_table_header() -> None:
Prints the table header for the vmmap --gaps command.
"""
header = (
f"{'Start':>{2 + 2 * pwndbg.gdblib.arch.ptrsize}} "
f"{'End':>{2 + 2 * pwndbg.gdblib.arch.ptrsize}} "
f"{'Start':>{2 + 2 * pwndbg.aglib.arch.ptrsize}} "
f"{'End':>{2 + 2 * pwndbg.aglib.arch.ptrsize}} "
f"{'Perm':>4} "
f"{'Size':>8} "
f"{'Note':>9} "
f"{'Accumulated Size':>{2 + 2 * pwndbg.gdblib.arch.ptrsize}}"
f"{'Accumulated Size':>{2 + 2 * pwndbg.aglib.arch.ptrsize}}"
)
print(header)
@ -87,7 +88,7 @@ def print_map(page: Page) -> None:
def print_adjacent_map(map_start: Page, map_end: Page) -> None:
print(
green(
f"{gap_text(map_end)} {'ADJACENT':>9} {hex(map_end.end - map_start.start):>{2 + 2 * pwndbg.gdblib.arch.ptrsize}}"
f"{gap_text(map_end)} {'ADJACENT':>9} {hex(map_end.end - map_start.start):>{2 + 2 * pwndbg.aglib.arch.ptrsize}}"
)
)
@ -100,7 +101,7 @@ def print_gap(current: Page, last_map: Page):
print(
red(
" - " * int(51 / 3)
+ f" {'GAP':>9} {hex(current.start - last_map.end):>{2 + 2 * pwndbg.gdblib.arch.ptrsize}}"
+ f" {'GAP':>9} {hex(current.start - last_map.end):>{2 + 2 * pwndbg.aglib.arch.ptrsize}}"
)
)
@ -200,7 +201,8 @@ def vmmap(
lines_before = min(lookaround_lines_limit, lines_before)
# All displayed pages, including lines after and lines before
total_pages = pwndbg.gdblib.vmmap.get()
vmmap = pwndbg.dbg.selected_inferior().vmmap()
total_pages = vmmap.ranges()
# Filtered memory pages, indicated by a backtrace arrow in results
filtered_pages = []
@ -240,7 +242,7 @@ def vmmap(
return
if gaps:
print_vmmap_gaps(total_pages)
print_vmmap_gaps(tuple(total_pages))
return
print(M.legend())
@ -263,126 +265,127 @@ def vmmap(
print(M.get(page.vaddr, text=display_text, prefix=backtrace_prefix))
if pwndbg.gdblib.qemu.is_qemu() and not pwndbg.gdblib.qemu.exec_file_supported():
if vmmap.is_qemu():
print("\n[QEMU target detected - vmmap result might not be accurate; see `help vmmap`]")
# Only GDB versions >=12 report permission info in info proc mappings. On older versions, we fallback on "rwx".
# See https://github.com/bminor/binutils-gdb/commit/29ef4c0699e1b46d41ade00ae07a54f979ea21cc
if pwndbg.gdblib.qemu.is_qemu_usermode() and gdb_version[0] < 12:
if not vmmap.has_reliable_perms():
print(
"\n[GDB <12.1 detected - vmmap cannot fetch permission information, defaulting to rwx]"
)
parser = argparse.ArgumentParser(description="Add virtual memory map page.")
parser.add_argument("start", help="Starting virtual address")
parser.add_argument("size", help="Size of the address space, in bytes")
parser.add_argument(
"flags", nargs="?", type=str, default="", help="Flags set by the ELF file, see PF_X, PF_R, PF_W"
)
parser.add_argument(
"offset",
nargs="?",
default=0,
help="Offset into the original ELF file that the data is loaded from",
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def vmmap_add(start, size, flags, offset) -> None:
page_flags = {
"r": pwndbg.gdblib.elf.PF_R,
"w": pwndbg.gdblib.elf.PF_W,
"x": pwndbg.gdblib.elf.PF_X,
}
perm = 0
for flag in flags:
flag_val = page_flags.get(flag, None)
if flag_val is None:
print('Invalid page flag "%s"', flag)
return
perm |= flag_val
page = pwndbg.lib.memory.Page(start, size, perm, offset)
pwndbg.gdblib.vmmap.add_custom_page(page)
print("%r added" % page)
@pwndbg.commands.ArgparsedCommand(
"Clear the vmmap cache.", category=CommandCategory.MEMORY
) # TODO is this accurate?
@pwndbg.commands.OnlyWhenRunning
def vmmap_clear() -> None:
pwndbg.gdblib.vmmap.clear_custom_page()
parser = argparse.ArgumentParser(description="Load virtual memory map pages from ELF file.")
parser.add_argument(
"filename", nargs="?", type=str, help="ELF filename, by default uses current loaded filename."
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def vmmap_load(filename) -> None:
if filename is None:
filename = pwndbg.gdblib.file.get_proc_exe_file()
print(f'Load "{filename}" ...')
# TODO: Add an argument to let use to choose loading the page information from sections or segments
# Use section information to recover the segment information.
# The entry point of bare metal environment is often at the first segment.
# For example, assume the entry point is at 0x8000.
# In most of case, link will create a segment and starts from 0x0.
# This cause all values less than 0x8000 be considered as a valid pointer.
pages = []
with open(filename, "rb") as f:
elffile = ELFFile(f)
for section in elffile.iter_sections():
vaddr = section["sh_addr"]
memsz = section["sh_size"]
sh_flags = section["sh_flags"]
offset = section["sh_offset"]
# Don't add the sections that aren't mapped into memory
if not sh_flags & SH_FLAGS.SHF_ALLOC:
continue
# Guess the segment flags from section flags
flags = pwndbg.gdblib.elf.PF_R
if sh_flags & SH_FLAGS.SHF_WRITE:
flags |= pwndbg.gdblib.elf.PF_W
if sh_flags & SH_FLAGS.SHF_EXECINSTR:
flags |= pwndbg.gdblib.elf.PF_X
if pwndbg.dbg.is_gdblib_available():
parser = argparse.ArgumentParser(description="Add virtual memory map page.")
parser.add_argument("start", help="Starting virtual address")
parser.add_argument("size", help="Size of the address space, in bytes")
parser.add_argument(
"flags",
nargs="?",
type=str,
default="",
help="Flags set by the ELF file, see PF_X, PF_R, PF_W",
)
parser.add_argument(
"offset",
nargs="?",
default=0,
help="Offset into the original ELF file that the data is loaded from",
)
page = pwndbg.lib.memory.Page(vaddr, memsz, flags, offset, filename)
pages.append(page)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def vmmap_add(start, size, flags, offset) -> None:
page_flags = {
"r": pwndbg.gdblib.elf.PF_R,
"w": pwndbg.gdblib.elf.PF_W,
"x": pwndbg.gdblib.elf.PF_X,
}
perm = 0
for flag in flags:
flag_val = page_flags.get(flag, None)
if flag_val is None:
print('Invalid page flag "%s"', flag)
return
perm |= flag_val
page = pwndbg.lib.memory.Page(start, size, perm, offset)
for page in pages:
pwndbg.gdblib.vmmap.add_custom_page(page)
print("%r added" % page)
print("%r added" % page)
parser = argparse.ArgumentParser(description="Explore a page, trying to guess permissions.")
parser.add_argument(
"address", type=pwndbg.commands.sloppy_gdb_parse, help="Address of the page to explore"
)
parser = argparse.ArgumentParser(description="Explore a page, trying to guess permissions.")
parser.add_argument(
"address", type=pwndbg.commands.sloppy_gdb_parse, help="Address of the page to explore"
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def vmmap_explore(address: int) -> None:
if not isinstance(address, int):
print("Address is not a valid integer.")
return
page = pwndbg.gdblib.vmmap.explore(address)
if page is None:
print("Exploration failed. Maybe the address isn't readable?")
return
print_vmmap_table_header()
print(page)
@pwndbg.commands.ArgparsedCommand(
"Clear the vmmap cache.", category=CommandCategory.MEMORY
) # TODO is this accurate?
@pwndbg.commands.OnlyWhenRunning
def vmmap_clear() -> None:
pwndbg.gdblib.vmmap.clear_custom_page()
parser = argparse.ArgumentParser(description="Load virtual memory map pages from ELF file.")
parser.add_argument(
"filename",
nargs="?",
type=str,
help="ELF filename, by default uses current loaded filename.",
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def vmmap_explore(address: int) -> None:
if not isinstance(address, int):
print("Address is not a valid integer.")
return
page = pwndbg.gdblib.vmmap.explore(address)
if page is None:
print("Exploration failed. Maybe the address isn't readable?")
return
print_vmmap_table_header()
print(page)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.MEMORY)
@pwndbg.commands.OnlyWhenRunning
def vmmap_load(filename) -> None:
if filename is None:
filename = pwndbg.gdblib.file.get_proc_exe_file()
print(f'Load "{filename}" ...')
# TODO: Add an argument to let use to choose loading the page information from sections or segments
# Use section information to recover the segment information.
# The entry point of bare metal environment is often at the first segment.
# For example, assume the entry point is at 0x8000.
# In most of case, link will create a segment and starts from 0x0.
# This cause all values less than 0x8000 be considered as a valid pointer.
pages = []
with open(filename, "rb") as f:
elffile = ELFFile(f)
for section in elffile.iter_sections():
vaddr = section["sh_addr"]
memsz = section["sh_size"]
sh_flags = section["sh_flags"]
offset = section["sh_offset"]
# Don't add the sections that aren't mapped into memory
if not sh_flags & SH_FLAGS.SHF_ALLOC:
continue
# Guess the segment flags from section flags
flags = pwndbg.gdblib.elf.PF_R
if sh_flags & SH_FLAGS.SHF_WRITE:
flags |= pwndbg.gdblib.elf.PF_W
if sh_flags & SH_FLAGS.SHF_EXECINSTR:
flags |= pwndbg.gdblib.elf.PF_X
page = pwndbg.lib.memory.Page(vaddr, memsz, flags, offset, filename)
pages.append(page)
for page in pages:
pwndbg.gdblib.vmmap.add_custom_page(page)
print("%r added" % page)

@ -8,17 +8,28 @@ import argparse
import codecs
from itertools import chain
import gdb
import pwndbg.aglib.arch
import pwndbg.aglib.memory
import pwndbg.aglib.strings
import pwndbg.aglib.typeinfo
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.strings
import pwndbg.gdblib.symbol
import pwndbg.gdblib.typeinfo
import pwndbg.hexdump
from pwndbg.commands import CommandCategory
if pwndbg.dbg.is_gdblib_available():
import gdb
def enhex(size, value):
value = value & ((1 << 8 * size) - 1)
x = "%x" % abs(value)
x = x.rjust(size * 2, "0")
return x
# `pwndbg.hexdump` imports `enhex` from this module, so we have to import it
# after it's been defined in order to avoid circular import errors.
import pwndbg.hexdump
parser = argparse.ArgumentParser(description="Starting at the specified address, dump N bytes.")
parser.add_argument(
"address", type=pwndbg.commands.HexOrAddressExpr, help="The address to dump from."
@ -149,13 +160,6 @@ def dX(size, address, count, to_string=False, repeat=False):
return lines
def enhex(size, value):
value = value & ((1 << 8 * size) - 1)
x = "%x" % abs(value)
x = x.rjust(size * 2, "0")
return x
parser = argparse.ArgumentParser(description="Write hex bytes at the specified address.")
parser.add_argument(
"address", type=pwndbg.commands.HexOrAddressExpr, help="The address to write to."
@ -286,13 +290,13 @@ def eX(size, address, data, hex=True) -> None:
else:
data = string
if pwndbg.gdblib.arch.endian == "little":
if pwndbg.aglib.arch.endian == "little":
data = data[::-1]
try:
pwndbg.gdblib.memory.write(address + (i * size), data)
pwndbg.aglib.memory.write(address + (i * size), data)
writes += 1
except gdb.error:
except pwndbg.dbg_mod.Error:
print("Cannot access memory at address %#x" % address)
if writes > 0:
print("(Made %d writes to memory; skipping further writes)" % writes)
@ -322,7 +326,7 @@ da_parser.add_argument("max", type=int, nargs="?", default=256, help="Maximum st
@pwndbg.commands.ArgparsedCommand(da_parser, category=CommandCategory.WINDBG)
@pwndbg.commands.OnlyWhenRunning
def da(address, max) -> None:
print("%x" % address, repr(pwndbg.gdblib.strings.get(address, max)))
print("%x" % address, repr(pwndbg.aglib.strings.get(address, max)))
ds_parser = argparse.ArgumentParser(description="Dump a string at the specified address.")
@ -340,7 +344,7 @@ def ds(address, max) -> None:
print("Max str len of %d too low, changing to 256" % max)
max = 256
string = pwndbg.gdblib.strings.get(address, max, maxread=4096)
string = pwndbg.aglib.strings.get(address, max, maxread=4096)
if string:
print(f"{address:x} {string!r}")
else:
@ -350,88 +354,91 @@ def ds(address, max) -> None:
print("Perhaps try: db <address> <count> or hexdump <address>")
@pwndbg.commands.ArgparsedCommand("List breakpoints.", category=CommandCategory.WINDBG)
def bl() -> None:
"""
List breakpoints
"""
gdb.execute("info breakpoints")
parser = argparse.ArgumentParser(description="Disable the breakpoint with the specified index.")
parser.add_argument(
"which", nargs="?", type=str, default="*", help="Index of the breakpoint to disable."
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def bd(which="*") -> None:
"""
Disable the breakpoint with the specified index.
"""
if which == "*":
gdb.execute("disable breakpoints")
else:
gdb.execute(f"disable breakpoints {which}")
parser = argparse.ArgumentParser(description="Enable the breakpoint with the specified index.")
parser.add_argument(
"which", nargs="?", type=str, default="*", help="Index of the breakpoint to enable."
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def be(which="*") -> None:
"""
Enable the breakpoint with the specified index.
"""
if which == "*":
gdb.execute("enable breakpoints")
else:
gdb.execute(f"enable breakpoints {which}")
parser = argparse.ArgumentParser(description="Clear the breakpoint with the specified index.")
parser.add_argument(
"which", nargs="?", type=str, default="*", help="Index of the breakpoint to clear."
)
if pwndbg.dbg.is_gdblib_available():
@pwndbg.commands.ArgparsedCommand("List breakpoints.", category=CommandCategory.WINDBG)
def bl() -> None:
"""
List breakpoints
"""
gdb.execute("info breakpoints")
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def bc(which="*") -> None:
"""
Clear the breakpoint with the specified index.
"""
if which == "*":
gdb.execute("delete breakpoints")
else:
gdb.execute(f"delete breakpoints {which}")
parser = argparse.ArgumentParser(description="Disable the breakpoint with the specified index.")
parser.add_argument(
"which", nargs="?", type=str, default="*", help="Index of the breakpoint to disable."
)
parser = argparse.ArgumentParser(description="Set a breakpoint at the specified address.")
parser.add_argument("where", type=int, help="The address to break at.")
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def bd(which="*") -> None:
"""
Disable the breakpoint with the specified index.
"""
if which == "*":
gdb.execute("disable breakpoints")
else:
gdb.execute(f"disable breakpoints {which}")
parser = argparse.ArgumentParser(description="Enable the breakpoint with the specified index.")
parser.add_argument(
"which", nargs="?", type=str, default="*", help="Index of the breakpoint to enable."
)
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def bp(where) -> None:
"""
Set a breakpoint at the specified address.
"""
result = pwndbg.commands.fix(where)
if result is not None:
gdb.execute("break *%#x" % int(result))
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def be(which="*") -> None:
"""
Enable the breakpoint with the specified index.
"""
if which == "*":
gdb.execute("enable breakpoints")
else:
gdb.execute(f"enable breakpoints {which}")
parser = argparse.ArgumentParser(description="Clear the breakpoint with the specified index.")
parser.add_argument(
"which", nargs="?", type=str, default="*", help="Index of the breakpoint to clear."
)
@pwndbg.commands.ArgparsedCommand(
"Print a backtrace (alias 'bt').", category=CommandCategory.WINDBG
)
@pwndbg.commands.OnlyWhenRunning
def k() -> None:
"""
Print a backtrace (alias 'bt')
"""
gdb.execute("bt")
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def bc(which="*") -> None:
"""
Clear the breakpoint with the specified index.
"""
if which == "*":
gdb.execute("delete breakpoints")
else:
gdb.execute(f"delete breakpoints {which}")
parser = argparse.ArgumentParser(description="Set a breakpoint at the specified address.")
parser.add_argument("where", type=int, help="The address to break at.")
@pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.WINDBG)
def bp(where) -> None:
"""
Set a breakpoint at the specified address.
"""
result = pwndbg.commands.fix(where)
if result is not None:
gdb.execute("break *%#x" % int(result))
@pwndbg.commands.ArgparsedCommand(
"Print a backtrace (alias 'bt').", category=CommandCategory.WINDBG
)
@pwndbg.commands.OnlyWhenRunning
def k() -> None:
"""
Print a backtrace (alias 'bt')
"""
gdb.execute("bt")
@pwndbg.commands.ArgparsedCommand(
"Windbg compatibility alias for 'continue' command.", category=CommandCategory.WINDBG
)
@pwndbg.commands.OnlyWhenRunning
def go() -> None:
"""
Windbg compatibility alias for 'continue' command.
"""
gdb.execute("continue")
parser = argparse.ArgumentParser(description="List the symbols nearest to the provided value.")
@ -447,9 +454,9 @@ def ln(value: int = None) -> None:
List the symbols nearest to the provided value.
"""
if value is None:
value = pwndbg.gdblib.regs.pc
value = pwndbg.aglib.regs.pc
x = pwndbg.gdblib.symbol.get(value)
x = pwndbg.dbg.selected_inferior().symbol_name_at_address(value)
if x:
result = f"({value:#x}) {x}"
print(result)
@ -467,17 +474,6 @@ def peb() -> None:
print("This isn't Windows!")
@pwndbg.commands.ArgparsedCommand(
"Windbg compatibility alias for 'continue' command.", category=CommandCategory.WINDBG
)
@pwndbg.commands.OnlyWhenRunning
def go() -> None:
"""
Windbg compatibility alias for 'continue' command.
"""
gdb.execute("continue")
@pwndbg.commands.ArgparsedCommand(
"Windbg compatibility alias for 'nextcall' command.", category=CommandCategory.WINDBG
)

@ -4,13 +4,13 @@ import argparse
import os
import pwndbg
import pwndbg.aglib.arch
import pwndbg.aglib.memory
import pwndbg.aglib.regs
import pwndbg.aglib.stack
import pwndbg.aglib.vmmap
import pwndbg.color.memory as M
import pwndbg.commands
import pwndbg.gdblib.arch
import pwndbg.gdblib.memory
import pwndbg.gdblib.regs
import pwndbg.gdblib.stack
import pwndbg.gdblib.vmmap
import pwndbg.wrappers
from pwndbg.commands import CommandCategory
@ -30,9 +30,9 @@ def xinfo_stack(page, addr) -> None:
# If it's a stack address, print offsets to top and bottom of stack, as
# well as offsets to current stack and base pointer (if used by debuggee)
sp = pwndbg.gdblib.regs.sp
frame = pwndbg.gdblib.regs[pwndbg.gdblib.regs.frame]
frame_mapping = pwndbg.gdblib.vmmap.find(frame)
sp = pwndbg.aglib.regs.sp
frame = pwndbg.aglib.regs[pwndbg.aglib.regs.frame]
frame_mapping = pwndbg.aglib.vmmap.find(frame)
print_line("Stack Top", addr, page.vaddr, addr - page.vaddr, "+")
print_line("Stack End", addr, page.end, page.end - addr, "-")
@ -46,7 +46,7 @@ def xinfo_stack(page, addr) -> None:
if canary_value is not None:
all_canaries = list(
pwndbg.search.search(
pwndbg.gdblib.arch.pack(canary_value), mappings=pwndbg.gdblib.stack.get().values()
pwndbg.aglib.arch.pack(canary_value), mappings=pwndbg.aglib.stack.get().values()
)
)
follow_canaries = sorted(filter(lambda a: a > addr, all_canaries))
@ -65,7 +65,7 @@ def xinfo_mmap_file(page, addr) -> None:
if not os.path.exists(file_name):
return None
objpages = filter(lambda p: p.objfile == file_name, pwndbg.gdblib.vmmap.get())
objpages = filter(lambda p: p.objfile == file_name, pwndbg.aglib.vmmap.get())
first = sorted(objpages, key=lambda p: p.vaddr)[0]
# print offset from ELF base load address
@ -75,7 +75,7 @@ def xinfo_mmap_file(page, addr) -> None:
# find possible LOAD segments that designate memory and file backings
containing_loads = [
seg
for seg in pwndbg.gdblib.elf.get_containing_segments(file_name, first.vaddr, addr)
for seg in pwndbg.aglib.elf.get_containing_segments(file_name, first.vaddr, addr)
if seg["p_type"] == "PT_LOAD"
]
@ -93,7 +93,7 @@ def xinfo_mmap_file(page, addr) -> None:
else:
print(f"{'File (Disk)'.rjust(20)} {M.get(addr)} = [not file backed]")
containing_sections = pwndbg.gdblib.elf.get_containing_sections(file_name, first.vaddr, addr)
containing_sections = pwndbg.aglib.elf.get_containing_sections(file_name, first.vaddr, addr)
if len(containing_sections) > 0:
print("\n Containing ELF sections:")
for sec in containing_sections:
@ -109,12 +109,12 @@ def xinfo_default(page, addr) -> None:
@pwndbg.commands.OnlyWhenRunning
def xinfo(address=None) -> None:
address = address.cast(
pwndbg.gdblib.typeinfo.pvoid
pwndbg.aglib.typeinfo.pvoid
) # Fixes issues with function ptrs (xinfo malloc)
addr = int(address)
addr &= pwndbg.gdblib.arch.ptrmask
addr &= pwndbg.aglib.arch.ptrmask
page = pwndbg.gdblib.vmmap.find(addr)
page = pwndbg.aglib.vmmap.find(addr)
if page is None:
print(f"\n Virtual address {addr:#x} is not mapped.")

@ -2,10 +2,9 @@ from __future__ import annotations
import argparse
import gdb
import pwndbg
import pwndbg.aglib.memory
import pwndbg.commands
import pwndbg.gdblib.memory
from pwndbg.commands import CommandCategory
@ -13,7 +12,7 @@ def xor_memory(address, key, count):
"""
Helper function for xorring memory in gdb
"""
mem = pwndbg.gdblib.memory.read(address, count, partial=True)
mem = pwndbg.aglib.memory.read(address, count, partial=True)
for index, byte in enumerate(mem):
key_index = index % len(key)
@ -35,8 +34,8 @@ parser.add_argument("count", type=int, help="The number of bytes to xor.")
def xor(address, key, count) -> None:
try:
xorred_memory = xor_memory(address, key, count)
pwndbg.gdblib.memory.write(address, xorred_memory)
except gdb.error as e:
pwndbg.aglib.memory.write(address, xorred_memory)
except pwndbg.dbg_mod.Error as e:
print(e)

@ -82,8 +82,7 @@ def prompt_hook():
global should_show_context
if should_show_context:
# TODO: Uncomment this once the LLDB command port PR for `context` is merged
# pwndbg.commands.context.context()
pwndbg.commands.context.context()
should_show_context = False

Loading…
Cancel
Save