@@ -249,31 +249,52 @@ def debug_shellcode(data, gdbscript=None, vma=None, api=False):
249
249
250
250
return debug (tmp_elf , gdbscript = gdbscript , arch = context .arch , api = api )
251
251
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
+
252
262
def _gdbserver_args (pid = None , path = None , args = None , which = None , env = None ):
253
263
"""_gdbserver_args(pid=None, path=None, args=None, which=None, env=None) -> list
254
264
255
265
Sets up a listening gdbserver, to either connect to the specified
256
266
PID, or launch the specified binary by its full path.
257
267
258
268
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.
262
272
which(callaable): Function to find the path of a binary.
273
+ env(dict): Dictionary containing the debugged process environment variables.
263
274
264
275
Returns:
265
276
A list of arguments to invoke gdbserver.
266
277
"""
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
+
269
291
270
292
if not which :
271
293
log .error ("Must specify which." )
272
294
273
- gdbserver = ''
295
+ args = list ( map ( bytes , args ))
274
296
275
- if not args :
276
- args = [str (path or pid )]
297
+ gdbserver = ''
277
298
278
299
# Android targets have a distinct gdbserver
279
300
if context .bits == 64 :
@@ -285,8 +306,6 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None):
285
306
if not gdbserver :
286
307
log .error ("gdbserver is not installed" )
287
308
288
- orig_args = args
289
-
290
309
gdbserver_args = [gdbserver , '--multi' ]
291
310
if context .aslr :
292
311
gdbserver_args += ['--no-disable-randomization' ]
@@ -297,13 +316,26 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None):
297
316
gdbserver_args += ['--once' , '--attach' ]
298
317
299
318
if env is not None :
300
- env_args = []
319
+ env_args = {}
320
+
301
321
for key in tuple (env ):
302
322
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 )
304
324
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" ]
307
339
308
340
gdbserver_args += ['localhost:0' ]
309
341
gdbserver_args += args
0 commit comments