def _create_win_event(name): from winappdbg.win32.kernel32 import CreateEventA, WaitForSingleObject, CloseHandle manual_reset = False # i.e.: after someone waits it, automatically set to False. initial_state = False if not isinstance(name, bytes): name = name.encode('utf-8') event = CreateEventA(None, manual_reset, initial_state, name) if not event: raise ctypes.WinError() class _WinEvent(object): def wait_for_event_set(self, timeout=None): ''' :param timeout: in seconds ''' if timeout is None: timeout = 0xFFFFFFFF else: timeout = int(timeout * 1000) ret = WaitForSingleObject(event, timeout) if ret in (0, 0x80): return True elif ret == 0x102: # Timed out return False else: raise ctypes.WinError() try: yield _WinEvent() finally: CloseHandle(event)
def _win_write_to_shared_named_memory(python_code, pid): # Use the definitions from winappdbg when possible. from winappdbg.win32 import defines from winappdbg.win32.kernel32 import ( CreateFileMapping, MapViewOfFile, CloseHandle, UnmapViewOfFile, ) memmove = ctypes.cdll.msvcrt.memmove memmove.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, defines.SIZE_T, ] memmove.restype = ctypes.c_void_p # Note: BUFSIZE must be the same from run_code_in_memory.hpp BUFSIZE = 2048 assert isinstance(python_code, bytes) assert len(python_code) > 0, 'Python code must not be empty.' # Note: -1 so that we're sure we'll add a \0 to the end. assert len( python_code ) < BUFSIZE - 1, 'Python code must have at most %s bytes (found: %s)' % ( BUFSIZE - 1, len(python_code)) python_code += b'\0' * (BUFSIZE - len(python_code)) assert python_code.endswith(b'\0') INVALID_HANDLE_VALUE = -1 PAGE_READWRITE = 0x4 FILE_MAP_WRITE = 0x2 filemap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, BUFSIZE, u"__pydevd_pid_code_to_run__%s" % (pid, )) if filemap == INVALID_HANDLE_VALUE or filemap is None: raise Exception( "Failed to create named file mapping (ctypes: CreateFileMapping): %s" % (filemap, )) try: view = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0) if not view: raise Exception( "Failed to create view of named file mapping (ctypes: MapViewOfFile)." ) try: memmove(view, python_code, BUFSIZE) yield finally: UnmapViewOfFile(view) finally: CloseHandle(filemap)
def _acquire_mutex(mutex_name, timeout): ''' Only one process may be attaching to a pid, so, create a system mutex to make sure this holds in practice. ''' from winappdbg.win32.kernel32 import CreateMutex, GetLastError, CloseHandle from winappdbg.win32.defines import ERROR_ALREADY_EXISTS initial_time = time.time() while True: mutex = CreateMutex(None, True, mutex_name) acquired = GetLastError() != ERROR_ALREADY_EXISTS if acquired: break if time.time() - initial_time > timeout: raise TimeoutError('Unable to acquire mutex to make attach before timeout.') time.sleep(.2) try: yield finally: CloseHandle(mutex)