diff --git a/pwndbg/color/hexdump.py b/pwndbg/color/hexdump.py index 23159f497..e9eb6352c 100644 --- a/pwndbg/color/hexdump.py +++ b/pwndbg/color/hexdump.py @@ -12,6 +12,9 @@ config_special = theme.ColoredParameter('hexdump-special-color', 'yellow', 'co config_offset = theme.ColoredParameter('hexdump-offset-color', 'none', 'color for hexdump command (offset label)') config_address = theme.ColoredParameter('hexdump-address-color', 'none', 'color for hexdump command (address label)') config_separator = theme.ColoredParameter('hexdump-separator-color', 'none', 'color for hexdump command (group separator)') +config_highlight_group_lsb = theme.Parameter('hexdump-highlight-group-lsb', 'underline', + 'highlight LSB of each group. Applies only if hexdump-adjust-group-endianess' + ' actually changes byte order.') def normal(x): return generateColorFunction(config.hexdump_normal_color)(x) @@ -33,3 +36,6 @@ def address(x): def separator(x): return generateColorFunction(config.hexdump_separator_color)(x) + +def highlight_group_lsb(x): + return generateColorFunction(config.hexdump_highlight_group_lsb)(x) diff --git a/pwndbg/commands/hexdump.py b/pwndbg/commands/hexdump.py index f59756000..23e25c161 100644 --- a/pwndbg/commands/hexdump.py +++ b/pwndbg/commands/hexdump.py @@ -17,6 +17,13 @@ pwndbg.config.Parameter('hexdump-width', pwndbg.config.Parameter('hexdump-bytes', 64, 'number of bytes printed by hexdump command') +pwndbg.config.Parameter('hexdump-group-width', + 4, + "number of bytes grouped in hexdump command (If -1, the architecture's pointer size is used)") +pwndbg.config.Parameter('hexdump-group-use-big-endian', + False, + 'Use big-endian within each group of bytes. Only applies to raw bytes, not the ASCII part. ' + 'See also hexdump-highlight-group-lsb.') def address_or_module_name(s): gdbval_or_str = pwndbg.commands.sloppy_gdb_parse(s) @@ -50,10 +57,13 @@ def hexdump(address_or_module=None, count=pwndbg.config.hexdump_bytes): else: hexdump.offset = 0 - address = int(address) - address &= pwndbg.arch.ptrmask - count = max(int(count), 0) - width = int(pwndbg.config.hexdump_width) + address = int(address) + address &= pwndbg.arch.ptrmask + count = max(int(count), 0) + width = int(pwndbg.config.hexdump_width) + group_width = int(pwndbg.config.hexdump_group_width) + group_width = pwndbg.typeinfo.ptrsize if group_width == -1 else group_width + flip_group_endianess = pwndbg.config.hexdump_group_use_big_endian and pwndbg.arch.endian == 'little' if count > address > 0x10000: count -= address @@ -65,7 +75,7 @@ def hexdump(address_or_module=None, count=pwndbg.config.hexdump_bytes): print(e) return - for i, line in enumerate(pwndbg.hexdump.hexdump(data, address=address, width=width, offset=hexdump.offset)): + for i, line in enumerate(pwndbg.hexdump.hexdump(data, address=address, width=width, group_width=group_width, flip_group_endianess=flip_group_endianess, offset=hexdump.offset)): print(line) hexdump.offset += i diff --git a/pwndbg/hexdump.py b/pwndbg/hexdump.py index d5b627b45..a4a0c0a34 100644 --- a/pwndbg/hexdump.py +++ b/pwndbg/hexdump.py @@ -23,6 +23,8 @@ def groupby(array, count, fill=None): config_colorize_ascii = theme.Parameter('hexdump-colorize-ascii', True, 'whether to colorize the hexdump command ascii section') config_separator = theme.Parameter('hexdump-ascii-block-separator', '│', 'block separator char of the hexdump command') +config_byte_separator = theme.Parameter('hexdump-byte-separator', ' ', 'separator of single bytes in hexdump (does NOT affect group separator)') + @pwndbg.config.Trigger([H.config_normal, H.config_zero, H.config_special, H.config_printable, config_colorize_ascii]) def load_color_scheme(): @@ -49,7 +51,7 @@ def load_color_scheme(): color_scheme[-1] = ' ' printable[-1] = ' ' -def hexdump(data, address = 0, width = 16, skip = True, offset = 0): +def hexdump(data, address = 0, width = 16, group_width=4, flip_group_endianess = False, skip = True, offset = 0): if not color_scheme or not printable: load_color_scheme() data = list(bytearray(data)) @@ -73,14 +75,19 @@ def hexdump(data, address = 0, width = 16, skip = True, offset = 0): hexline.append(H.address("%#08x " % (base + (i * width)))) - for group in groupby(line, 4): - for char in group: - hexline.append(color_scheme[char]) - hexline.append(' ') + for group in groupby(line, group_width): + group_length = len(group) + group = reversed(group) if flip_group_endianess else group + for idx, char in enumerate(group): + if flip_group_endianess and idx == group_length - 1: + hexline.append(H.highlight_group_lsb(color_scheme[char])) + else: + hexline.append(color_scheme[char]) + hexline.append(f'{config_byte_separator}') hexline.append(' ') hexline.append(H.separator('%s' % config_separator)) - for group in groupby(line, 4): + for group in groupby(line, group_width): for char in group: hexline.append(printable[char]) hexline.append(H.separator('%s' % config_separator))