pwnlib.gdb — Working with GDB

pwnlib.gdb.attach(target, execute=None, exe=None, arch=None) → None[source]

Start GDB in a new terminal and attach to target. pwnlib.util.proc.pidof() is used to find the PID of target except when target is a (host, port)-pair. In that case target is assumed to be a GDB server.

If it is running locally and exe is not given we will try to find the path of the target binary from parsing the command line of the program running the GDB server (e.g. qemu or gdbserver). Notice that if the PID is known (when target is not a GDB server) exe will be read from /proc/<pid>/exe.

If gdb-multiarch is installed we use that or ‘gdb’ otherwise.

Parameters:
  • target – The target to attach to.
  • execute (str or file) – GDB script to run after attaching.
  • exe (str) – The path of the target binary.
  • arch (str) – Architechture of the target binary. If exe known GDB will detect the architechture automatically (if it is supported).
Returns:

None

pwnlib.gdb.debug(args) → tube[source]

Launch a GDB server with the specified command line, and launches GDB to attach to it.

Parameters:
  • args – Same args as passed to pwnlib.tubes.process
  • ssh – Remote ssh session to use to launch the process. Automatically sets up port forwarding so that gdb runs locally.
Returns:

A tube connected to the target process

pwnlib.gdb.debug_assembly(asm, execute=None, vma=None)[source]

Creates an ELF file, and launches it with GDB.

This is identical to debug_shellcode, except that any defined symbols are available in GDB, and it saves you the explicit call to asm().

pwnlib.gdb.debug_shellcode(data, execute=None, vma=None)[source]

Creates an ELF file, and launches it with GDB.

Parameters:
  • data (bytes) – Assembled shellcode bytes
  • kwargs (dict) – Arguments passed to context (e.g. arch=’arm’)
Returns:

A process tube connected to the shellcode on stdin/stdout/stderr.

pwnlib.gdb.find_module_addresses(binary, ssh=None, ulimit=False)[source]

Cheat to find modules by using GDB.

We can’t use /proc/$pid/map since some servers forbid it. This breaks info proc in GDB, but info sharedlibrary still works. Additionally, info sharedlibrary works on FreeBSD, which may not have procfs enabled or accessible.

The output looks like this:

info proc mapping
process 13961
warning: unable to open /proc file '/proc/13961/maps'

info sharedlibrary
From        To          Syms Read   Shared Object Library
0xf7fdc820  0xf7ff505f  Yes (*)     /lib/ld-linux.so.2
0xf7fbb650  0xf7fc79f8  Yes         /lib32/libpthread.so.0
0xf7e26f10  0xf7f5b51c  Yes (*)     /lib32/libc.so.6
(*): Shared library is missing debugging information.

Note that the raw addresses provided by info sharedlibrary are actually the address of the .text segment, not the image base address.

This routine automates the entire process of:

  1. Downloading the binaries from the remote server
  2. Scraping GDB for the information
  3. Loading each library into an ELF
  4. Fixing up the base address vs. the .text segment address
Parameters:
  • binary (str) – Path to the binary on the remote server
  • ssh (pwnlib.tubes.tube) – SSH connection through which to load the libraries. If left as None, will use a pwnlib.tubes.process.process.
  • ulimit (bool) – Set to True to run “ulimit -s unlimited” before GDB.
Returns:

A list of pwnlib.elf.ELF objects, with correct base addresses.

Example

>>> with context.local(log_level=9999): 
...     shell = ssh(host='bandit.labs.overthewire.org', user='bandit0', password='bandit0')
...     bash_libs = gdb.find_module_addresses('/bin/bash', shell)
>>> os.path.basename(bash_libs[0].path) 
'libc.so.6'
>>> hex(bash_libs[0].symbols[b'system']) 
'0x7ffff7634660'