1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

gdb.py: add a 'memdump' command.

This makes it easier for me to examine the contents of binary memory
buffers, while debugging through code that does crypto or packet
marshalling.
This commit is contained in:
Simon Tatham 2018-06-09 07:52:28 +01:00
parent be6fed13fa
commit 734ada9b57

View File

@ -35,3 +35,62 @@ rcpp.add_printer(PuTTYBignumPrettyPrinter.name, "^Bignum$",
PuTTYBignumPrettyPrinter)
gdb.printing.register_pretty_printer(None, rcpp)
class MemDumpCommand(gdb.Command):
"""Print a hex+ASCII dump of object EXP.
EXP must be an expression whose value resides in memory. The
contents of the memory it occupies are printed in a standard hex
dump format, with each line showing an offset relative to the
address of EXP, then the hex byte values of the memory at that
offset, and then a translation into ASCII of the same bytes (with
values outside the printable ASCII range translated as '.').
To dump a number of bytes from a particular address, it's useful
to use the gdb expression extensions {TYPE} and @LENGTH. For
example, if 'ptr' and 'len' are variables giving an address and a
length in bytes, then the command
memdump {char} ptr @ len
will dump the range of memory described by those two variables."""
def __init__(self):
super(MemDumpCommand, self).__init__(
"memdump", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
def invoke(self, cmdline, from_tty):
expr = gdb.parse_and_eval(cmdline)
try:
start, size = int(expr.address), expr.type.sizeof
except gdb.error as e:
sys.stderr.write(str(e))
return
except (TypeError, AttributeError):
sys.stderr.write("expression must identify an object in memory")
return
width = 16
line_ptr_type = gdb.lookup_type(
"unsigned char").const().array(width).pointer()
dumpaddr = 0
while size > 0:
line = gdb.Value(start).cast(line_ptr_type).dereference()
thislinelen = min(size, width)
start += thislinelen
size -= thislinelen
dumpline = [None, " "] + [" "] * width + [" "] + [""] * width
dumpline[0] = "{:08x}".format(dumpaddr)
dumpaddr += thislinelen
for i in range(thislinelen):
ch = int(line[i]) & 0xFF
dumpline[2+i] = " {:02x}".format(ch)
dumpline[3+width+i] = chr(ch) if 0x20 <= ch < 0x7F else "."
sys.stdout.write("".join(dumpline) + "\n")
MemDumpCommand()