Memory dump formatted like xxd from gdb

(gdb) define xxd
>dump binary memory dump.bin $arg0 $arg0+$arg1
>shell xxd dump.bin
>end
(gdb) xxd &j 10 
0000000: 0000 0000 0000 0000 0000 0000 4d8c a7f7  ............M...
0000010: ff7f 0000 0000 0000 0000 0000 c8d7 ffff  ................
0000020: ff7f 0000 0000 0000

Seems easy enough 😉

You could likely write a Python script (modern GDB versions have embedded Python interpreter) to do the same, and get rid of the need to “shell out”.

Update:

Here is a possible Python implementation (save this into xxd.py):

class XXD(gdb.Command):
  def __init__(self):
    super(XXD, self).__init__("xxd", gdb.COMMAND_USER)

  def _PrintLine(self, offset, bytes, size):
      print('{:08x}: '.format(offset), end='')
      todo = size
      while todo >= 4:
        print(''.join('{:02x}'.format(b) for b in bytes[0:4]), end='')
        todo -= 4
        bytes = bytes[3:]
        if todo:
          print(' ', end='')

      # Print any remaining bytes
      print(''.join('{:02x}'.format(b) for b in bytes[0:todo]), end='')

      print()
      return size

  def invoke(self, arg, from_tty):
    args = arg.split()
    if len(args) != 2:
      print("xxd: <addr> <count>")
      return
    size = int(args[1])
    addr = gdb.parse_and_eval(args[0])
    inferior = gdb.inferiors()[0]
    bytes = inferior.read_memory(addr, size).tobytes()

    offset = int(addr)
    while size > 0:
      n = self._PrintLine(offset, bytes, min(len(bytes), 16))
      size -= n
      offset += n
      bytes = bytes[n:]

XXD()

Use it like so:

// Sample program x.c
char foo[] = "abcdefghijklmopqrstuvwxyz";
int main() { return 0; }

gcc -g x.c
gdb -q ./a.out

(gdb) source xxd.py
Temporary breakpoint 1, main () at x.c:3
3       int main() { return 0; }

(gdb) xxd &foo[0] 18
00404030: 61626364 64656667 6768696a 6a6b6c6d
00404040: 7273

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)