Skip to content

Commit 51cbdb4

Browse files
ckxckxpeace-maker
andauthored
Fix attaching to a gdbserver with tuple gdb.attach(('0.0.0.0',12345)) (#2291)
* Patch for #issues/2290 * Return listening process on `pidof(("0.0.0.0", 1234))` Instead of returning the process which is connected to port 1234, return the process which is listening on that port. * Update CHANGELOG --------- Co-authored-by: Peace-Maker <[email protected]>
1 parent 61804b1 commit 51cbdb4

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ The table below shows which release corresponds to each branch, and what date th
8484
- [#2482][2482] Throw error when using `sni` and setting `server_hostname` manually in `remote`
8585
- [#2478][2478] libcdb-cli: add `--offline-only`, refactor unstrip and add fetch parser for download libc-database
8686
- [#2484][2484] Allow to disable caching
87+
- [#2291][2291] Fix attaching to a gdbserver with tuple `gdb.attach(('0.0.0.0',12345))`
8788

8889
[2471]: https://github.com/Gallopsled/pwntools/pull/2471
8990
[2358]: https://github.com/Gallopsled/pwntools/pull/2358
@@ -96,6 +97,7 @@ The table below shows which release corresponds to each branch, and what date th
9697
[2482]: https://github.com/Gallopsled/pwntools/pull/2482
9798
[2478]: https://github.com/Gallopsled/pwntools/pull/2478
9899
[2484]: https://github.com/Gallopsled/pwntools/pull/2484
100+
[2291]: https://github.com/Gallopsled/pwntools/pull/2291
99101

100102
## 4.14.0 (`beta`)
101103

pwnlib/gdb.py

+26
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,8 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
950950
Process name. The youngest process is selected.
951951
:obj:`tuple`
952952
Host, port pair of a listening ``gdbserver``
953+
Tries to look up the target exe from the ``gdbserver`` commandline,
954+
requires explicit ``exe`` argument if the target exe is not in the commandline.
953955
:class:`.process`
954956
Process to connect to
955957
:class:`.sock`
@@ -1034,6 +1036,30 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
10341036
>>> io.sendline(b'echo Hello from bash && exit')
10351037
>>> io.recvall()
10361038
b'Hello from bash\n'
1039+
>>> server.close()
1040+
1041+
Attach to a gdbserver / gdbstub running on the local machine
1042+
by specifying the host and port tuple it is listening on.
1043+
(gdbserver always listens on 0.0.0.0)
1044+
1045+
>>> gdbserver = process(['gdbserver', '1.2.3.4:12345', '/bin/bash'])
1046+
>>> gdbserver.recvline_contains(b'Listening on port', timeout=10)
1047+
b'Listening on port 12345'
1048+
>>> pid = gdb.attach(('0.0.0.0', 12345), gdbscript='''
1049+
... tbreak main
1050+
... commands
1051+
... call puts("Hello from gdbserver debugger!")
1052+
... continue
1053+
... end
1054+
... ''')
1055+
>>> gdbserver.recvline(timeout=10) # doctest: +ELLIPSIS
1056+
b'Remote debugging from host 127.0.0.1, ...\n'
1057+
>>> gdbserver.recvline(timeout=10)
1058+
b'Hello from gdbserver debugger!\n'
1059+
>>> gdbserver.sendline(b'echo Hello from bash && exit')
1060+
>>> gdbserver.recvline(timeout=10)
1061+
b'Hello from bash\n'
1062+
>>> gdbserver.close()
10371063
10381064
Attach to processes running on a remote machine via an SSH :class:`.ssh` process
10391065

pwnlib/util/net.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,17 @@ def sockinfos(addr, f, t):
259259
infos |= set(socket.getaddrinfo(sockaddr[0], sockaddr[1], socket.AF_INET6, t, proto, socket.AI_V4MAPPED))
260260
return infos
261261

262-
if local is not None:
263-
local = sockinfos(local, fam, typ)
264-
remote = sockinfos(remote, fam, typ)
262+
local = sockinfos(local, fam, typ)
263+
if remote is not None:
264+
remote = sockinfos(remote, fam, typ)
265265

266266
def match(c):
267267
laddrs = sockinfos(c.laddr, c.family, c.type)
268268
raddrs = sockinfos(c.raddr, c.family, c.type)
269-
if not (raddrs & remote):
269+
if not (laddrs & local):
270270
return False
271-
if local is None:
271+
if remote is None:
272272
return True
273-
return bool(laddrs & local)
273+
return bool(raddrs & remote)
274274

275275
return match

pwnlib/util/proc.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ def pidof(target):
2727
- :class:`pwnlib.tubes.sock.sock`: singleton list of the PID at the
2828
remote end of `target` if it is running on the host. Otherwise an
2929
empty list.
30+
- :class:`pwnlib.tubes.ssh.ssh_channel`: singleton list of the PID of
31+
`target` on the remote system.
32+
- :class:`tuple`: singleton list of the PID at the local end of the
33+
connection to `target` if it is running on the host. Otherwise an
34+
empty list.
3035
3136
Arguments:
3237
target(object): The target whose PID(s) to find.
@@ -38,7 +43,7 @@ def pidof(target):
3843
3944
>>> l = tubes.listen.listen()
4045
>>> p = process(['curl', '-s', 'http://127.0.0.1:%d'%l.lport])
41-
>>> pidof(p) == pidof(l) == pidof(('127.0.0.1', l.lport))
46+
>>> pidof(p) == pidof(l) == pidof(('127.0.0.1', l.rport))
4247
True
4348
"""
4449
if isinstance(target, tubes.ssh.ssh_channel):
@@ -51,7 +56,7 @@ def pidof(target):
5156
return [c.pid for c in psutil.net_connections() if match(c)]
5257

5358
elif isinstance(target, tuple):
54-
match = sock_match(None, target)
59+
match = sock_match(target, None)
5560
return [c.pid for c in psutil.net_connections() if match(c)]
5661

5762
elif isinstance(target, tubes.process.process):

0 commit comments

Comments
 (0)