mirror of https://github.com/pwndbg/pwndbg.git
wip
parent
be8fdab940
commit
ca801c0d6d
@ -1,2 +1,67 @@
|
||||
import traceback
|
||||
import gdb
|
||||
|
||||
class Command(gdb.Command):
|
||||
import gef.regs
|
||||
import gef.memory
|
||||
import gef.hexdump
|
||||
import gef.color
|
||||
import gef.chain
|
||||
import gef.enhance
|
||||
import gef.symbol
|
||||
import gef.ui
|
||||
import gef.proc
|
||||
|
||||
debug = True
|
||||
|
||||
class ParsedCommand(gdb.Command):
|
||||
def __init__(self, function):
|
||||
super(ParsedCommand, self).__init__(function.__name__, gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION)
|
||||
self.function = function
|
||||
|
||||
def invoke(self, argument, from_tty):
|
||||
argv = gdb.string_to_argv(argument)
|
||||
|
||||
for i,arg in enumerate(argv):
|
||||
try:
|
||||
argv[i] = gdb.parse_and_eval(arg)
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
arg = gef.regs.fix(arg)
|
||||
argv[i] = gdb.parse_and_eval(arg)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.function(*argv)
|
||||
except TypeError:
|
||||
if debug: print(traceback.format_exc())
|
||||
pass
|
||||
|
||||
def __call__(self, *args):
|
||||
self.function(*args)
|
||||
|
||||
def OnlyWhenRunning(func):
|
||||
def wrapper(*a):
|
||||
func.__doc__
|
||||
if not gef.proc.alive:
|
||||
pass
|
||||
else:
|
||||
func(*a)
|
||||
wrapper.__name__ = func.__name__
|
||||
wrapper.__module__ = func.__module__
|
||||
return wrapper
|
||||
|
||||
|
||||
@ParsedCommand
|
||||
@OnlyWhenRunning
|
||||
def searchmem(searchfor):
|
||||
|
||||
if isinstance(searchfor, gdb.Value):
|
||||
try:
|
||||
searchfor = gef.memory.read(searchfor.address, searchfor.sizeof)
|
||||
except:
|
||||
searchfor = 0
|
||||
print(searchfor)
|
||||
@ -0,0 +1,86 @@
|
||||
import gdb
|
||||
import gef.commands
|
||||
import gef.color
|
||||
import gef.vmmap
|
||||
import gef.symbol
|
||||
import gef.regs
|
||||
import gef.ui
|
||||
import gef.disasm
|
||||
import gef.chain
|
||||
import gef.commands.telescope
|
||||
import gef.events
|
||||
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
@gef.events.stop
|
||||
def context(*args):
|
||||
if len(args) == 0:
|
||||
args = ['reg','code','stack','backtrace']
|
||||
|
||||
args = [a[0] for a in args]
|
||||
|
||||
print(gef.color.legend())
|
||||
if 'r' in args: context_regs()
|
||||
if 'c' in args: context_code()
|
||||
if 's' in args: context_stack()
|
||||
if 'b' in args: context_backtrace()
|
||||
|
||||
def context_regs():
|
||||
print(gef.color.blue(gef.ui.banner("registers")))
|
||||
for reg in gef.regs.gpr + (gef.regs.frame, gef.regs.stack, '$pc'):
|
||||
if reg is None:
|
||||
continue
|
||||
|
||||
value = gef.regs[reg]
|
||||
|
||||
# Make the register stand out
|
||||
regname = gef.color.bold(reg.ljust(4).upper())
|
||||
|
||||
print("%s %s" % (regname, gef.chain.format(value)))
|
||||
|
||||
def context_code():
|
||||
print(gef.color.blue(gef.ui.banner("code")))
|
||||
pc = gef.regs.pc
|
||||
instructions = gef.disasm.near(gef.regs.pc, 5)
|
||||
|
||||
# In case $pc is in a new map we don't know about,
|
||||
# this will trigger an exploratory search.
|
||||
gef.vmmap.find(pc)
|
||||
|
||||
# Ensure screen data is always at the same spot
|
||||
for i in range(11 - len(instructions)):
|
||||
print()
|
||||
|
||||
# Find all of the symbols for the addresses
|
||||
symbols = []
|
||||
for i in instructions:
|
||||
symbol = gef.symbol.get(i.address)
|
||||
if symbol:
|
||||
symbol = '<%s> ' % symbol
|
||||
symbols.append(symbol)
|
||||
|
||||
# Find the longest symbol name so we can adjust
|
||||
longest_sym = max(map(len, symbols))
|
||||
|
||||
# Pad them all out
|
||||
for i,s in enumerate(symbols):
|
||||
symbols[i] = s.ljust(longest_sym)
|
||||
|
||||
# Print out each instruction
|
||||
for i,s in zip(instructions, symbols):
|
||||
asm = gef.disasm.color(i)
|
||||
prefix = ' =>' if i.address == pc else ' '
|
||||
print(prefix, s + hex(i.address), asm)
|
||||
|
||||
def context_stack():
|
||||
print(gef.color.blue(gef.ui.banner("stack")))
|
||||
gef.commands.telescope.telescope(gef.regs.sp)
|
||||
|
||||
def context_backtrace():
|
||||
print(gef.color.blue(gef.ui.banner("backtrace")))
|
||||
frame = gdb.selected_frame()
|
||||
for i in range(0,10):
|
||||
if frame:
|
||||
print(gef.ui.addrsz(frame.pc()), frame.name() or '???')
|
||||
frame = frame.older()
|
||||
@ -0,0 +1,10 @@
|
||||
import gdb
|
||||
import gef.vmmap
|
||||
import gef.commands
|
||||
import gef.color
|
||||
import gef.dt
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
def dt(typename, address=None):
|
||||
print(gef.dt.dt(typename, addr=address))
|
||||
@ -0,0 +1,19 @@
|
||||
import gef.regs
|
||||
import gef.commands
|
||||
import gef.memory
|
||||
import gef.hexdump
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
def hexdump(address=None, count=64):
|
||||
"""Hexdumps some data"""
|
||||
if address is None:
|
||||
address = gef.regs.sp
|
||||
|
||||
int(address)
|
||||
|
||||
data = gef.memory.read(address, count)
|
||||
|
||||
for line in gef.hexdump.hexdump(data, address=address):
|
||||
print(line)
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
import struct
|
||||
import gdb
|
||||
|
||||
def pack(data, size=None):
|
||||
@ -0,0 +1,29 @@
|
||||
import gdb
|
||||
import gef.commands
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
def start():
|
||||
|
||||
entries = ["main"]
|
||||
main_addr = peda.main_entry()
|
||||
if main_addr:
|
||||
entries += ["*0x%x" % main_addr]
|
||||
entries += ["__libc_start_main@plt"]
|
||||
entries += ["_start"]
|
||||
entries += ["_init"]
|
||||
|
||||
started = 0
|
||||
for e in entries:
|
||||
out = peda.execute_redirect("tbreak %s" % e)
|
||||
if out and "breakpoint" in out:
|
||||
peda.execute("run %s" % ' '.join(arg))
|
||||
started = 1
|
||||
break
|
||||
|
||||
if not started: # try ELF entry point or just "run" as the last resort
|
||||
elf_entry = peda.elfentry()
|
||||
if elf_entry:
|
||||
out = peda.execute_redirect("tbreak *%s" % elf_entry)
|
||||
|
||||
peda.execute("run")
|
||||
@ -0,0 +1,44 @@
|
||||
import gef.memory
|
||||
import gef.regs
|
||||
import gef.types
|
||||
import gef.commands
|
||||
import gef.chain
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
def telescope(address=None, count=8):
|
||||
if address is None:
|
||||
address = gef.regs.sp
|
||||
|
||||
if address < 100:
|
||||
count = address
|
||||
address = gef.regs.sp
|
||||
|
||||
address = int(address)
|
||||
count = int(count)
|
||||
|
||||
reg_values = {r:v for (r,v) in gef.regs.items()}
|
||||
# address = gef.memory.poi(gef.types.ppvoid, address)
|
||||
ptrsize = gef.types.ptrsize
|
||||
|
||||
start = address
|
||||
stop = address + (count*ptrsize)
|
||||
step = ptrsize
|
||||
|
||||
# Find all registers which show up in the trace
|
||||
regs = {}
|
||||
for i in range(start, stop, step):
|
||||
regs[i] = []
|
||||
for reg, regval in reg_values.items():
|
||||
if i <= regval < i+ptrsize:
|
||||
regs[i].append(reg)
|
||||
regs[i] = ' '.join(regs[i])
|
||||
|
||||
# Find the longest set of register information
|
||||
longest_regs = max(map(len, regs.values())) + 1
|
||||
|
||||
# Print everything out
|
||||
for i,addr in enumerate(range(start, stop, step)):
|
||||
print("%02i:%04i|" % (i, addr-start),
|
||||
regs[addr].ljust(longest_regs),
|
||||
gef.chain.format(addr))
|
||||
@ -0,0 +1,24 @@
|
||||
import gdb
|
||||
import gef.vmmap
|
||||
import gef.commands
|
||||
import gef.color
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
def vmmap(map=None):
|
||||
int_map = None
|
||||
str_map = None
|
||||
if isinstance(map, str):
|
||||
str_map = map
|
||||
elif isinstance(map, (int, gdb.Value)):
|
||||
int_map = int(map)
|
||||
|
||||
|
||||
for page in gef.vmmap.get():
|
||||
if str_map and str_map not in page.objfile:
|
||||
continue
|
||||
if int_map and int_map not in page:
|
||||
continue
|
||||
|
||||
print(gef.color.get(page.vaddr, text=str(page)))
|
||||
print(gef.color.legend())
|
||||
@ -0,0 +1,5 @@
|
||||
import gdb
|
||||
import gef.commands
|
||||
|
||||
@gef.commands.ParsedCommand
|
||||
@gef.commands.OnlyWhenRunning
|
||||
@ -0,0 +1,80 @@
|
||||
import copy
|
||||
import string
|
||||
import gef.color
|
||||
|
||||
|
||||
def groupby(array, count, fill=None):
|
||||
array = copy.copy(array)
|
||||
while fill and len(array) % count:
|
||||
array.append(fill)
|
||||
for i in range(0, len(array), count):
|
||||
yield array[i:i+count]
|
||||
|
||||
#
|
||||
# We want to colorize the hex characters
|
||||
#
|
||||
color_scheme = {i:gef.color.normal("%02x" % i) for i in range(256)}
|
||||
|
||||
for c in (string.ascii_letters + string.digits + string.punctuation).encode('utf-8'):
|
||||
color_scheme[c] = gef.color.bold("%02x" % c)
|
||||
|
||||
for c in bytearray(b'\x00\xff'):
|
||||
color_scheme[c] = gef.color.red("%02x" % c)
|
||||
|
||||
color_scheme[-1] = ' '
|
||||
|
||||
#
|
||||
# Only print out printable values on the righ hand side
|
||||
#
|
||||
printable = {i:'.' for i in range(256)}
|
||||
for c in (string.ascii_letters + string.digits + string.punctuation).encode('utf-8'):
|
||||
printable[c] = chr(c)
|
||||
|
||||
printable[-1] = ' '
|
||||
|
||||
def hexdump(data, address = 0, width = 16, skip = True):
|
||||
data = list(bytearray(data))
|
||||
base = address
|
||||
last_line = None
|
||||
skipping = False
|
||||
for i, line in enumerate(groupby(data, width, -1)):
|
||||
if skip and line == last_line:
|
||||
if not skipping:
|
||||
skipping = True
|
||||
yield '*'
|
||||
continue
|
||||
else:
|
||||
skipping = False
|
||||
last_line = line
|
||||
|
||||
hexline = []
|
||||
|
||||
if address:
|
||||
hexline.append("+%04x " % (i*width))
|
||||
|
||||
hexline.append("%#08x " % (base + (i*width)))
|
||||
|
||||
for group in groupby(line, 4):
|
||||
for char in group:
|
||||
hexline.append(color_scheme[char])
|
||||
hexline.append(' ')
|
||||
hexline.append(' ')
|
||||
|
||||
hexline.append('|')
|
||||
for group in groupby(line, 4):
|
||||
for char in group:
|
||||
hexline.append(printable[char])
|
||||
hexline.append('|')
|
||||
|
||||
|
||||
yield(''.join(hexline))
|
||||
|
||||
hexline = []
|
||||
|
||||
if address:
|
||||
hexline.append("+%04x " % len(data))
|
||||
|
||||
hexline.append("%#08x " % (base + len(data)))
|
||||
|
||||
yield ''.join(hexline)
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
import gdb
|
||||
import string
|
||||
import gef.types
|
||||
|
||||
def get(address):
|
||||
try:
|
||||
return gdb.Value(value).cast(gef.types.pchar).string()
|
||||
sz = gdb.Value(address).cast(gef.types.pchar).string()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
return None
|
||||
|
||||
if not all(s in string.printable for s in sz):
|
||||
sz
|
||||
|
||||
if len(sz) < 15:
|
||||
return sz
|
||||
|
||||
return sz[:15] + '...'
|
||||
@ -0,0 +1,15 @@
|
||||
import struct, termios, fcntl, sys
|
||||
import gef.arch
|
||||
|
||||
def banner(title):
|
||||
title = title.upper()
|
||||
try:
|
||||
_height, width = struct.unpack('hh', fcntl.ioctl(sys.stdin.fileno(), termios.TIOCGWINSZ, '1234'))
|
||||
except:
|
||||
width = 80
|
||||
width -= 2
|
||||
return ("[{:-^%ss}]" % width).format(title)
|
||||
|
||||
def addrsz(address):
|
||||
address = int(address) & gef.arch.ptrmask
|
||||
return "%{}x".format(2*gef.arch.ptrsize) % address
|
||||
Loading…
Reference in new issue