Ejemplo n.º 1
0
    def accept_connection(self, msg, port_attr=None, port_context=None):
        """Accept the connection for a ``LPC_CONNECTION_REQUEST`` message.
            ``msg.MessageId`` must be the same as the connection requesting message.

            :param AlpcMessage msg: The response message.
            :param ALPC_PORT_ATTRIBUTES port_attr: The attributes of the port, one with default value will be used if this parameter is ``None``
            :param PVOID port_context: A value that will be copied in ``ALPC_CONTEXT_ATTR.PortContext`` of every message on this connection.

        """
        rhandle = gdef.HANDLE()

        if port_attr is None:
            port_attr = gdef.ALPC_PORT_ATTRIBUTES()
            port_attr.Flags = 0x80000
            # port_attr.Flags = 0x80000 + 0x2000000
            # port_attr.Flags =  0x2000000
            port_attr.MaxMessageLength = DEFAULT_MESSAGE_SIZE
            port_attr.MemoryBandwidth = 0
            port_attr.MaxPoolUsage = 0xffffffff
            port_attr.MaxSectionSize = 0xffffffff
            port_attr.MaxViewSize = 0xffffffff
            port_attr.MaxTotalSectionSize = 0xffffffff
            port_attr.DupObjectTypes = 0xffffffff
        # windows.utils.print_ctypes_struct(port_attr, "   - CONN_PORT_ATTR", hexa=True)
        winproxy.NtAlpcAcceptConnectPort(rhandle, self.handle, 0, None,
                                         port_attr, port_context,
                                         msg.port_message, None, True)
        self.communication_port_list.append(rhandle.value)
        return msg
Ejemplo n.º 2
0
 def create_port_section(self, Flags, SectionHandle, SectionSize):
     AlpcSectionHandle = gdef.HANDLE()
     ActualSectionSize = gdef.SIZE_T()
     # RPCRT4 USE FLAGS 0x40000 ALPC_VIEWFLG_NOT_SECURE ?
     winproxy.NtAlpcCreatePortSection(self.handle, Flags, SectionHandle,
                                      SectionSize, AlpcSectionHandle,
                                      ActualSectionSize)
     return AlpcSection(AlpcSectionHandle.value, ActualSectionSize.value)
Ejemplo n.º 3
0
    def connect_to_port(self, port_name, connect_message=None,
                                port_attr=None, port_attr_flags=0x10000, obj_attr=None,
                                flags=gdef.ALPC_MSGFLG_SYNC_REQUEST, timeout=None):
        """Connect to the ALPC port ``port_name``. Most of the parameters have defauls value is ``None`` is passed.

            :param AlpcMessage connect_message: The message send with the connection request, if not ``None`` the function will return an :class:`AlpcMessage`
            :param ALPC_PORT_ATTRIBUTES port_attr: The port attributes, one with default value will be used if this parameter is ``None``
            :param int port_attr_flags: ``ALPC_PORT_ATTRIBUTES.Flags`` used if ``port_attr`` is ``None`` (MUTUALY EXCLUSINVE WITH ``port_attr``)
            :param OBJECT_ATTRIBUTES obj_attr: The attributes of the port (can be None)
            :param int flags: The flags for :func:`NtAlpcConnectPort`
            :param int timeout: The timeout of the request
        """
        # TODO raise on mutual exclusive parameter
        if self.handle is not None:
            raise ValueError("Client already connected")
        handle = gdef.HANDLE()
        port_name_unicode = self._alpc_port_to_unicode_string(port_name)

        if port_attr is None:
            port_attr = gdef.ALPC_PORT_ATTRIBUTES()
            port_attr.Flags = port_attr_flags # Flag qui fonctionne pour l'UAC
            port_attr.MaxMessageLength = self.DEFAULT_MAX_MESSAGE_LENGTH
            port_attr.MemoryBandwidth = 0
            port_attr.MaxPoolUsage = 0xffffffff
            port_attr.MaxSectionSize = 0xffffffff
            port_attr.MaxViewSize = 0xffffffff
            port_attr.MaxTotalSectionSize = 0xffffffff
            port_attr.DupObjectTypes = 0xffffffff

            port_attr.SecurityQos.Length = ctypes.sizeof(port_attr.SecurityQos)
            port_attr.SecurityQos.ImpersonationLevel = gdef.SecurityImpersonation
            port_attr.SecurityQos.ContextTrackingMode = 0
            port_attr.SecurityQos.EffectiveOnly = 0

        if connect_message is None:
            send_msg = None
            send_msg_attr = None
            buffersize = None
        elif isinstance(connect_message, basestring):
            buffersize = gdef.DWORD(len(connect_message) + 0x1000)
            send_msg = AlpcMessagePort.from_buffer_size(buffersize.value)
            send_msg.data = connect_message
            send_msg_attr = MessageAttribute.with_all_attributes()
        elif isinstance(connect_message, AlpcMessage):
            send_msg = connect_message.port_message
            send_msg_attr = connect_message.attributes
            buffersize = gdef.DWORD(connect_message.port_message_buffer_size)
        else:
            raise ValueError("Don't know how to send <{0!r}> as connect message".format(connect_message))

        # windows.utils.print_ctypes_struct(port_attr, "port_attr_connect", hexa=True)
        receive_attr = MessageAttribute.with_all_attributes()
        winproxy.NtAlpcConnectPort(handle, port_name_unicode, obj_attr, port_attr, flags, None, send_msg, buffersize, send_msg_attr, receive_attr, timeout)
        # If send_msg is not None, it contains the ClientId.UniqueProcess : PID of the server :)
        self.handle = handle.value
        self.port_name = port_name
        return AlpcMessage(send_msg, receive_attr) if send_msg is not None else None
Ejemplo n.º 4
0
    def local_handle(self):
        """A local copy of the handle, acquired with ``DuplicateHandle``

        :type: :class:`int`"""
        if self.dwProcessId == windows.current_process.pid:
            return self.wValue
        res = gdef.HANDLE()
        winproxy.DuplicateHandle(self.process.handle, self.wValue, windows.current_process.handle, ctypes.byref(res), dwOptions=gdef.DUPLICATE_SAME_ACCESS)
        return res.value
Ejemplo n.º 5
0
 def get_next_resource_descriptor(self, resource, resdes=None):
     if resdes is None:
         # Using logical-conf as resdes will retrieve the first one
         # https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_next_res_des#remarks
         resdes = self
     resid = None
     if resource == gdef.ResType_All:
         resid = gdef.RESOURCEID()
     res = gdef.HANDLE()
     winproxy.CM_Get_Next_Res_Des(res, resdes, resource, resid, 0)
     resdes_type = resid.value if resid is not None else resource
     return ResourceDescriptor.from_handle_and_type(res.value, resdes_type)
Ejemplo n.º 6
0
 def _open_directory(self):
     path = self.fullname
     utf16_len = len(path) * 2
     obj_attr = gdef.OBJECT_ATTRIBUTES()
     obj_attr.Length = ctypes.sizeof(obj_attr)
     obj_attr.RootDirectory = None
     obj_attr.ObjectName = ctypes.pointer(gdef.LSA_UNICODE_STRING.from_string(path))
     obj_attr.Attributes = gdef.OBJ_CASE_INSENSITIVE
     obj_attr.SecurityDescriptor = 0
     obj_attr.SecurityQualityOfService = 0
     res = gdef.HANDLE()
     winproxy.NtOpenDirectoryObject(res, gdef.DIRECTORY_QUERY | gdef.READ_CONTROL , obj_attr)
     return res.value
Ejemplo n.º 7
0
    def create_port(self,
                    port_name,
                    msglen=None,
                    port_attr_flags=0,
                    obj_attr=None,
                    port_attr=None):
        """Create the ALPC port ``port_name``. Most of the parameters have defauls value is ``None`` is passed.

            :param str port_name: The port's name to create.
            :param int msglen: ``ALPC_PORT_ATTRIBUTES.MaxMessageLength`` used if ``port_attr`` is ``None`` (MUTUALY EXCLUSINVE WITH ``port_attr``)
            :param int port_attr_flags: ``ALPC_PORT_ATTRIBUTES.Flags`` used if ``port_attr`` is ``None`` (MUTUALY EXCLUSINVE WITH ``port_attr``)
            :param OBJECT_ATTRIBUTES obj_attr: The attributes of the port, one with default value will be used if this parameter is ``None``
            :param ALPC_PORT_ATTRIBUTES port_attr: The port attributes, one with default value will be used if this parameter is ``None``
        """
        # TODO raise on mutual exclusive parameter (port_attr + port_attr_flags | obj_attr + msglen)
        handle = gdef.HANDLE()
        raw_name = port_name
        if not raw_name.startswith("\\"):
            raw_name = "\\" + port_name
        port_name = self._alpc_port_to_unicode_string(raw_name)

        if msglen is None:
            msglen = DEFAULT_MESSAGE_SIZE
        if obj_attr is None:
            obj_attr = gdef.OBJECT_ATTRIBUTES()
            obj_attr.Length = ctypes.sizeof(obj_attr)
            obj_attr.RootDirectory = None
            obj_attr.ObjectName = ctypes.pointer(port_name)
            obj_attr.Attributes = 0
            obj_attr.SecurityDescriptor = None
            obj_attr.SecurityQualityOfService = None
        if port_attr is None:
            port_attr = gdef.ALPC_PORT_ATTRIBUTES()
            port_attr.Flags = port_attr_flags
            # port_attr.Flags = 0x2080000
            # port_attr.Flags = 0x90000
            port_attr.MaxMessageLength = msglen
            port_attr.MemoryBandwidth = 0
            port_attr.MaxPoolUsage = 0xffffffff
            port_attr.MaxSectionSize = 0xffffffff
            port_attr.MaxViewSize = 0xffffffff
            port_attr.MaxTotalSectionSize = 0xffffffff
            port_attr.DupObjectTypes = 0xffffffff
            # windows.utils.print_ctypes_struct(port_attr, "   - PORT_ATTR", hexa=True)

        winproxy.NtAlpcCreatePort(handle, obj_attr, port_attr)
        self.port_name = raw_name
        self.handle = handle.value
Ejemplo n.º 8
0
def query_link(linkpath):
    """Resolve the link object with path ``linkpath``"""
    obj_attr = gdef.OBJECT_ATTRIBUTES()
    obj_attr.Length = ctypes.sizeof(obj_attr)
    obj_attr.RootDirectory = 0
    obj_attr.ObjectName = ctypes.pointer(
        gdef.LSA_UNICODE_STRING.from_string(linkpath))
    obj_attr.Attributes = gdef.OBJ_CASE_INSENSITIVE
    obj_attr.SecurityDescriptor = 0
    obj_attr.SecurityQualityOfService = 0
    res = gdef.HANDLE()
    x = winproxy.NtOpenSymbolicLinkObject(
        res, gdef.DIRECTORY_QUERY | gdef.READ_CONTROL, obj_attr)
    v = gdef.LSA_UNICODE_STRING.from_string("\x00" * 1000)
    s = gdef.ULONG()
    winproxy.NtQuerySymbolicLinkObject(res, v, s)  # Handle Buffer-too-small ?
    return v.str
Ejemplo n.º 9
0
def NtCreateThreadEx(ThreadHandle=None,
                     DesiredAccess=0x1fffff,
                     ObjectAttributes=0,
                     ProcessHandle=NeededParameter,
                     lpStartAddress=NeededParameter,
                     lpParameter=NeededParameter,
                     CreateSuspended=0,
                     dwStackSize=0,
                     Unknown1=0,
                     Unknown2=0,
                     Unknown=0):
    if ThreadHandle is None:
        ThreadHandle = ctypes.byref(gdef.HANDLE())
    return NtCreateThreadEx.ctypes_function(ThreadHandle, DesiredAccess,
                                            ObjectAttributes, ProcessHandle,
                                            lpStartAddress, lpParameter,
                                            CreateSuspended, dwStackSize,
                                            Unknown1, Unknown2, Unknown3)
Ejemplo n.º 10
0
    def duplicate(self,
                  access_rigth=gdef.MAXIMUM_ALLOWED,
                  attributes=None,
                  type=None,
                  impersonation_level=None):
        """Duplicate the token into a new :class:`Token`.

        :param type: The type of token: ``TokenPrimary(0x1L)`` or ``TokenImpersonation(0x2L)``
        :param impersonation_level: The :class:`~windows.generated_def.winstructs.SECURITY_IMPERSONATION_LEVEL` for a ``TokenImpersonation(0x2L)``:

            - If ``type`` is ``TokenPrimary(0x1L)`` this parameter is ignored if ``None`` or used as-is.
            - If ``type`` is ``TokenImpersonation(0x2L)`` and this parameter is None, ``self.impersonation_level`` is used.
            - If ``type`` is ``TokenImpersonation(0x2L)`` and our Token is a ``TokenPrimary(0x1L)`` this parameter MUST be provided

        :returns: :class:`Token` - The duplicate token

        Example:

            >>> tok
            <Token TokenId=0x39d6dde5 Type=TokenPrimary(0x1L)>
            >>> tok.duplicate()
            <Token TokenId=0x39d7b206 Type=TokenPrimary(0x1L)>
            >>> tok.duplicate(type=gdef.TokenImpersonation)
            ...
            ValueError: Duplicating a PrimaryToken as a TokenImpersonation require explicit <impersonation_level> parameter
            >>> tok.duplicate(type=gdef.TokenImpersonation, impersonation_level=gdef.SecurityImpersonation)
            <Token TokenId=0x39dadbf8 Type=TokenImpersonation(0x2L) ImpersonationLevel=SecurityImpersonation(0x2L)>
        """
        newtoken = gdef.HANDLE()
        if type is None:
            type = self.type
        if impersonation_level is None:
            if self.type == gdef.TokenImpersonation:
                impersonation_level = self.impersonation_level
            elif type != gdef.TokenImpersonation:
                impersonation_level = 0  #: ignored
            else:
                raise ValueError(
                    "Duplicating a PrimaryToken as a TokenImpersonation require explicit <impersonation_level> parameter"
                )
        winproxy.DuplicateTokenEx(self.handle, access_rigth, attributes,
                                  impersonation_level, type, newtoken)
        return bltn_type(self)(newtoken.value)
Ejemplo n.º 11
0
def query_link(linkpath):
    """Resolve the link object with path ``linkpath``"""
    obj_attr = gdef.OBJECT_ATTRIBUTES()
    obj_attr.Length = ctypes.sizeof(obj_attr)
    obj_attr.RootDirectory = 0
    obj_attr.ObjectName = ctypes.pointer(gdef.LSA_UNICODE_STRING.from_string(linkpath))
    obj_attr.Attributes = gdef.OBJ_CASE_INSENSITIVE
    obj_attr.SecurityDescriptor = 0
    obj_attr.SecurityQualityOfService = 0
    res = gdef.HANDLE()
    x = winproxy.NtOpenSymbolicLinkObject(res, gdef.DIRECTORY_QUERY | gdef.READ_CONTROL , obj_attr)
    v = gdef.LSA_UNICODE_STRING.from_size(1000)
    s = gdef.ULONG()
    try:
        winproxy.NtQuerySymbolicLinkObject(res, v, s)
    except WindowsError as e:
        if not (e.winerror & 0xffffffff) == gdef.STATUS_BUFFER_TOO_SMALL:
            raise
        # If our initial 1000 buffer is not enought (improbable) retry with correct size
        v = gdef.LSA_UNICODE_STRING.from_size(s.value)
        winproxy.NtQuerySymbolicLinkObject(res, v, s)
    return v.str
Ejemplo n.º 12
0
def CreatePipe(lpPipeAttributes=None, nSize=0):
    hReadPipe = gdef.HANDLE()
    hWritePipe = gdef.HANDLE()
    CreatePipe.ctypes_function(hReadPipe, hWritePipe, lpPipeAttributes, nSize)
    return hReadPipe.value, hWritePipe.value
Ejemplo n.º 13
0
 def get_next_logical_configuration(self, logconf):
     res = gdef.HANDLE(0)
     winproxy.CM_Get_Next_Log_Conf(res, logconf)
     return res
Ejemplo n.º 14
0
def SetThreadToken(Thread, Token):
    if isinstance(Thread, (int, long)):
        Thread = gdef.HANDLE(Thread)
    return SetThreadToken.ctypes_function(Thread, Token)