mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48: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)
|
PuTTYBignumPrettyPrinter)
|
||||||
|
|
||||||
gdb.printing.register_pretty_printer(None, rcpp)
|
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