WIP: fixing handle 'leak' in dbg that require manual garbare collection for now

This commit is contained in:
hakril
2016-09-16 00:50:32 +02:00
committed by Clement Rouault
parent 861884099f
commit 03aec90d63
4 changed files with 50 additions and 4 deletions
+38 -3
View File
@@ -136,6 +136,7 @@ class Debugger(object):
def _killed_in_action(self):
"""Return ``True`` if current process have been detached by user callback"""
# Fix ? _handle_exit_process remove from processes but need a FinishDebugEvent
return self.current_process.pid not in self.processes
@@ -627,8 +628,6 @@ class Debugger(object):
thread_handle = HANDLE()
cp_handle = windows.current_process.handle
winproxy.DuplicateHandle(cp_handle, create_process.hProcess, cp_handle, ctypes.byref(proc_handle), dwOptions=DUPLICATE_SAME_ACCESS)
winproxy.DuplicateHandle(cp_handle, create_process.hThread, cp_handle, ctypes.byref(thread_handle), dwOptions=DUPLICATE_SAME_ACCESS)
@@ -659,6 +658,8 @@ class Debugger(object):
def _handle_exit_process(self, debug_event):
"""Handle EXIT_PROCESS_DEBUG_EVENT"""
self._update_debugger_state(debug_event)
print("Exit process !!!")
#import pdb;pdb.set_trace()
exit_process = debug_event.u.ExitProcess
retvalue = self.on_exit_process(exit_process)
del self.threads[self.current_thread.tid]
@@ -667,6 +668,36 @@ class Debugger(object):
del self._breakpoint_to_reput[self.current_thread.tid]
del self.processes[self.current_process.pid]
del self._watched_pages[self.current_process.pid]
del self._module_by_process[self.current_process.pid]
# GC EXPLORATION CODE
import gc
over = gc.get_referrers
under = gc.get_referents
####
cpid = self.current_process.pid
del self.current_thread
## This should trigger DEL of the self.current_process
#print("self.current_process WILL BE DELETED")
del self.current_process
#print("self.current_process DELETED")
if cpid == self.target.pid:
#del self.target
print("DEL TARGET")
del self.target
#import pdb;pdb.set_trace()
# This is like.. the WORST PATCH EVER
# I'am going to sleep so here the problem for when it will time to fix this:
# The PEFile class is a mess: too much cell arround target
# This means that destroying them is not enought to __del__ the target (dbg.current_process)
# So the dbg.current_process is still alive, so handle is also still alive..
# For now we need to force gc.collect
# This will need a rewrite of GetPEFile...
import gc; gc.collect()
return retvalue
def _handle_create_thread(self, debug_event):
@@ -744,7 +775,11 @@ class Debugger(object):
dbg_continue_flag = self._dispatch_debug_event(debug_event)
if dbg_continue_flag is None:
dbg_continue_flag = DBG_CONTINUE
if not self._killed_in_action():
if debug_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT or not self._killed_in_action():
#if not self._killed_in_action():
# should we always _finish_debug_event even if process was killed ?
# rhaaa _killed_in_action is a REALLY bad name, it's not killed, it's detached
# TODO: FIXME
self._finish_debug_event(debug_event, dbg_continue_flag)
if not self.processes:
break
+5
View File
@@ -171,6 +171,11 @@ def GetPEFile(baseaddr, target=None, force_bitness=None):
class PEFile(object):
"""Represent a PE loaded in a process (current or remote)"""
#def __del__(self):
# print("YOLODEL")
# import pprint
# pprint.pprint(vars(self))
def __init__(self):
self.baseaddr = baseaddr
self.bitness = targetedbitness
+4 -1
View File
@@ -48,7 +48,10 @@ class Handle(SYSTEM_HANDLE):
size_needed = DWORD()
try:
winproxy.NtQueryObject(lh, ObjectTypeInformation, ctypes.byref(xxx), ctypes.sizeof(xxx), ctypes.byref(size_needed))
except Exception as e:
except WindowsError as e:
if e.code != STATUS_INFO_LENGTH_MISMATCH:
print("ERROR WITH {0:x}".format(lh))
raise
size = size_needed.value
buffer = ctypes.c_buffer(size)
winproxy.NtQueryObject(lh, ObjectTypeInformation, buffer, size, ctypes.byref(size_needed))
+3
View File
@@ -48,6 +48,9 @@ class AutoHandle(object):
return self._handle
self._handle = self._get_handle()
dbgprint("Open handle {0} for {1}".format(hex(self._handle), self), "HANDLE")
#if "DEAD" in str(self):
# print("OPEN FOR THE DEADS")
# import pdb;pdb.set_trace()
return self._handle
def wait(self, timeout=INFINITE):