Ejemplo n.º 1
0
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)
Ejemplo n.º 3
0
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)