コード例 #1
0
ファイル: kill.c プロジェクト: CSRedRat/reactos-playground
VOID
NTAPI
PspDeleteThread(IN PVOID ObjectBody)
{
    PETHREAD Thread = (PETHREAD)ObjectBody;
    PEPROCESS Process = Thread->ThreadsProcess;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
    PSREFTRACE(Thread);
    ASSERT(Thread->Tcb.Win32Thread == NULL);

    /* Check if we have a stack */
    if (Thread->Tcb.InitialStack)
    {
        /* Release it */
        MmDeleteKernelStack((PVOID)Thread->Tcb.StackBase,
                            Thread->Tcb.LargeStack);
    }

    /* Check if we have a CID Handle */
    if (Thread->Cid.UniqueThread)
    {
        /* Delete the CID Handle */
        if (!(ExDestroyHandle(PspCidTable, Thread->Cid.UniqueThread, NULL)))
        {
            /* Something wrong happened, bugcheck */
            KeBugCheck(CID_HANDLE_DELETION);
        }
    }

    /* Cleanup impersionation information */
    PspDeleteThreadSecurity(Thread);

    /* Make sure the thread was inserted, before continuing */
    if (!Process) return;

    /* Check if the thread list is valid */
    if (Thread->ThreadListEntry.Flink)
    {
        /* Lock the thread's process */
        KeEnterCriticalRegion();
        ExAcquirePushLockExclusive(&Process->ProcessLock);

        /* Remove us from the list */
        RemoveEntryList(&Thread->ThreadListEntry);

        /* Release the lock */
        ExReleasePushLockExclusive(&Process->ProcessLock);
        KeLeaveCriticalRegion();
    }

    /* Dereference the Process */
    ObDereferenceObject(Process);
}
コード例 #2
0
ファイル: atom.c プロジェクト: BaoYu0721/WRK-1.2
void
RtlpFreeHandleForAtom(
    PRTL_ATOM_TABLE p,
    PRTL_ATOM_TABLE_ENTRY a
    )
{
    EXHANDLE ExHandle;

    ExHandle.GenericHandleOverlay = 0;
    ExHandle.Index = a->HandleIndex;
    ExDestroyHandle( p->ExHandleTable, ExHandle.GenericHandleOverlay, NULL );
    return;
}
コード例 #3
0
ファイル: kill.c プロジェクト: CSRedRat/reactos-playground
VOID
NTAPI
PspDeleteProcess(IN PVOID ObjectBody)
{
    PEPROCESS Process = (PEPROCESS)ObjectBody;
    KAPC_STATE ApcState;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG, "ObjectBody: %p\n", ObjectBody);
    PSREFTRACE(Process);

    /* Check if it has an Active Process Link */
    if (Process->ActiveProcessLinks.Flink)
    {
        /* Remove it from the Active List */
        KeAcquireGuardedMutex(&PspActiveProcessMutex);
        RemoveEntryList(&Process->ActiveProcessLinks);
        Process->ActiveProcessLinks.Flink = NULL;
        Process->ActiveProcessLinks.Blink = NULL;
        KeReleaseGuardedMutex(&PspActiveProcessMutex);
    }

    /* Check for Auditing information */
    if (Process->SeAuditProcessCreationInfo.ImageFileName)
    {
        /* Free it */
        ExFreePoolWithTag(Process->SeAuditProcessCreationInfo.ImageFileName,
                          TAG_SEPA);
        Process->SeAuditProcessCreationInfo.ImageFileName = NULL;
    }

    /* Check if we have a job */
    if (Process->Job)
    {
        /* Remove the process from the job */
        PspRemoveProcessFromJob(Process, Process->Job);

        /* Dereference it */
        ObDereferenceObject(Process->Job);
        Process->Job = NULL;
    }

    /* Increase the stack count */
    Process->Pcb.StackCount++;

    /* Check if we have a debug port */
    if (Process->DebugPort)
    {
        /* Deference the Debug Port */
        ObDereferenceObject(Process->DebugPort);
        Process->DebugPort = NULL;
    }

    /* Check if we have an exception port */
    if (Process->ExceptionPort)
    {
        /* Deference the Exception Port */
        ObDereferenceObject(Process->ExceptionPort);
        Process->ExceptionPort = NULL;
    }

    /* Check if we have a section object */
    if (Process->SectionObject)
    {
        /* Deference the Section Object */
        ObDereferenceObject(Process->SectionObject);
        Process->SectionObject = NULL;
    }

#if defined(_X86_)
    /* Clean Ldt and Vdm objects */
    PspDeleteLdt(Process);
    PspDeleteVdmObjects(Process);
#endif

    /* Delete the Object Table */
    if (Process->ObjectTable)
    {
        /* Attach to the process */
        KeStackAttachProcess(&Process->Pcb, &ApcState);

        /* Kill the Object Info */
        ObKillProcess(Process);

        /* Detach */
        KeUnstackDetachProcess(&ApcState);
    }

    /* Check if we have an address space, and clean it */
    if (Process->HasAddressSpace)
    {
        /* Attach to the process */
        KeStackAttachProcess(&Process->Pcb, &ApcState);

        /* Clean the Address Space */
        PspExitProcess(FALSE, Process);

        /* Detach */
        KeUnstackDetachProcess(&ApcState);

        /* Completely delete the Address Space */
        MmDeleteProcessAddressSpace(Process);
    }

    /* See if we have a PID */
    if (Process->UniqueProcessId)
    {
        /* Delete the PID */
        if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId, NULL)))
        {
            /* Something wrong happened, bugcheck */
            KeBugCheck(CID_HANDLE_DELETION);
        }
    }

    /* Cleanup security information */
    PspDeleteProcessSecurity(Process);

    /* Check if we have kept information on the Working Set */
    if (Process->WorkingSetWatch)
    {
        /* Free it */
        ExFreePool(Process->WorkingSetWatch);

        /* And return the quota it was taking up */
        PsReturnProcessNonPagedPoolQuota(Process, 0x2000);
    }

    /* Dereference the Device Map */
    ObDereferenceDeviceMap(Process);

    /* Destroy the Quota Block */
    PspDestroyQuotaBlock(Process);
}
コード例 #4
0
ファイル: obclose.c プロジェクト: mingpen/OpenNT
NTSTATUS
NtClose (
    IN HANDLE Handle
    )

/*++

Routine Description:

    This function is used to close access to the specified handle

Arguments:

    Handle - Supplies the handle being closed

Return Value:

    An appropriate status value

--*/

{
    PHANDLE_TABLE ObjectTable;
    PHANDLE_TABLE_ENTRY ObjectTableEntry;
    PVOID Object;
    ULONG CapturedGrantedAccess;
    ULONG CapturedAttributes;
    POBJECT_HEADER ObjectHeader;
    POBJECT_TYPE ObjectType;
    NTSTATUS Status;
    BOOLEAN AttachedToProcess = FALSE;
    KAPC_STATE ApcState;

    //
    //  Protect ourselves from being interrupted while we hold a handle table
    //  entry lock
    //

    KeEnterCriticalRegion();

    try {

    #if DBG
        KIRQL SaveIrql;
    #endif // DBG

        ObpValidateIrql( "NtClose" );

        ObpBeginTypeSpecificCallOut( SaveIrql );

    #if DBG

        //
        //  On checked builds, check that if the Kernel handle bit is set, then
        //  we're coming from Kernel mode. We should probably fail the call if
        //  bit set && !Kmode
        //

        if ((Handle != NtCurrentThread()) && (Handle != NtCurrentProcess())) {

            ASSERT((Handle < 0 ) ? (KeGetPreviousMode() == KernelMode) : TRUE);
        }

    #endif
        //
        //  For the current process we will grab its handle/object table and
        //  translate the handle to its corresponding table entry.  If the
        //  call is successful it also lock down the handle table.  But first
        //  check for a kernel handle and attach and use that table if so.
        //

        if (IsKernelHandle( Handle, KeGetPreviousMode() ))  {

            Handle = DecodeKernelHandle( Handle );

            ObjectTable = ObpKernelHandleTable;

            //
            //  Go to the system process if we have to
            //
            if (PsGetCurrentProcess() != PsInitialSystemProcess) {
               KeStackAttachProcess (&PsInitialSystemProcess->Pcb, &ApcState);
               AttachedToProcess = TRUE;
            }

        } else {

            ObjectTable = ObpGetObjectTable();
        }

        ObjectTableEntry = ExMapHandleToPointer( ObjectTable,
                                                 Handle );

        //
        //  Check that the specified handle is legitimate otherwise we can
        //  assume the caller just passed in some bogus handle value
        //

        if (ObjectTableEntry != NULL) {

            //
            //  From the object table entry we can grab a pointer to the object
            //  header, get its type and its body
            //

            ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES);
            ObjectType = ObjectHeader->Type;
            Object = &ObjectHeader->Body;

            //
            //  If the object type specifies an okay to close procedure then we
            //  need to invoke that callback.  If the callback doesn't want us to
            //  close handle then unlock the object table and return the error
            //  to our caller
            //

            if (ObjectType->TypeInfo.OkayToCloseProcedure != NULL) {

                if (!(*ObjectType->TypeInfo.OkayToCloseProcedure)( PsGetCurrentProcess(), Object, Handle )) {

                    ObpEndTypeSpecificCallOut( SaveIrql, "NtClose", ObjectType, Object );

                    ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry );

                    //
                    //  If we are attached to the system process then return
                    //  back to our caller
                    //

                    if (AttachedToProcess) {

                        KeUnstackDetachProcess(&ApcState);
                        AttachedToProcess = FALSE;
                    }

                    Status = STATUS_HANDLE_NOT_CLOSABLE;
                    leave;
                }
            }

            CapturedAttributes = ObjectTableEntry->ObAttributes;

            //
            //  If the previous mode was user and the handle is protected from
            //  being closed, then we'll either raise or return an error depending
            //  on the global flags and debugger port situation.
            //

            if ((CapturedAttributes & OBJ_PROTECT_CLOSE) != 0) {

                if (KeGetPreviousMode() != KernelMode) {

                    ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry );

                    if ((NtGlobalFlag & FLG_ENABLE_CLOSE_EXCEPTIONS) ||
                        (PsGetCurrentProcess()->DebugPort != NULL)) {

                        //
                        //  If we are attached to the system process then return
                        //  back to our caller
                        //

                        if (AttachedToProcess) {
                            KeUnstackDetachProcess(&ApcState);
                            AttachedToProcess = FALSE;
                        }

                        Status = KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
                        leave;

                    } else {

                        //
                        //  If we are attached to the system process then return
                        //  back to our caller
                        //

                        if (AttachedToProcess) {
                            KeUnstackDetachProcess(&ApcState);
                            AttachedToProcess = FALSE;
                        }

                        Status = STATUS_HANDLE_NOT_CLOSABLE;
                        leave;
                    }

                } else {

                    if ((!PsIsThreadTerminating(PsGetCurrentThread())) &&
                        (PsGetCurrentProcess()->Peb != NULL)) {

                        ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry );

    #if DBG
                        //
                        //  bugcheck here on checked builds if kernel mode code is
                        //  closing a protected handle and process is not exiting.
                        //  Ignore if no PEB as this occurs if process is killed
                        //  before really starting.
                        //

                        KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 0, 0, 0);
    #else
                        //
                        //  If we are attached to the system process then return
                        //  back to our caller
                        //

                        if (AttachedToProcess) {
                            KeUnstackDetachProcess(&ApcState);
                            AttachedToProcess = FALSE;
                        }

                        Status = STATUS_HANDLE_NOT_CLOSABLE;
                        leave;
    #endif // DBG

                    }
                }
            }

            //
            //  Get the granted access for the handle
            //

    #if defined(_X86_) && !FPO

            if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {

                CapturedGrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex );

            } else {

                CapturedGrantedAccess = ObjectTableEntry->GrantedAccess;
            }

    #else

            CapturedGrantedAccess = ObjectTableEntry->GrantedAccess;

    #endif // _X86_ && !FPO

            //
            //  Now remove the handle from the handle table
            //

            ExDestroyHandle( ObjectTable,
                             Handle,
                             ObjectTableEntry );

            //
            //  perform any auditing required
            //

            //
            //  Extract the value of the GenerateOnClose bit stored
            //  after object open auditing is performed.  This value
            //  was stored by a call to ObSetGenerateOnClosed.
            //

            if (CapturedAttributes & OBJ_AUDIT_OBJECT_CLOSE) {

                if ( SepAdtAuditingEnabled ) {

                    SeCloseObjectAuditAlarm( Object,
                                             (HANDLE)((ULONG_PTR)Handle & ~OBJ_HANDLE_TAGBITS),  // Mask off the tagbits defined for OB objects.
                                             TRUE );
                }
            }

            //
            //  Since we took the handle away we need to decrement the objects
            //  handle count, and remove a reference
            //

            ObpDecrementHandleCount( PsGetCurrentProcess(),
                                     ObjectHeader,
                                     ObjectHeader->Type,
                                     CapturedGrantedAccess );

            ObDereferenceObject( Object );

            ObpEndTypeSpecificCallOut( SaveIrql, "NtClose", ObjectType, Object );

            //
            //  If we are attached to the system process then return
            //  back to our caller
            //

            if (AttachedToProcess) {
                KeUnstackDetachProcess(&ApcState);
                AttachedToProcess = FALSE;
            }

            //
            //  And return to our caller
            //

            Status = STATUS_SUCCESS;
            leave;

        } else {

            //
            //  At this point the input handle did not translate to a valid
            //  object table entry
            //

            ObpEndTypeSpecificCallOut( SaveIrql, "NtClose", ObpTypeObjectType, Handle );

            //
            //  If we are attached to the system process then return
            //  back to our caller
            //

            if (AttachedToProcess) {
                KeUnstackDetachProcess(&ApcState);
                AttachedToProcess = FALSE;
            }

            //
            //  Now if the handle is not null and it does not represent the
            //  current thread or process then if we're user mode we either raise
            //  or return an error
            //

            if ((Handle != NULL) &&
                (Handle != NtCurrentThread()) &&
                (Handle != NtCurrentProcess())) {

                if (KeGetPreviousMode() != KernelMode) {

                    if ((NtGlobalFlag & FLG_ENABLE_CLOSE_EXCEPTIONS) ||
                        (PsGetCurrentProcess()->DebugPort != NULL)) {

                        Status = KeRaiseUserException(STATUS_INVALID_HANDLE);
                        leave;

                    } else {

                        Status = STATUS_INVALID_HANDLE;
                        leave;
                    }

                } else {

                    //
                    //  bugcheck here if kernel debugger is enabled and if kernel mode code is
                    //  closing a bogus handle and process is not exiting.  Ignore
                    //  if no PEB as this occurs if process is killed before
                    //  really starting.
                    //

                    if (( !PsIsThreadTerminating(PsGetCurrentThread())) &&
                        (PsGetCurrentProcess()->Peb != NULL)) {

                        if (KdDebuggerEnabled) {
                            KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 1, 0, 0);
                        }
                    }

                }
            }

            Status = STATUS_INVALID_HANDLE;
            leave;
        }

    } finally {

        KeLeaveCriticalRegion();
    }

    return Status;
}