Skip to content

Commit 29b7ecf

Browse files
authored
Update gdb.py
before this commit, it was not was possible to specify `argv[0]` using `gdb.debug`, nor run the program with `argc = 0` (see for example Gallopsled#1273) this commit adds support for specifying both `argv` and `exe`, thus allowing further customization of the provided arguments.
1 parent 04f401c commit 29b7ecf

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

pwnlib/gdb.py

+46-14
Original file line numberDiff line numberDiff line change
@@ -249,31 +249,52 @@ def debug_shellcode(data, gdbscript=None, vma=None, api=False):
249249

250250
return debug(tmp_elf, gdbscript=gdbscript, arch=context.arch, api=api)
251251

252+
def _find_python(which):
253+
for py in ["python2.7", "python2", "python", "python3"]:
254+
# python3 os.execve does not support os.exec* with no argv, so it is last resort
255+
found = which(py)
256+
257+
if found is not None:
258+
return found
259+
260+
return None
261+
252262
def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None):
253263
"""_gdbserver_args(pid=None, path=None, args=None, which=None, env=None) -> list
254264
255265
Sets up a listening gdbserver, to either connect to the specified
256266
PID, or launch the specified binary by its full path.
257267
258268
Arguments:
259-
pid(int): Process ID to attach to
260-
path(str): Process to launch
261-
args(list): List of arguments to provide on the debugger command line
269+
pid(int): Process ID to attach to.
270+
path(str): Process to launch.
271+
args(list): List of arguments to provide on the debugger command line.
262272
which(callaable): Function to find the path of a binary.
273+
env(dict): Dictionary containing the debugged process environment variables.
263274
264275
Returns:
265276
A list of arguments to invoke gdbserver.
266277
"""
267-
if [pid, path, args].count(None) != 2:
268-
log.error("Must specify exactly one of pid, path, or args")
278+
if pid is not None:
279+
if [path, args].count(None) != 2:
280+
log.error("Cannot specify both pid and path or args")
281+
282+
elif path is None:
283+
if args:
284+
path = args[0]
285+
286+
path = packing._need_bytes(path, min_wrong=0x80)
287+
288+
if args is None:
289+
args = [path or str(pid).encode("utf-8")]
290+
269291

270292
if not which:
271293
log.error("Must specify which.")
272294

273-
gdbserver = ''
295+
args = list(map(bytes, args))
274296

275-
if not args:
276-
args = [str(path or pid)]
297+
gdbserver = ''
277298

278299
# Android targets have a distinct gdbserver
279300
if context.bits == 64:
@@ -285,8 +306,6 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None):
285306
if not gdbserver:
286307
log.error("gdbserver is not installed")
287308

288-
orig_args = args
289-
290309
gdbserver_args = [gdbserver, '--multi']
291310
if context.aslr:
292311
gdbserver_args += ['--no-disable-randomization']
@@ -297,13 +316,26 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None):
297316
gdbserver_args += ['--once', '--attach']
298317

299318
if env is not None:
300-
env_args = []
319+
env_args = {}
320+
301321
for key in tuple(env):
302322
if key.startswith(b'LD_'): # LD_PRELOAD / LD_LIBRARY_PATH etc.
303-
env_args.append(b'%s=%s' % (key, env.pop(key)))
323+
env_args[key] = env.pop(key)
304324
else:
305-
env_args.append(b'%s=%s' % (key, env[key]))
306-
gdbserver_args += ['--wrapper', 'env', '-i'] + env_args + ['--']
325+
env_args[key] = env[key]
326+
327+
python = _find_python(which)
328+
329+
gdbserver_args += ['--wrapper', '%s -c "import os; os.execvpe(%s, %s, %s)"' % (python, bytes(path), args, env_args)] + ['--']
330+
331+
elif not args or path != args[0]:
332+
python = _find_python(which)
333+
334+
gdbserver_args += ['--wrapper', '%s -c "import os; os.execvp(%s, %s)"' % (python, bytes(path), args)] + ['--']
335+
336+
if not args:
337+
# gdbserver won't start with no arguments supplied, so pass some dummy args in order to satisfy it.
338+
args += ["dummy_arg"]
307339

308340
gdbserver_args += ['localhost:0']
309341
gdbserver_args += args

0 commit comments

Comments
 (0)