Exemplo n.º 1
0
def _create_event():
    """
    Creates a Win32 unnamed Event .

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx
    """
    return windll.kernel32.CreateEventA(pointer(SECURITY_ATTRIBUTES()), BOOL(True), BOOL(False), None)
Exemplo n.º 2
0
    def __init__(self, pipe_name, read_callback, done_callback):
        self.pipe_name = pipe_name
        self.read_callback = read_callback
        self.done_callback = done_callback
        self.done = False

        self.handle = windll.kernel32.CreateFileW(pipe_name, GENERIC_READ, 0,
                                                  None, OPEN_EXISTING,
                                                  FILE_FLAG_OVERLAPPED, None)

        if self.handle == INVALID_HANDLE_VALUE:
            error_code = windll.kernel32.GetLastError()
            raise Exception('Invalid pipe handle. Error code=%r.' % error_code)

        # Create overlapped structure and event.
        self._overlapped = OVERLAPPED()
        self._event = windll.kernel32.CreateEventA(
            None,  # Default security attributes.
            BOOL(True),  # Manual reset event.
            BOOL(True),  # initial state = signaled.
            None  # Unnamed event object.
        )
        self._overlapped.hEvent = self._event

        self._reading = Event()

        # Start reader coroutine.
        ensure_future(self._async_reader())
Exemplo n.º 3
0
 def InsertHandle(self, handle, callback):
     if handle is None:
         CreateEventW = ctypes.windll.kernel32.CreateEventW
         CreateEventW.restype = HANDLE
         handle = CreateEventW(None, BOOL(), BOOL(), None)
         if not handle:
             raise ctypes.WinError()
     self.waitables[handle] = callback
     return handle
Exemplo n.º 4
0
def create_win32_event():
    """
    Creates a Win32 unnamed Event .
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx
    """
    return windll.kernel32.CreateEventA(
        pointer(SECURITY_ATTRIBUTES()),
        BOOL(True),  # Manual reset event.
        BOOL(False),  # Initial state.
        None  # Unnamed event object.
    )
Exemplo n.º 5
0
def create_event():
    """
    Create Win32 event.
    """
    event = windll.kernel32.CreateEventA(
        None,  # Default security attributes.
        BOOL(True),  # Manual reset event.
        BOOL(True),  # Initial state = signaled.
        None  # Unnamed event object.
    )
    if not event:
        raise Exception('event creation failed.')
    return event
Exemplo n.º 6
0
def GetProcessName(hwnd):
    if not isinstance(hwnd, HWND):
        hwnd = HWND(hwnd)

    lpdwProcessId = DWORD()
    _GetWindowThreadProcessId(hwnd, ctypes.byref(lpdwProcessId))

    hProcess = _OpenProcess(DWORD(PROCESS_QUERY_INFORMATION), BOOL(False),
                            lpdwProcessId)

    lpdwSize = DWORD(MAX_PATH)

    lpExeName = ctypes.create_string_buffer(MAX_PATH)
    _QueryFullProcessImageName(hProcess, DWORD(0), lpExeName,
                               ctypes.byref(lpdwSize))

    if sys.version_info[0] == 2:
        res = ''
    else:
        res = b''

    for i in range(260):
        if sys.version_info[0] == 2:
            if lpExeName[i] == '\x00':
                continue
        else:
            if lpExeName[i] == b'\x00':
                continue

        res += lpExeName[i]

    if res:
        res = os.path.split(res)[-1]
    return res
Exemplo n.º 7
0
def write_message_bytes_to_pipe(pipe_handle, data):
    overlapped = OVERLAPPED()
    overlapped.hEvent = create_event()

    try:
        c_written = DWORD()

        success = windll.kernel32.WriteFile(pipe_handle,
                                            create_string_buffer(data),
                                            len(data), byref(c_written),
                                            byref(overlapped))

        if success:
            return

        error_code = windll.kernel32.GetLastError()
        if error_code == ERROR_IO_PENDING:
            yield From(wait_for_event(overlapped.hEvent))

            success = windll.kernel32.GetOverlappedResult(
                pipe_handle, byref(overlapped), byref(c_written), BOOL(False))

            if not success:
                error_code = windll.kernel32.GetLastError()
                if error_code == ERROR_BROKEN_PIPE:
                    raise BrokenPipeError
                else:
                    raise Exception(
                        'Writing overlapped IO failed. error_code=%r' %
                        error_code)

        elif error_code == ERROR_BROKEN_PIPE:
            raise BrokenPipeError
    finally:
        windll.kernel32.CloseHandle(overlapped.hEvent)
Exemplo n.º 8
0
def wait_for_handles(handles: List[HANDLE],
                     timeout: int = INFINITE) -> Optional[HANDLE]:
    """
    Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
    Returns `None` on timeout.
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

    Note that handles should be a list of `HANDLE` objects, not integers. See
    this comment in the patch by @quark-zju for the reason why:

        ''' Make sure HANDLE on Windows has a correct size

        Previously, the type of various HANDLEs are native Python integer
        types. The ctypes library will treat them as 4-byte integer when used
        in function arguments. On 64-bit Windows, HANDLE is 8-byte and usually
        a small integer. Depending on whether the extra 4 bytes are zero-ed out
        or not, things can happen to work, or break. '''

    This function returns either `None` or one of the given `HANDLE` objects.
    (The return value can be tested with the `is` operator.)
    """
    arrtype = HANDLE * len(handles)
    handle_array = arrtype(*handles)

    ret: int = windll.kernel32.WaitForMultipleObjects(len(handle_array),
                                                      handle_array,
                                                      BOOL(False),
                                                      DWORD(timeout))

    if ret == WAIT_TIMEOUT:
        return None
    else:
        return handles[ret]
Exemplo n.º 9
0
def GetProcessName(hwnd):
    if not isinstance(hwnd, HWND):
        hwnd = HWND(hwnd)

    lpdwProcessId = DWORD()
    _GetWindowThreadProcessId(hwnd, ctypes.byref(lpdwProcessId))

    hProcess = _OpenProcess(
        DWORD(PROCESS_QUERY_INFORMATION),
        BOOL(False),
        lpdwProcessId
    )

    lpdwSize = DWORD(MAX_PATH)
    lpExeName = ctypes.create_string_buffer(MAX_PATH)

    _QueryFullProcessImageName(
        hProcess,
        DWORD(0),
        lpExeName,
        ctypes.byref(lpdwSize)
    )

    res = str(lpExeName)

    if res:
        res = os.path.split(res)[-1]
    return res
Exemplo n.º 10
0
    def __init__(self, pid, auto_eject=True):
        self.id = pid
        self.handle = OpenProcess(
            PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE
            | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION, False, pid)
        self.injected = {}
        self.auto_eject = auto_eject

        if not self.handle:
            raise WinError()

        if IsWow64Process is None:
            self.bits = 32
        else:
            wow64 = BOOL()

            if not IsWow64Process(self.handle, byref(wow64)):
                raise WinError()

            if wow64:
                self.bits = 32
            else:
                self.bits = 64

        assert self.bits == 32 or sys.maxsize > 2**32
Exemplo n.º 11
0
def fop(files):
    import ctypes
    from ctypes.wintypes import HWND, UINT, LPCWSTR, BOOL

    class SHFILEOPSTRUCTW(ctypes.Structure):
        _fields_ = [
            ("hwnd", HWND),
            ("wFunc", UINT),
            ("pFrom", LPCWSTR),
            ("pTo", LPCWSTR),
            ("fFlags", ctypes.c_uint),
            ("fAnyOperationsAborted", BOOL),
            ("hNameMappings", ctypes.c_uint),
            ("lpszProgressTitle", LPCWSTR),
        ]

    SHFileOperationW = ctypes.windll.shell32.SHFileOperationW
    SHFileOperationW.argtypes = [ctypes.POINTER(SHFILEOPSTRUCTW)]
    pFrom = u'\x00'.join(files) + u'\x00'
    args = SHFILEOPSTRUCTW(wFunc=UINT(3),
                           pFrom=LPCWSTR(pFrom),
                           pTo=None,
                           fFlags=64,
                           fAnyOperationsAborted=BOOL())
    out = SHFileOperationW(ctypes.byref(args))
Exemplo n.º 12
0
def windowsExit():
    global stopped, running, sentReport
    if not stopped:
        stopped = True
        print("Exiting...")
        windows_utils.SetConsoleCtrlHandler(None, BOOL(True))
        if not sentReport:
            print("Waiting for report descriptor to be sent first")
            t = time()
            while time() < t + 15 and not sentReport:
                sleep(1)
            if sentReport:
                print("Ready to uninstall")
            sleep(1)
            if not sentReport:
                print(
                    "Report still not sent. There may be some difficulties in disconnecting."
                )

        running = False
        usb_container.running = False
        usb_container.detach()
        print("Bye!")
        windows_utils.ExitProcess(0)
        return False
    return True
Exemplo n.º 13
0
    def __init__(self,
                 process_id: int,
                 inherit_handle: bool = False,
                 desired_access: int = PROCESS_ALL_ACCESS):
        """
        Attempt to open a handle for the given PID with requested access level.

        Raises a WinError if it fails.

        see msdn doc for OpenProcess for more information about process handles.

        :param process_id: the id of the process to open
        :param inherit_handle: whether children should inherit permissions
        :param desired_access: a windows flag specifying

        """
        super().__init__()
        self._id = process_id
        self._inherit_handle = inherit_handle
        self._desired_access = PROCESS_ALL_ACCESS

        self._handle = _open_process(DWORD(desired_access),
                                     BOOL(inherit_handle), DWORD(process_id))

        @property
        def pid(self) -> int:
            return self._id
Exemplo n.º 14
0
def is64bitProc(process_handle):
    is64 = BOOL()
    res = IsWow64Process(process_handle, ctypes.byref(is64))
    if res == 0:
        logging.warning('Failed to get process version info!')
        WinError(get_last_error())
    return not bool(is64.value)
Exemplo n.º 15
0
def kill_pid(pid):
    K32DLL.OpenProcess.restype = HANDLE
    handle = K32DLL.OpenProcess(PROCESS_TERMINATE, BOOL(False), DWORD(pid))
    try:
        exit_status = ctypes.c_int32()
        K32DLL.TerminateProcess(handle, byref(exit_status))
    finally:
        K32DLL.CloseHandle(handle)
Exemplo n.º 16
0
def can_get_admin_access():
    """
    Check if the user may be able to get administrator access.
    Returns True if the user is in the administrator's group.
    Otherwise returns False
    """
    SECURITY_MAX_SID_SIZE = 68
    WinBuiltinAdministratorsSid = 26
    ERROR_NO_SUCH_LOGON_SESSION = 1312
    ERROR_PRIVILEGE_NOT_HELD = 1314
    TokenLinkedToken = 19

    # On XP or lower this is equivalent to has_root()
    # Note: sys.getwindowsversion() does work on every system
    if sys.getwindowsversion()[0] < 6:
        return bool(IsUserAnAdmin())

    # On Vista or higher, there's the whole UAC token-splitting thing.
    # Many thanks for Junfeng Zhang for the workflow: htttp://blogs.msdn.com/junfeng/archive/2007/01/26/how-to-tell-if-the-current-user-is-in-administrators-group-programmatically.aspx

    # Get the token for the current process.
    proc = GetCurrentProcess()
    try:
        token = HANDLE()
        OpenProcessToken(proc, TOKEN_QUERY, byref(token))
        try:
            # Get the administrators SID.
            sid = create_string_buffer(SECURITY_MAX_SID_SIZE)
            sz = DWORD(SECURITY_MAX_SID_SIZE)
            target_sid = WinBuiltinAdministratorsSid
            CreateWellKnownSid(target_sid, None, byref(sid), byref(sz))
            # Check whether the token has that SID directly.
            has_admin = BOOL()
            CheckTokenMembership(None, byref(sid), byref(has_admin))
            if has_admin.value:
                return True
            # Get the linked token.  Failure may mean no linked token.
            lToken = HANDLE()
            try:
                cls = TokenLinkedToken
                GetTokenInformation(token, cls, byref(lToken), sizeof(lToken),
                                    byref(sz))
            except WindowsError, e:
                if e.winerror == ERROR_NO_SUCH_LOGON_SESSION:
                    return False
                elif e.winerror == ERROR_PRIVILEGE_NOT_HELD:
                    return False
                else:
                    raise
            # Check if the linked token has the admin SID
            try:
                CheckTokenMembership(lToken, byref(sid), byref(has_admin))
                return bool(has_admin.value)
            finally:
                CloseHandle(lToken)
        finally:
            CloseHandle(token)
Exemplo n.º 17
0
def read_message_bytes_from_pipe(pipe_handle):
    """
    (coroutine)
    Read message from this pipe. Return bytes.
    """
    overlapped = OVERLAPPED()
    overlapped.hEvent = create_event()

    try:
        buff = create_string_buffer(BUFSIZE + 1)
        c_read = DWORD()

        success = windll.kernel32.ReadFile(pipe_handle, buff, DWORD(BUFSIZE),
                                           byref(c_read), byref(overlapped))

        if success:
            buff[c_read.value] = b'\0'
            raise Return(buff.value)

        error_code = windll.kernel32.GetLastError()

        if error_code == ERROR_IO_PENDING:
            yield From(wait_for_event(overlapped.hEvent))

            success = windll.kernel32.GetOverlappedResult(
                pipe_handle, byref(overlapped), byref(c_read), BOOL(False))

            if success:
                buff[c_read.value] = b'\0'
                raise Return(buff.value)

            else:
                error_code = windll.kernel32.GetLastError()
                if error_code == ERROR_BROKEN_PIPE:
                    raise BrokenPipeError

                elif error_code == ERROR_MORE_DATA:
                    more_data = yield From(
                        read_message_bytes_from_pipe(pipe_handle))
                    raise Return(buff.value + more_data)
                else:
                    raise Exception(
                        'reading overlapped IO failed. error_code=%r' %
                        error_code)

        elif error_code == ERROR_BROKEN_PIPE:
            raise BrokenPipeError

        elif error_code == ERROR_MORE_DATA:
            more_data = yield From(read_message_bytes_from_pipe(pipe_handle))
            raise Return(buff.value + more_data)

        else:
            raise Exception('Reading pipe failed, error_code=%s' % error_code)
    finally:
        windll.kernel32.CloseHandle(overlapped.hEvent)
Exemplo n.º 18
0
 def __init__(self, dwProcessId):
     self.is_open = False
     self.hProcess = NULL
     self.dwProcessId = dwProcessId
     self.bInheritHandle = BOOL(False)
     self.dwDesiredAccess = DWORD(
         PROCESS_QUERY_INFORMATION |
         PROCESS_VM_READ |
         PROCESS_TERMINATE
     )
Exemplo n.º 19
0
def get_colorization_color():
    dwmapi = WinDLL("dwmapi", use_last_error=True)
    DwmGetColorizationColor = dwmapi.DwmGetColorizationColor
    DwmGetColorizationColor.restype = c_int
    DwmGetColorizationColor.argtypes = [PDWORD, PBOOL]
    color = DWORD()
    opaque = BOOL()
    r = DwmGetColorizationColor(byref(color), byref(opaque))
    log("DwmGetColorizationColor(..)=%i", r)
    if r:
        return None
    return color.value
Exemplo n.º 20
0
 def InsertHandle(self, handle, callback):
     """InsertHandle(handle, callback) -> handle
     Insert a handle to a waitable object.
     
     If 'handle' is None, a new event object will be created.
     
     The 'callback' is a class instance with the following function defined:
     def OnObjectSignaled(self, handle, abandoned)
     
     If 'abandoned' is False, the 'handle' is signaled.
     
     A weak reference to the callback is held, so if the  callback function is destroyed,
     the handle is removed from the waitables list as well.
     """
     if handle is None:
         CreateEventW = ctypes.windll.kernel32.CreateEventW
         CreateEventW.restype = HANDLE
         handle = CreateEventW(None, BOOL(), BOOL(), None)
         if not handle:
             raise ctypes.WinError()
     self.waitables[handle] = callback
     return handle
Exemplo n.º 21
0
def open_event(event_name: str,
               desired_access: int = EVENT_ALL_ACCESS,
               inherit_handle: bool = False) -> HANDLE:
    """
    Attempts to open an event object with the given name at the requested access level.

    The name must easily convert to ascii.

    :param event_name: a name to open. must be convertible to ascii
    :param desired_access:
    :param inherit_handle: whether child processes get access to the handle.
    :return: a handle for the event if successful
    """
    return _open_event(DWORD(desired_access), BOOL(inherit_handle),
                       LPCSTR(bytes(event_name, 'ASCII')))
Exemplo n.º 22
0
def RtlAdjustPrivilege(privilige_id, enable = True, thread_or_process = False):
	"""
	privilige_id: int
	"""
	_RtlAdjustPrivilege = windll.ntdll.RtlAdjustPrivilege
	_RtlAdjustPrivilege.argtypes = [ULONG, BOOL, BOOL, POINTER(BOOL)]
	_RtlAdjustPrivilege.restype = NTSTATUS
	
	CurrentThread = thread_or_process # enable for whole process
	Enabled = BOOL()
	
	status = _RtlAdjustPrivilege(privilige_id, enable, CurrentThread, ctypes.byref(Enabled))
	if status != STATUS_SUCCESS:
		raise Exception(NtError(status))
	
	return True
Exemplo n.º 23
0
def EnumProcesses():
    buf_count = 256
    while True:
        buf = (DWORD * buf_count)()
        buf_size = DWORD(0)
        buf_size = sizeof(buf)
        res_size = DWORD(0)
        res = BOOL()
        res = Psapi.EnumProcesses(byref(buf), buf_size, byref(res_size))
        if not res:
            raise OSError('EnumProcesses failed')
        if res_size.value >= buf_size:
            buf_count *= 2
            continue
        count = res_size.value // (buf_size // buf_count)
        return buf[:count]
Exemplo n.º 24
0
def wait_for_handles(handles: List[int], timeout: int = INFINITE) -> Optional[HANDLE]:
    """
    Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
    Returns `None` on timeout.
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
    """
    arrtype = HANDLE * len(handles)
    handle_array = arrtype(*handles)

    ret = windll.kernel32.WaitForMultipleObjects(
        len(handle_array), handle_array, BOOL(False), DWORD(timeout))

    if ret == WAIT_TIMEOUT:
        return None
    else:
        h = handle_array[ret]
        return h
Exemplo n.º 25
0
def main(pid=None):
    PROCESS_TERMINATE = 0x0001
    PROCESS_QUERY_INFORMATION = 0x0400
    JOB_OBJECT_ALL_ACCESS = 0x1F001F
    hProc = HANDLE()
    result = BOOL()
    kernel32 = windll.kernel32
    hProc = kernel32.OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION,
                                 None, pid)
    hJobObject = kernel32.OpenJobObjectW(JOB_OBJECT_ALL_ACCESS, 1,
                                         LPCWSTR("fuzzjob"))
    if hJobObject == None:
        # this process is not in the fuzzjob, bail
        exit()
    kernel32.IsProcessInJob(hProc, hJobObject, byref(result))
    if result.value:
        kernel32.TerminateJobObject(hJobObject, 0xC0000005)
Exemplo n.º 26
0
def EnumProcessModulesEx(hProcess):
    buf_count = 256
    LPDWORD
    while True:
        buf = (HMODULE * buf_count)()
        buf_size = DWORD(sizeof(buf))
        needed = DWORD(0)
        res = BOOL()
        res = Psapi.EnumProcessModulesEx(hProcess, byref(buf), buf_size,
                                         byref(needed), LIST_MODULES_ALL)
        if not res:
            raise OSError('EnumProcessModulesEx failed')
        if buf_size < needed.value:
            buf_count = needed.value // (buf_size // buf_count)
            continue
        count = needed.value // (buf_size // buf_count)
        return map(HMODULE, buf[:count])
Exemplo n.º 27
0
def RtlAdjustPrivilege(privilige_id, enable=True, thread_or_process=False):
    """
	privilige_id: int
	"""
    _RtlAdjustPrivilege = windll.ntdll.RtlAdjustPrivilege
    _RtlAdjustPrivilege.argtypes = [ULONG, BOOL, BOOL, POINTER(BOOL)]
    _RtlAdjustPrivilege.restype = NTSTATUS

    CurrentThread = thread_or_process  #False = enable for whole process, True = current thread only
    Enabled = BOOL()

    status = _RtlAdjustPrivilege(privilige_id, enable, CurrentThread,
                                 ctypes.byref(Enabled))
    if status != 0:
        raise Exception('Failed call to RtlAdjustPrivilege! Status: %s' %
                        status)

    return Enabled.value
Exemplo n.º 28
0
def RtlAdjustPrivilege():
    NTSTATUS = LONG
    POINTER = c.POINTER
    SE_DEBUG = 20
    STATUS_SUCCESS = 0
    _RtlAdjustPrivilege = windll.ntdll.RtlAdjustPrivilege
    _RtlAdjustPrivilege.argtypes = [ULONG, BOOL, BOOL, POINTER(BOOL)]
    _RtlAdjustPrivilege.restype = NTSTATUS

    Enabled = BOOL()

    status = _RtlAdjustPrivilege(SE_DEBUG, True, False, c.byref(Enabled))
    if status == STATUS_SUCCESS:
        print("Enable debug privilege successfully")
    else:
        print(
            "Fail to enable debug privilege, check your privilege is admin or not"
        )

    return True
Exemplo n.º 29
0
def WinStationConnect(hServer,
                      SessionID,
                      TargetSessionID,
                      Password="",
                      Wait=False):
    if hServer is None:
        hServer = win32ts.WTS_CURRENT_SERVER_HANDLE

    if SessionID is None:
        SessionID = win32ts.WTS_CURRENT_SESSION

    if TargetSessionID is None:
        TargetSessionID = win32ts.WTS_CURRENT_SESSION

    res = winsta.WinStationConnectW(HANDLE(hServer), ULONG(SessionID),
                                    ULONG(TargetSessionID),
                                    LPWSTR(Password or ""), BOOL(Wait))

    if res != 1:
        raise Win32Error(func="WinStationConnect")
Exemplo n.º 30
0
    def _async_reader(self):
        buffer_size = 65536
        c_read = DWORD()
        buffer = ctypes.create_string_buffer(buffer_size + 1)

        while True:
            # Wait until `start_reading` is called.
            yield From(self._reading.wait())

            # Call read.
            success = windll.kernel32.ReadFile(self.handle, buffer,
                                               DWORD(buffer_size),
                                               ctypes.byref(c_read),
                                               ctypes.byref(self._overlapped))

            if success:
                buffer[c_read.value] = b'\0'
                self.read_callback(buffer.value.decode('utf-8', 'ignore'))

            else:
                error_code = windll.kernel32.GetLastError()
                # Pending I/O. Wait for it to finish.
                if error_code == ERROR_IO_PENDING:
                    # Wait for event.
                    yield From(self._wait_for_event())

                    # Get pending data.
                    success = windll.kernel32.GetOverlappedResult(
                        self.handle, ctypes.byref(self._overlapped),
                        ctypes.byref(c_read), BOOL(False))

                    if success:
                        buffer[c_read.value] = b'\0'
                        self.read_callback(
                            buffer.value.decode('utf-8', 'ignore'))

                elif error_code == ERROR_BROKEN_PIPE:
                    self.stop_reading()
                    self.done_callback()
                    self.done = False
                    return