Closed peace-maker closed 3 months ago
Can you test and review again please @masthoon?
I added some comments. I can't think of a way to wait for the debugger without using Windows specific code.
There is a issue with CREATE_SUSPENDED
process in case the thread is not resumed (for example: using invalid windbg command line argument or if windbg is not installed).
On exit, the tube atexit
callback will call process.close
that first calls poll()
then closes the file descriptors and finally stops the process. The problem is that the stdout fd.close
is blocking (I don't know why) thus Python
stops responding (even to ctrl+c) and it must be killed manually using Task Manager.
Reproduce with:
from pwn import *
process(['cmd.exe'], creationflags=4)
exit(0)
One way to fix this issue is to first terminate the process then close the file descriptors in process.close
:
# pwntools\pwnlib\tubes\process.py
def close(self):
if self.proc is None:
return
# First check if we are already dead
self.poll()
# Terminate before closing fd
if not self._stop_noticed:
try:
self.proc.kill()
self.proc.wait()
self._stop_noticed = time.time()
self.info('Stopped process %r (pid %i)' % (self.program, self.pid))
except OSError:
pass
# close file descriptors
for fd in [self.proc.stdin, self.proc.stdout, self.proc.stderr]:
if fd is not None:
try:
fd.close()
except IOError as e:
if e.errno != errno.EPIPE and e.errno != errno.EINVAL:
raise
Also resuming the process would work. I'm not sure if changing the cleanup order in 'process.close' would cause issues on other operating systems.
Maybe we can use psutil.Process.resume() to resume all threads in the process atexit, but that seems finicky.
Changing the order of killing and closing file descriptiors doesn't seem to matter. The file descriptors were closed in #576 and the testcase of starting and killing lots of processes still doesn't leave dangling file descriptors around when moving the closing after the killing of the process. So I think we can switch up the order and be fine on Linux too.
Currently only
windbg.debug()
andwindbg.attach()
are implemented, which open a WinDbg instance and attach to the process.