Error attaching to suspended process
Hi Marito! I'm trying to start a suspended process and attaching to it after the creation, but an error occurs when the attach method (in debug.py) calls scan_modules (the error occurs calling CreateTool32Snapshot function). I've work around it commenting lines call functions scan_modules and scan_threads, but would be great if you can add an option to call, or not, scan_modules (and scan_threads).
Message error is the following:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python27\Lib\threading.py", line 530, in __bootstrap_inner
self.run()
File "C:\Python27\Lib\threading.py", line 483, in run
self.__target(*self.__args, **self.__kwargs)
File "reporte_marito.py", line 37, in _run
aProcess = debug.attach( dwProcessId )
File "c:\Python27\lib\site-packages\winappdbg\debug.py", line 269, in attach
aProcess.scan_modules()
File "c:\Python27\lib\site-packages\winappdbg\module.py", line 1059, in scan_m
odules
dwProcessId) as hSnapshot:
File "c:\Python27\lib\site-packages\winappdbg\win32\kernel32.py", line 4239, i
n CreateToolhelp32Snapshot
raise ctypes.WinError()
WindowsError: [Error 299] Only part of a ReadProcessMemory or WriteProcessMemory
request was completed.
This is the POC to reproduce the issue:
import winappdbg
from winappdbg import EventHandler, HexDump, Disassembler
import time
from multiprocessing import Queue
import win32process
from threading import Thread
import struct
class DebuggingParams:
Q_FROM_PARENT = None
Q_TO_PARENT = None
class DebuggingSession:
def __init__(self, parent_to_child, child_to_parent):
DebuggingParams.Q_FROM_PARENT = parent_to_child
DebuggingParams.Q_TO_PARENT = child_to_parent
def run(self):
# this function will create an thread to start and kill the acro process
t = Thread(target=self._run)
t.start()
def _run(self):
# Instance a Debug object.
debug = winappdbg.Debug()
try:
from_parent = DebuggingParams.Q_FROM_PARENT
to_parent = DebuggingParams.Q_TO_PARENT
#wait for event start process
dwProcessId = from_parent.get(block=True)
# Attach to a running process.
print "[-] Attaching to process"
aProcess = debug.attach( dwProcessId )
#send attach ok! to parent
to_parent.put(True)
# Make sure the debugees die if the debugger dies unexpectedly
debug.system.set_kill_on_exit_mode(True)
#wait resume thread!
from_parent.get(block=True)
# Wait for the debugee to finish.
print "[-] Running Process"
debug.loop()
# Stop the debugger.
finally:
debug.stop()
to_parent.put(True)
parent_to_child = Queue()
child_to_parent = Queue()
#create processs
commandLine = "C:\Windows\System32\calc.exe"
si = win32process.STARTUPINFO()
flags = win32process.CREATE_SUSPENDED
print "[*] Creating Debugging session"
ds = DebuggingSession(parent_to_child, child_to_parent)
ds.run()
print "[*] Creating Process"
(_handle, _thandle, _pid, i2) = win32process.CreateProcess(None, commandLine, None, None, 0, flags, None, '.', si)
#waiting creation
time.sleep(0.2)
#send pid
parent_to_child.put(_pid)
#wait for attach
child_to_parent.get(block=True)
print "[*] Resuming Thread"
win32process.ResumeThread(_thandle)
#thread resumed
parent_to_child.put(True)
#wait process finish
child_to_parent.get(block=True)
Hi! Sorry for not working on this at all for so long, but to be honest, it's such a weird corner case... no debugger actually does this, you're supposed to start the process from the debugger itself (so it's automatically attached) rather than manually starting the process in a suspended state, then try to attach before the process has had a chance to initialize its modules. :(