Fix some handle leak, debugger close hFile on event + enumerate processes/threads close snap handle

This commit is contained in:
Clement Rouault
2017-04-26 14:46:45 +02:00
parent feb76b48c3
commit c0d03a2f58
5 changed files with 53 additions and 12 deletions
+8 -3
View File
@@ -674,8 +674,10 @@ class Debugger(object):
self._setup_pending_breakpoints_new_process(self.current_process)
self._setup_pending_breakpoints_new_thread(self.current_thread)
with self.DisabledMemoryBreakpoint():
return self.on_create_process(create_process)
# TODO: close hFile
try:
return self.on_create_process(create_process)
finally:
winproxy.CloseHandle(create_process.hFile)
def _handle_exit_process(self, debug_event):
"""Handle EXIT_PROCESS_DEBUG_EVENT"""
@@ -745,7 +747,10 @@ class Debugger(object):
self._module_by_process[self.current_process.pid][dll_name] = windows.pe_parse.GetPEFile(load_dll.lpBaseOfDll, self.current_process)
self._setup_pending_breakpoints_load_dll(dll_name)
with self.DisabledMemoryBreakpoint():
return self.on_load_dll(load_dll)
try:
return self.on_load_dll(load_dll)
finally:
winproxy.CloseHandle(load_dll.hFile)
def _handle_unload_dll(self, debug_event):
"""Handle UNLOAD_DLL_DEBUG_EVENT"""
+3 -5
View File
@@ -17,8 +17,8 @@ class SystemTestCase(unittest.TestCase):
@check_for_gc_garbage
def test_version_name(self):
return windows.system.version_name
@check_for_gc_garbage
def test_computer_name(self):
return windows.system.computer_name
@@ -32,10 +32,7 @@ class SystemTestCase(unittest.TestCase):
return windows.system.logicaldrives
@check_for_gc_garbage
def test_processes(self):
return windows.system.processes
@check_for_gc_garbage
@check_for_handle_leak
def test_threads(self):
return windows.system.threads
@@ -44,6 +41,7 @@ class SystemTestCase(unittest.TestCase):
return windows.system.wmi.select("Win32_Process", "*")
@check_for_gc_garbage
@check_for_handle_leak
def test_processes(self):
procs = windows.system.processes
self.assertIn(windows.current_process.pid, [p.pid for p in procs])
+36 -2
View File
@@ -88,11 +88,45 @@ def check_for_gc_garbage(f):
return wrapper
def check_for_handle_leak(f):
def wrapper(testcase, *args, **kwargs):
current_process_hdebugger.refresh_handles()
res = f(testcase, *args, **kwargs)
leaked_handles = current_process_hdebugger.get_new_handle()
testcase.assertFalse(leaked_handles, "Test Leaked <{0}> handles of types ({1})".format(len(leaked_handles), set(h.type for h in leaked_handles)))
return res
return wrapper
def print_call(f):
def wrapper(*args, **kwargs):
res = f(*args, **kwargs)
print("Call to <{0}>({1}) returned <{2}>".format(f.func_name, (args, kwargs), res))
return res
return wrapper
return wrapper
class HandleDebugger(object):
def __init__(self, pid):
self.pid = pid
self.handles = 0
def refresh_handles(self):
self.handles = self.get_handles()
def get_handles(self):
tpid = self.pid
return [h for h in windows.system.handles if h.dwProcessId == tpid]
def get_new_handle(self):
nh = self.get_handles()
handle_diff = set(h.wValue for h in nh) - set(h.wValue for h in self.handles)
return [h for h in nh if h.wValue in handle_diff]
def handles_types(self, hlist):
return set(h.type for h in hlist)
def print_new_handle_type(self):
print(self.handles_types(self.get_new_handle()))
current_process_hdebugger = HandleDebugger(windows.current_process.pid)
+3 -1
View File
@@ -1,3 +1,4 @@
import os
import ctypes
import windows
@@ -9,6 +10,7 @@ from windows.generated_def.winstructs import *
class EPUBLIC_OBJECT_TYPE_INFORMATION(ctypes.Structure):
_fields_ = windows.utils.transform_ctypes_fields(PUBLIC_OBJECT_TYPE_INFORMATION, {"TypeName": windows.winobject.process.WinUnicodeString})
current_process_pid = os.getpid()
class Handle(SYSTEM_HANDLE):
"""A handle of the system"""
@@ -86,7 +88,7 @@ class Handle(SYSTEM_HANDLE):
return "<{0} value=<0x{1:x}> in process pid={2}>".format(type(self).__name__, self.wValue, self.dwProcessId)
def __del__(self):
if self.dwProcessId == windows.current_process.pid:
if self.dwProcessId == current_process_pid:
return
if hasattr(self, "_local_handle"):
return winproxy.CloseHandle(self._local_handle)
+3 -1
View File
@@ -210,6 +210,7 @@ class System(object):
res.append(process.WinProcess._from_PROCESSENTRY32(process_entry))
while winproxy.Process32Next(snap, process_entry):
res.append(process.WinProcess._from_PROCESSENTRY32(process_entry))
winproxy.CloseHandle(snap)
return res
@staticmethod
@@ -222,4 +223,5 @@ class System(object):
threads.append(copy.copy(thread_entry))
while winproxy.Thread32Next(snap, thread_entry):
threads.append(copy.copy(thread_entry))
return threads
winproxy.CloseHandle(snap)
return threads