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:
parent
be6fed13fa
commit
734ada9b57
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user