• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 1

22 Mar 2023 11:26AM UTC coverage: 1.304% (-70.2%) from 71.53%
1

push

github

web-flow
Add search for libc binary by leaked function addresses (#2103)

* libcdb: Add option to search by function offsets

When you're able to leak addresses of the libc library, use `libcdb.search_by_symbol_offsets()` to find and download the matching libc library from https://libc.rip.

If there are multiple matches, the user is prompted to select one interactively. The selection can be saved in the code for future executions of the script.

Fixes #1867

* libcdb: Handle multiple results when looking up by hash

Sometimes the same library appears to be indexed multiple times (see 0b52d2e71). Handle that situation by selecting the first in the list, since they should all be identical given the same hash value.

* Update CHANGELOG

* Fix off-by-one when pre-selecting a libc

* Do .json() only once

---------

Co-authored-by: Arusekk <arek_koz@o2.pl>

2 of 5910 branches covered (0.03%)

0 of 52 new or added lines in 1 file covered. (0.0%)

11873 existing lines in 140 files now uncovered.

221 of 16952 relevant lines covered (1.3%)

0.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pwnlib/commandline/debug.py
1
#!/usr/bin/env python2
UNCOV
2
from __future__ import absolute_import
×
UNCOV
3
from __future__ import division
×
4

UNCOV
5
import argparse
×
UNCOV
6
import sys
×
7

UNCOV
8
from pwn import *
×
UNCOV
9
from pwnlib.commandline import common
×
10

UNCOV
11
parser = common.parser_commands.add_parser(
×
12
    'debug',
13
    help = 'Debug a binary in GDB',
14
    description = 'Debug a binary in GDB'
15
)
UNCOV
16
parser.add_argument(
×
17
    '-x', metavar='GDBSCRIPT',
18
    type=argparse.FileType('r'),
19
    help='Execute GDB commands from this file.'
20
)
UNCOV
21
parser.add_argument(
×
22
    '--pid',
23
    type=int,
24
    help="PID to attach to"
25
)
UNCOV
26
parser.add_argument(
×
27
    '-c', '--context',
28
    metavar = 'context',
29
    action = 'append',
30
    type   = common.context_arg,
31
    choices = common.choices,
32
    help = 'The os/architecture/endianness/bits the shellcode will run in (default: linux/i386), choose from: %s' % common.choices,
33
)
UNCOV
34
parser.add_argument(
×
35
    '--exec',
36

37
    # NOTE: Type cannot be "file" because we may be referring to a remote
38
    #       file, or a file on an Android device.
39
    type=str,
40

41
    dest='executable',
42
    help='File to debug'
43
)
UNCOV
44
parser.add_argument(
×
45
    '--process', metavar='PROCESS_NAME',
46
    help='Name of the process to attach to (e.g. "bash")'
47
)
UNCOV
48
parser.add_argument(
×
49
    '--sysroot', metavar='SYSROOT',
50
    type=str,
51
    default='',
52
    help="GDB sysroot path"
53
)
54

UNCOV
55
def main(args):
×
56
    gdbscript = ''
×
57
    if args.x:
×
58
        gdbscript = args.x.read()
×
59

60
    if context.os == 'android':
×
61
        context.device = adb.wait_for_device()
×
62

63
    if args.executable:
×
64
        if os.path.exists(args.executable):
×
65
            context.binary = ELF(args.executable)
×
66
            target = context.binary.path
×
67

68
        # This path does nothing, but avoids the "print_usage()"
69
        # path below.
70
        elif context.os == 'android':
×
71
            target = args.executable
×
72
    elif args.pid:
×
73
        target = int(args.pid)
×
74
    elif args.process:
×
75
        if context.os == 'android':
×
76
            target = adb.pidof(args.process)
×
77
        else:
78
            target = pidof(args.process)
×
79

80
        # pidof() returns a list
81
        if not target:
×
82
            log.error("Could not find a PID for %r", args.process)
×
83

84
        target = target[0]
×
85

86
        # pidof will sometimes return all PIDs, including init
87
        if target == 1:
×
88
            log.error("Got PID 1 from pidof.  Check the process name, or use --pid 1 to debug init")
×
89
    else:
90
        parser.print_usage()
×
91
        return 1
×
92

93
    if args.pid or args.process:
×
94
        pid = gdb.attach(target, gdbscript=gdbscript, sysroot=args.sysroot)
×
95

96
        # Since we spawned the gdbserver process, and process registers an
97
        # atexit handler to close itself, gdbserver will be terminated when
98
        # we exit.  This will manifest as a "remote connected ended" or
99
        # similar error message.  Hold it open for the user.
100
        log.info("GDB connection forwarding will terminate when you press enter")
×
101
        pause()
×
102
    else:
103
        gdb.debug(target, gdbscript=gdbscript, sysroot=args.sysroot).interactive()
×
104

UNCOV
105
if __name__ == '__main__':
×
106
    pwnlib.commandline.common.main(__file__)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc