Example #1
0
DECLSPEC_NOINLINE
VOID
KiContinuePreviousModeUser (
    IN PCONTEXT ContextRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )

/*++

Routine Description:

    This function is called to copy the specified context record when the
    previous mode is user. Its only purpose is to save stack space in the
    caller. 

    N.B. This routine assumes that the caller has protected access to the
       specified context record.

Arguments:

    ContextRecord - Supplies a pointer to a context record.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

Return Value:

    None.

--*/

{

    CONTEXT ContextRecord2;

    //
    // Probe and copy the context record to a stack local context record.
    //

    ProbeForReadSmallStructure(ContextRecord, sizeof(CONTEXT), CONTEXT_ALIGN);
    RtlCopyMemory(&ContextRecord2, ContextRecord, sizeof(CONTEXT));

    //
    // Move information from the context record to the exception and trap
    // frames.
    //

    KeContextToKframes(TrapFrame,
                       ExceptionFrame,
                       &ContextRecord2,
                       ContextRecord2.ContextFlags,
                       UserMode);

    return;
}
Example #2
0
NTSTATUS
NtImpersonateThread(
    __in HANDLE ServerThreadHandle,
    __in HANDLE ClientThreadHandle,
    __in PSECURITY_QUALITY_OF_SERVICE SecurityQos
    )

/*++

Routine Description:

    This routine is used to cause the server thread to impersonate the client
    thread.  The impersonation is done according to the specified quality
    of service parameters.



Arguments:

    ServerThreadHandle - Is a handle to the server thread (the impersonator, or
        doing the impersonation).  This handle must be open for
        THREAD_IMPERSONATE access.

    ClientThreadHandle - Is a handle to the Client thread (the impersonatee, or
        one being impersonated).   This handle must be open for
        THREAD_DIRECT_IMPERSONATION access.


    SecurityQos - A pointer to security quality of service information
        indicating what form of impersonation is to be performed.



Return Value:

    STATUS_SUCCESS - Indicates the call completed successfully.


--*/

{


    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;
    PETHREAD ClientThread, ServerThread;
    SECURITY_QUALITY_OF_SERVICE CapturedQos;
    SECURITY_CLIENT_CONTEXT ClientSecurityContext;

    //
    // Get previous processor mode and probe and capture arguments if necessary
    //

    PreviousMode = KeGetPreviousMode();

    try {

        if (PreviousMode != KernelMode) {
            ProbeForReadSmallStructure (SecurityQos,
                                        sizeof (SECURITY_QUALITY_OF_SERVICE),
                                        sizeof (ULONG));
        }
        CapturedQos = *SecurityQos;

    } except (ExSystemExceptionFilter ()) {
        return GetExceptionCode ();
    }



    //
    // Reference the client thread, checking for appropriate access.
    //

    Status = ObReferenceObjectByHandle (ClientThreadHandle,           // Handle
                                        THREAD_DIRECT_IMPERSONATION,  // DesiredAccess
                                        PsThreadType,                 // ObjectType
                                        PreviousMode,                 // AccessMode
                                        &ClientThread,                // Object
                                        NULL);                        // GrantedAccess

    if (!NT_SUCCESS (Status)) {
        return Status;
    }

    //
    // Reference the client thread, checking for appropriate access.
    //

    Status = ObReferenceObjectByHandle (ServerThreadHandle,           // Handle
                                        THREAD_IMPERSONATE,           // DesiredAccess
                                        PsThreadType,                 // ObjectType
                                        PreviousMode,                 // AccessMode
                                        &ServerThread,                // Object
                                        NULL);                        // GrantedAccess

    if (!NT_SUCCESS (Status)) {
        ObDereferenceObject (ClientThread);
        return Status;
    }


    //
    // Get the client's security context
    //

    Status = SeCreateClientSecurity (ClientThread,             // ClientThread
                                     &CapturedQos,             // SecurityQos
                                     FALSE,                    // ServerIsRemote
                                     &ClientSecurityContext);  // ClientContext

    if (!NT_SUCCESS (Status)) {
        ObDereferenceObject (ServerThread);
        ObDereferenceObject (ClientThread);
        return Status;
    }


    //
    // Impersonate the client
    //

    Status = SeImpersonateClientEx (&ClientSecurityContext, ServerThread);

    SeDeleteClientSecurity (&ClientSecurityContext);

    //
    // Done.
    //


    ObDereferenceObject (ServerThread);
    ObDereferenceObject (ClientThread);

    return Status ;
}
Example #3
0
NTSTATUS
ObpCaptureObjectCreateInformation (
    IN POBJECT_TYPE ObjectType OPTIONAL,
    IN KPROCESSOR_MODE ProbeMode,
    IN KPROCESSOR_MODE CreatorMode,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN OUT PUNICODE_STRING CapturedObjectName,
    IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
    IN LOGICAL UseLookaside
    )

/*++

Routine Description:

    This function captures the object creation information and stuff
    it into the input variable ObjectCreateInfo

Arguments:

    ObjectType - Specifies the type of object we expect to capture,
        currently ignored.

    ProbeMode - Specifies the processor mode for doing our parameter
        probes

    CreatorMode - Specifies the mode the object is being created for

    ObjectAttributes - Supplies the object attributes we are trying
        to capture

    CapturedObjectName - Receives the name of the object being created

    ObjectCreateInfo - Receives the create information for the object
        like its root, attributes, and security information

    UseLookaside - Specifies if we are to allocate the captured name
        buffer from the lookaside list or from straight pool.

Return Value:

    An appropriate status value

--*/

{
    PUNICODE_STRING ObjectName;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
    NTSTATUS Status;
    ULONG Size;

    PAGED_CODE();

    UNREFERENCED_PARAMETER (ObjectType);

    //
    //  Capture the object attributes, the security quality of service, if
    //  specified, and object name, if specified.
    //

    Status = STATUS_SUCCESS;

    RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));

    try {

        if (ARGUMENT_PRESENT(ObjectAttributes)) {

            //
            //  Probe the object attributes if necessary.
            //

            if (ProbeMode != KernelMode) {

                ProbeForReadSmallStructure( ObjectAttributes,
                                            sizeof(OBJECT_ATTRIBUTES),
                                            sizeof(ULONG_PTR) );
            }

            if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES) ||
                (ObjectAttributes->Attributes & ~OBJ_ALL_VALID_ATTRIBUTES)) {

                Status = STATUS_INVALID_PARAMETER;

                goto failureExit;
            }

            //
            //  Capture the object attributes.
            //

            ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
            ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_ALL_VALID_ATTRIBUTES;
            //
            // Remove privileged option if passed in from user mode
            //
            if (CreatorMode != KernelMode) {
                ObjectCreateInfo->Attributes &= ~OBJ_KERNEL_HANDLE;
            } else if (ObWatchHandles) {
                if ((ObjectCreateInfo->Attributes&OBJ_KERNEL_HANDLE) == 0 &&
                    PsGetCurrentProcess() != PsInitialSystemProcess) {
                    DbgBreakPoint ();
                }
            }
            ObjectName = ObjectAttributes->ObjectName;
            SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
            SecurityQos = ObjectAttributes->SecurityQualityOfService;

            if (ARGUMENT_PRESENT(SecurityDescriptor)) {

                Status = SeCaptureSecurityDescriptor( SecurityDescriptor,
                                                      ProbeMode,
                                                      PagedPool,
                                                      TRUE,
                                                      &ObjectCreateInfo->SecurityDescriptor );

                if (!NT_SUCCESS(Status)) {

                    KdPrint(( "OB: Failed to capture security descriptor at %08x - Status == %08x\n",
                              SecurityDescriptor,
                              Status) );

                    //
                    //  The cleanup routine depends on this being NULL if it isn't
                    //  allocated.  SeCaptureSecurityDescriptor may modify this
                    //  parameter even if it fails.
                    //

                    ObjectCreateInfo->SecurityDescriptor = NULL;

                    goto failureExit;
                }

                SeComputeQuotaInformationSize(  ObjectCreateInfo->SecurityDescriptor,
                                                &Size );

                ObjectCreateInfo->SecurityDescriptorCharge = SeComputeSecurityQuota( Size );
                ObjectCreateInfo->ProbeMode = ProbeMode;
            }

            if (ARGUMENT_PRESENT(SecurityQos)) {

                if (ProbeMode != KernelMode) {

                    ProbeForReadSmallStructure( SecurityQos, sizeof(*SecurityQos), sizeof(ULONG));
                }

                ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
                ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService;
            }

        } else {

            ObjectName = NULL;
        }

    } except (ExSystemExceptionFilter()) {

        Status = GetExceptionCode();

        goto failureExit;
    }

    //
    //  If an object name is specified, then capture the object name.
    //  Otherwise, initialize the object name descriptor and check for
    //  an incorrectly specified root directory.
    //

    if (ARGUMENT_PRESENT(ObjectName)) {

        Status = ObpCaptureObjectName( ProbeMode,
                                       ObjectName,
                                       CapturedObjectName,
                                       UseLookaside );

    } else {

        CapturedObjectName->Buffer = NULL;
        CapturedObjectName->Length = 0;
        CapturedObjectName->MaximumLength = 0;

        if (ARGUMENT_PRESENT(ObjectCreateInfo->RootDirectory)) {

            Status = STATUS_OBJECT_NAME_INVALID;
        }
    }

    //
    //  If the completion status is not successful, and a security quality
    //  of service parameter was specified, then free the security quality
    //  of service memory.
    //

failureExit:

    if (!NT_SUCCESS(Status)) {

        ObpReleaseObjectCreateInformation(ObjectCreateInfo);
    }

    return Status;
}
Example #4
0
NTSTATUS
KiContinueEx (
    IN PCONTEXT ContextRecord,
    IN BOOLEAN TestAlert,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )

/*++

Routine Description:

    This function is called to copy the specified context frame to the
    specified exception and trap frames for the continue system service.

    N.B. If the previous mode is user mode, alerts are being tested, a user
         APC is available to execute, and the specified context record was
         previously placed on the stack by the user APC initialization routine,
         then bypass context record copy to the kernel frames and back again.

Arguments:

    ContextRecord - Supplies a pointer to a context record.

    TestAlert - Supplies a boolean value that determines whether a test alert
       is to be performed.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

Return Value:

    STATUS_ACCESS_VIOLATION is returned if the context record is not readable
        from user mode.

    STATUS_DATATYPE_MISALIGNMENT is returned if the context record is not
        properly aligned.

    STATUS_SUCCESS + 1 is returned if the context frame is copied successfully
        to the specified exception and trap frames.

    STATUS_SUCCESS is returned if the context record copy was bypassed and
        another user APC is ready to be delivered.

--*/

{

    KIRQL OldIrql;
    NTSTATUS Status;
    PKTHREAD Thread;
    ULONG64 UserStack;

    //
    // Synchronize with other context operations.
    //
    // If the current IRQL is less than APC_LEVEL, then raise IRQL to APC level.
    // 

    OldIrql = KeGetCurrentIrql();
    if (OldIrql < APC_LEVEL) {
        KfRaiseIrql(APC_LEVEL);
    }

    //
    // If the previous mode was not kernel mode, then attempt to bypass
    // the copy of the context record. Otherwise, copy context to kernel
    // frames directly.
    // 
      
    Status = STATUS_SUCCESS + 1;
    Thread = KeGetCurrentThread();
    if (Thread->PreviousMode != KernelMode) {
        try {
            if (TestAlert != FALSE) {
                ProbeForWriteSmallStructure(ContextRecord,
                                            sizeof(CONTEXT),
                                            CONTEXT_ALIGN);

                KeTestAlertThread(UserMode);
                UserStack = (ContextRecord->Rsp  - sizeof(MACHINE_FRAME)) & ~STACK_ROUND;
                if (((UserStack - sizeof(CONTEXT)) == (ULONG64)ContextRecord) &&
                    (Thread->ApcState.UserApcPending != FALSE)) {

                    //
                    // Save the context record and exception frame addresses
                    // in the trap frame and deliver the user APC bypassing
                    // the context copy.
                    //

                    TrapFrame->ContextRecord = (ULONG64)ContextRecord;
                    TrapFrame->ExceptionFrame = (ULONG64)ExceptionFrame;
                    KiDeliverApc(UserMode, NULL, TrapFrame);
                    Status = STATUS_SUCCESS;
                    leave;
                }

            } else {
                ProbeForReadSmallStructure(ContextRecord,
                                           sizeof(CONTEXT),
                                           CONTEXT_ALIGN);
            }

            KiContinuePreviousModeUser(ContextRecord,
                                       ExceptionFrame,
                                       TrapFrame);

        } except(EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
        }

    } else {
Example #5
0
NTSTATUS
NtReplyWaitReceivePortEx(
    __in HANDLE PortHandle,
    __out_opt PVOID *PortContext,
    __in_opt PPORT_MESSAGE ReplyMessage,
    __out PPORT_MESSAGE ReceiveMessage,
    __in_opt PLARGE_INTEGER Timeout
    )

/*++

Routine Description:

    See NtReplyWaitReceivePort.

Arguments:

    See NtReplyWaitReceivePort.

    Timeout - Supplies an optional timeout value to use when waiting for a
        receive.

Return Value:

    See NtReplyWaitReceivePort.

--*/

{
    PLPCP_PORT_OBJECT PortObject;
    PLPCP_PORT_OBJECT ReceivePort;
    PORT_MESSAGE CapturedReplyMessage;
    KPROCESSOR_MODE PreviousMode;
    KPROCESSOR_MODE WaitMode;
    NTSTATUS Status;
    PLPCP_MESSAGE Msg;
    PETHREAD CurrentThread;
    PETHREAD WakeupThread;
    LARGE_INTEGER TimeoutValue ;
    PLPCP_PORT_OBJECT ConnectionPort = NULL;

    PAGED_CODE();

    CurrentThread = PsGetCurrentThread();

    TimeoutValue.QuadPart = 0 ;

    //
    //  Get previous processor mode
    //

    PreviousMode = KeGetPreviousMode();
    WaitMode = PreviousMode;

    if (PreviousMode != KernelMode) {

        try {

            if (ARGUMENT_PRESENT( PortContext )) {

                ProbeForWriteUlong( (PULONG)PortContext );
            }

            if (ARGUMENT_PRESENT( ReplyMessage)) {

                ProbeForReadSmallStructure( ReplyMessage,
                                            sizeof( *ReplyMessage ),
                                            sizeof( ULONG ));

                CapturedReplyMessage = *ReplyMessage;
            }

            if (ARGUMENT_PRESENT( Timeout )) {

                TimeoutValue = ProbeAndReadLargeInteger( Timeout );

                Timeout = &TimeoutValue ;
            }

            ProbeForWriteSmallStructure( ReceiveMessage,
                                         sizeof( *ReceiveMessage ),
                                         sizeof( ULONG ));

        } except( EXCEPTION_EXECUTE_HANDLER ) {

            return GetExceptionCode();
        }

    } else {

        //
        //  Kernel mode threads call with wait mode of user so that their
        //  kernel // stacks are swappable. Main consumer of this is
        //  SepRmCommandThread
        //

        if ( IS_SYSTEM_THREAD(CurrentThread) ) {
Example #6
0
NTSTATUS
NtAcceptConnectPort (
    __out PHANDLE PortHandle,
    __in_opt PVOID PortContext,
    __in PPORT_MESSAGE ConnectionRequest,
    __in BOOLEAN AcceptConnection,
    __inout_opt PPORT_VIEW ServerView,
    __out_opt PREMOTE_PORT_VIEW ClientView
    )

/*++

Routine Description:

    A server process can accept or reject a client connection request
    using the NtAcceptConnectPort service.

    The ConnectionRequest parameter must specify a connection request
    returned by a previous call to the NtListenPort service.  This
    service will either complete the connection if the AcceptConnection
    parameter is TRUE, or reject the connection request if the
    AcceptConnection parameter is FALSE.

    In either case, the contents of the data portion of the connection
    request is the data to return to the caller of NtConnectPort.

    If the connection request is accepted, then two communication port
    objects will be created and connected together.  One will be
    inserted in the client process' handle table and returned to the
    client via the PortHandle parameter it specified on the
    NtConnectPort service.  The other will be inserted in the server
    process' handle table and returned via the PortHandle parameter
    specified on the NtCompleteConnectPort service.  In addition the
    two communication ports (client and server) will be linked together.

    If the connection request is accepted, and the ServerView parameter
    was specified, then the section handle is examined.  If it is valid,
    then the portion of the section described by the SectionOffset and
    ViewSize fields will be mapped into both the client and server
    process address spaces.  The address in server's address space will
    be returned in the ViewBase field.  The address in the client's
    address space will be returned in the ViewRemoteBase field.  The
    actual offset and size used to map the section will be returned in
    the SectionOffset and ViewSize fields.

    Communication port objects are temporary objects that have no names
    and cannot be inherited.  When either the client or server process
    calls the !f NtClose service for a communication port, the port will
    be deleted since there can never be more than one outstanding handle
    for each communication port.  The port object type specific delete
    procedure will then be invoked.  This delete procedure will examine
    the communication port, and if it is connected to another
    communication port, it will queue an LPC_PORT_CLOSED datagram to
    that port's message queue.  This will allow both the client and
    server processes to notice when a port becomes disconnected, either
    because of an explicit call to NtClose or an implicit call due to
    process termination.  In addition, the delete procedure will scan
    the message queue of the port being closed and for each message
    still in the queue, it will return an ERROR_PORT_CLOSED status to
    any thread that is waiting for a reply to the message.

Arguments:

    PortHandle - A pointer to a variable that will receive the server
        communication port object handle value.

    PortContext - An uninterpreted pointer that is stored in the
        server communication port.  This pointer is returned whenever
        a message is received for this port.

    ConnectionRequest - A pointer to a structure that describes the
        connection request being accepted or rejected:

        The ConnectionRequest structure

        ULONG Length - Specifies the size of this data structure in
            bytes.

        CLIENT_ID ClientId - Specifies a structure that contains the
            client identifier (CLIENT_ID) of the thread that sent the
            request.

        The ClientId Structure

            ULONG UniqueProcessId - A unique value for each process
                in the system.

            ULONG UniqueThreadId - A unique value for each thread in the
                system.

        ULONG MessageId - A unique value that identifies the connection
            request being completed.

        ULONG PortAttributes - This field has no meaning for this service.

        ULONG ClientViewSize - This field has no meaning for this service.

    AcceptConnection - Specifies a boolean value which indicates where
        the connection request is being accepted or rejected.  A value
        of TRUE means that the connection request is accepted and a
        server communication port handle will be created and connected
        to the client's communication port handle.  A value of FALSE
        means that the connection request is not accepted.

    ServerView - A pointer to a structure that specifies the section that
        the server process will use to send messages back to the client
        process connected to this port.

        The ServerView Structure

        ULONG Length - Specifies the size of this data structure in
            bytes.

        HANDLE SectionHandle - Specifies an open handle to a section
            object.

        ULONG SectionOffset - Specifies a field that will receive the
            actual offset, in bytes, from the start of the section.  The
            initial value of this parameter specifies the byte offset
            within the section that the client's view is based.  The
            value is rounded down to the next host page size boundary.

        ULONG ViewSize - Specifies the size of the view, in bytes.

        PVOID ViewBase - Specifies a field that will receive the base
            address of the port memory in the server's address space.

        PVOID ViewRemoteBase - Specifies a field that will receive
            the base address of the server port's memory in the client's
            address space.  Used to generate pointers that are
            meaningful to the client.

    ClientView - An optional pointer to a structure that will receive
        information about the client process' view in the server's
        address space.  The server process can use this information
        to validate pointers it receives from the client process.

        The ClientView Structure

        ULONG Length - Specifies the size of this data structure in
            bytes.

        PVOID ViewBase - Specifies a field that will receive the base
            address of the client port's memory in the server's address
            space.

        ULONG ViewSize - Specifies a field that will receive the
            size, in bytes, of the client's view in the server's address
            space.  If this field is zero, then client has no view in
            the server's address space.

Return Value:

    NTSTATUS - An appropriate status value.

--*/

{
    PLPCP_PORT_OBJECT ConnectionPort;
    PLPCP_PORT_OBJECT ServerPort;
    PLPCP_PORT_OBJECT ClientPort;
    PVOID ClientSectionToMap;
    HANDLE Handle;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;
    ULONG ConnectionInfoLength;
    PLPCP_MESSAGE Msg;
    PLPCP_CONNECTION_MESSAGE ConnectMsg;
    PORT_MESSAGE CapturedReplyMessage;
    PVOID SectionToMap;
    LARGE_INTEGER SectionOffset;
    SIZE_T ViewSize;
    PEPROCESS ClientProcess;
    PETHREAD ClientThread;
    PORT_VIEW CapturedServerView;

    PAGED_CODE();

    //
    //  Get previous processor mode and probe output arguments if necessary.
    //

    PreviousMode = KeGetPreviousMode();

    if (PreviousMode != KernelMode) {

        try {

            ProbeForWriteHandle( PortHandle );

            ProbeForReadSmallStructure( ConnectionRequest,
                                        sizeof( *ConnectionRequest ),
                                        sizeof( ULONG ));

            CapturedReplyMessage = *ConnectionRequest;

            if (ARGUMENT_PRESENT( ServerView )) {

                CapturedServerView = ProbeAndReadStructure( ServerView, PORT_VIEW );

                if (CapturedServerView.Length != sizeof( *ServerView )) {

                    return STATUS_INVALID_PARAMETER;
                }

                ProbeForWriteSmallStructure( ServerView,
                                             sizeof( *ServerView ),
                                             sizeof( ULONG ));
            }

            if (ARGUMENT_PRESENT( ClientView )) {

                if (ProbeAndReadUlong( &ClientView->Length ) != sizeof( *ClientView )) {

                    return STATUS_INVALID_PARAMETER;
                }

                ProbeForWriteSmallStructure( ClientView,
                                             sizeof( *ClientView ),
                                             sizeof( ULONG ));
            }

        } except( EXCEPTION_EXECUTE_HANDLER ) {

            return GetExceptionCode();
        }

    } else {
Example #7
0
NTSTATUS
NtImpersonateClientOfPort (
    __in HANDLE PortHandle,
    __in PPORT_MESSAGE Message
    )

/*++

Routine Description:

    This procedure is used by the server thread to temporarily acquire the
    identifier set of a client thread.

    This service establishes an impersonation token for the calling thread.
    The impersonation token corresponds to the context provided by the port
    client.  The client must currently be waiting for a reply to the
    specified message.

    This service returns an error status code if the client thread is not
    waiting for a reply to the message.  The security quality of service
    parameters specified by the client upon connection dictate what use the
    server will have of the client's security context.

    For complicated or extended impersonation needs, the server may open a
    copy of the client's token (using NtOpenThreadToken()).  This must be
    done while impersonating the client.

Arguments:

    PortHandle - Specifies the handle of the communication port that the
        message was received from.

    Message - Specifies an address of a message that was received from the
        client that is to be impersonated.  The ClientId field of the message
        identifies the client thread that is to be impersonated.  The client
        thread must be waiting for a reply to the message in order to
        impersonate the client.

Return Value:

    NTSTATUS - Status code that indicates whether or not the operation was
    successful.

--*/

{
    PLPCP_PORT_OBJECT PortObject;
    PLPCP_PORT_OBJECT ConnectedPort;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;
    PETHREAD ClientThread;
    CLIENT_ID CapturedClientId;
    ULONG CapturedMessageId;
    SECURITY_CLIENT_CONTEXT DynamicSecurity;

    PAGED_CODE();

    //
    //  Get previous processor mode and probe output arguments if necessary.
    //

    PreviousMode = KeGetPreviousMode();

    if (PreviousMode != KernelMode) {

        try {

            ProbeForReadSmallStructure( Message, sizeof( PORT_MESSAGE ), sizeof( ULONG ));

            CapturedClientId = Message->ClientId;
            CapturedMessageId = Message->MessageId;

        } except( EXCEPTION_EXECUTE_HANDLER ) {

            return( GetExceptionCode() );
        }

    } else {
Example #8
0
NTSTATUS
NtOpenProcess (
    __out PHANDLE ProcessHandle,
    __in ACCESS_MASK DesiredAccess,
    __in POBJECT_ATTRIBUTES ObjectAttributes,
    __in_opt PCLIENT_ID ClientId
    )

/*++

Routine Description:

    This function opens a handle to a process object with the specified
    desired access.

    The object is located either by name, or by locating a thread whose
    Client ID matches the specified Client ID and then opening that thread's
    process.

Arguments:

    ProcessHandle - Supplies a pointer to a variable that will receive
        the process object handle.

    DesiredAccess - Supplies the desired types of access for the process
        object.

    ObjectAttributes - Supplies a pointer to an object attributes structure.
        If the ObjectName field is specified, then ClientId must not be
        specified.

    ClientId - Supplies a pointer to a ClientId that if supplied
        specifies the thread whose process is to be opened. If this
        argument is specified, then ObjectName field of the ObjectAttributes
        structure must not be specified.

Return Value:

    NTSTATUS - Status of call

--*/

{

    HANDLE Handle;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;
    PEPROCESS Process;
    PETHREAD Thread;
    CLIENT_ID CapturedCid={0};
    BOOLEAN ObjectNamePresent;
    BOOLEAN ClientIdPresent;
    ACCESS_STATE AccessState;
    AUX_ACCESS_DATA AuxData;
    ULONG Attributes;

    PAGED_CODE();

    //
    // Make sure that only one of either ClientId or ObjectName is
    // present.
    //

    PreviousMode = KeGetPreviousMode();
    if (PreviousMode != KernelMode) {

        //
        // Since we need to look at the ObjectName field, probe
        // ObjectAttributes and capture object name present indicator.
        //

        try {

            ProbeForWriteHandle (ProcessHandle);

            ProbeForReadSmallStructure (ObjectAttributes,
                                        sizeof(OBJECT_ATTRIBUTES),
                                        sizeof(ULONG));
            ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
            Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);

            if (ARGUMENT_PRESENT (ClientId)) {
                ProbeForReadSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG));
                CapturedCid = *ClientId;
                ClientIdPresent = TRUE;
            } else {
                ClientIdPresent = FALSE;
            }
        } except (EXCEPTION_EXECUTE_HANDLER) {
            return GetExceptionCode();
        }
    } else {