Refactor pwndbg.commands.windbg.dX and pwndbg.hexdump.hexdump (#1341)

* Update windbg.py

* Update hexdump.py

* Update hexdump.py

* Update hexdump.py

* Update hexdump.py

* Update hexdump.py

* Update hexdump.py

* Update windbg.py

* Update windbg.py

* Update hexdump.py

* Update hexdump.py

* Update typeinfo.py

* Update hexdump.py

* Update windbg.py

* Update setup-dev.sh

* Update setup-dev.sh

* Update setup-dev.sh
pull/1348/head
ruijia-zhou 3 years ago committed by GitHub
parent f9dac535c3
commit 45f8712dfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,8 +4,8 @@ Compatibility functionality for Windbg users.
import argparse
import codecs
import math
from builtins import str
from itertools import chain
import gdb
@ -15,16 +15,7 @@ import pwndbg.gdblib.memory
import pwndbg.gdblib.strings
import pwndbg.gdblib.symbol
import pwndbg.gdblib.typeinfo
def get_type(size):
return {
1: pwndbg.gdblib.typeinfo.uint8,
2: pwndbg.gdblib.typeinfo.uint16,
4: pwndbg.gdblib.typeinfo.uint32,
8: pwndbg.gdblib.typeinfo.uint64,
}[size]
import pwndbg.hexdump
parser = argparse.ArgumentParser(description="Starting at the specified address, dump N bytes.")
parser.add_argument(
@ -141,50 +132,18 @@ def dX(size, address, count, to_string=False, repeat=False):
"""
Traditionally, windbg will display 16 bytes of data per line.
"""
values = []
if repeat:
count = dX.last_count
address = dX.last_address
else:
address = int(address) & pwndbg.gdblib.arch.ptrmask
count = int(count)
type = get_type(size)
for i in range(count):
try:
gval = pwndbg.gdblib.memory.poi(type, address + i * size)
# print(str(gval))
values.append(int(gval))
except gdb.MemoryError:
break
if not values:
print("Could not access the provided address")
return
n_rows = int(math.ceil(count * size / float(16)))
row_sz = int(16 / size)
rows = [values[i * row_sz : (i + 1) * row_sz] for i in range(n_rows)]
lines = []
# sys.stdout.write(repr(rows) + '\n')
for i, row in enumerate(rows):
if not row:
continue
line = [enhex(pwndbg.gdblib.arch.ptrsize, address + (i * 16)), " "]
for value in row:
line.append(enhex(size, value))
lines.append(" ".join(line))
lines = list(
chain.from_iterable(
pwndbg.hexdump.hexdump(
data=None, size=size, count=count, address=address, repeat=repeat, dX_call=True
)
)
)
if not to_string:
if not to_string and lines:
print("\n".join(lines))
dX.last_count = count
dX.last_address = address + len(rows) * 16
return lines

@ -87,3 +87,12 @@ def read_gdbvalue(type_name, addr):
"""Read the memory contents at addr and interpret them as a GDB value with the given type"""
gdb_type = pwndbg.gdblib.typeinfo.load(type_name)
return gdb.Value(addr).cast(gdb_type.pointer()).dereference()
def get_type(size):
return {
1: pwndbg.gdblib.typeinfo.uint8,
2: pwndbg.gdblib.typeinfo.uint16,
4: pwndbg.gdblib.typeinfo.uint32,
8: pwndbg.gdblib.typeinfo.uint64,
}[size]

@ -2,13 +2,17 @@
Hexdump implementation, ~= stolen from pwntools.
"""
import math
import string
import gdb
import pwnlib.util.lists
import pwndbg.color.hexdump as H
import pwndbg.color.theme as theme
import pwndbg.gdblib.config
import pwndbg.gdblib.typeinfo
from pwndbg.commands.windbg import enhex
color_scheme = None
printable = None
@ -66,51 +70,105 @@ def load_color_scheme():
def hexdump(
data, address=0, width=16, group_width=4, flip_group_endianess=False, skip=True, offset=0
data,
address=0,
width=16,
group_width=4,
flip_group_endianess=False,
skip=True,
offset=0,
size=0,
count=0,
repeat=False,
dX_call=False,
):
if not color_scheme or not printable:
load_color_scheme()
# If there's nothing to print, just print the offset and address and return
if len(data) == 0:
yield H.offset("+%04x " % len(data)) + H.address("%#08x " % (address + len(data)))
# Don't allow iterating over this generator again
return
data = list(bytearray(data))
last_line = None
skipping = False
for i, line in enumerate(groupby(width, data, fill=-1)):
if skip and line == last_line:
if skipping:
continue
if not dX_call:
if not color_scheme or not printable:
load_color_scheme()
# If there's nothing to print, just print the offset and address and return
if len(data) == 0:
yield H.offset("+%04x " % len(data)) + H.address("%#08x " % (address + len(data)))
# Don't allow iterating over this generator again
return
data = list(bytearray(data))
last_line = None
skipping = False
for i, line in enumerate(groupby(width, data, fill=-1)):
if skip and line == last_line:
if skipping:
continue
skipping = True
yield "..."
else:
skipping = False
last_line = line
hexline = []
hexline.append(H.offset("+%04x " % ((i + offset) * width)))
hexline.append(H.address("%#08x " % (address + (i * width))))
for group in groupby(group_width, line):
group = reversed(group) if flip_group_endianess else group
for idx, char in enumerate(group):
if flip_group_endianess and idx == group_width - 1:
hexline.append(H.highlight_group_lsb(color_scheme[char]))
else:
hexline.append(color_scheme[char])
hexline.append(str(config_byte_separator))
hexline.append(" ")
skipping = True
yield "..."
else:
skipping = False
last_line = line
hexline = []
hexline.append(H.offset("+%04x " % ((i + offset) * width)))
hexline.append(H.address("%#08x " % (address + (i * width))))
for group in groupby(group_width, line):
group = reversed(group) if flip_group_endianess else group
for idx, char in enumerate(group):
if flip_group_endianess and idx == group_width - 1:
hexline.append(H.highlight_group_lsb(color_scheme[char]))
else:
hexline.append(color_scheme[char])
hexline.append(str(config_byte_separator))
hexline.append(" ")
hexline.append(H.separator("%s" % config_separator))
for group in groupby(group_width, line):
for char in group:
hexline.append(printable[char])
hexline.append(H.separator("%s" % config_separator))
for group in groupby(group_width, line):
for char in group:
hexline.append(printable[char])
hexline.append(H.separator("%s" % config_separator))
yield "".join(hexline)
else:
# Traditionally, windbg will display 16 bytes of data per line.
values = []
if repeat:
count = hexdump.last_count
address = hexdump.last_address
else:
address = int(address) & pwndbg.gdblib.arch.ptrmask
count = int(count)
size_type = pwndbg.gdblib.typeinfo.get_type(size)
for i in range(count):
try:
gval = pwndbg.gdblib.memory.poi(size_type, address + i * size)
values.append(int(gval))
except gdb.MemoryError:
break
if not values:
print("Could not access the provided address")
return
n_rows = int(math.ceil(count * size / float(16)))
row_sz = int(16 / size)
rows = [values[i * row_sz : (i + 1) * row_sz] for i in range(n_rows)]
lines = []
for i, row in enumerate(rows):
if not row:
continue
line = [enhex(pwndbg.gdblib.arch.ptrsize, address + (i * 16)), " "]
for value in row:
line.append(enhex(size, value))
lines.append(" ".join(line))
hexdump.last_count = count
hexdump.last_address = address + len(rows) * 16
yield "".join(hexline)
yield lines

Loading…
Cancel
Save