[普通]ObReferenceObjectByHandle内核函数

作者(passion) 阅读(1399次) 评论(0) 分类( 内核开发)

大槪就是看这个句柄是当前进程的句柄还是当前线程的句柄,最后再看看这AccessMode是内核还是用户态下,内核的话,句柄表就用ObpKernelHandleTable,用户态的话就用当前进程的句柄表

NTSTATUS
ObReferenceObjectByHandle (
    __in HANDLE Handle,
    __in ACCESS_MASK DesiredAccess,
    __in_opt POBJECT_TYPE ObjectType,
    __in KPROCESSOR_MODE AccessMode,
    __out PVOID *Object,
    __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
    )

/*++

Routine Description:

    Given a handle to an object this routine returns a pointer
    to the body of the object with proper ref counts

Arguments:

    Handle - Supplies a handle to the object being referenced. It can
        also be the result of NtCurrentProcess or NtCurrentThread

    DesiredAccess - Supplies the access being requested by the caller

    ObjectType - Optionally supplies the type of the object we
        are expecting

    AccessMode - Supplies the processor mode of the access

    Object - Receives a pointer to the object body if the operation
        is successful

    HandleInformation - Optionally receives information regarding the
        input handle.

Return Value:

    An appropriate NTSTATUS value

--*/

{
    ACCESS_MASK GrantedAccess;
    PHANDLE_TABLE HandleTable;
    POBJECT_HEADER ObjectHeader;
    PHANDLE_TABLE_ENTRY ObjectTableEntry;
    PEPROCESS Process;
    NTSTATUS Status;
    PETHREAD Thread;

    ObpValidateIrql("ObReferenceObjectByHandle");

    Thread = PsGetCurrentThread ();//得到调用ObReferenceObjectByHandle当前线程
    *Object = NULL;

    //
    // Check is this handle is a kernel handle or one of the two builtin pseudo handles
    //
    if ((LONG)(ULONG_PTR) Handle < 0) {
        //
        // If the handle is equal to the current process handle and the object
        // type is NULL or type process, then attempt to translate a handle to
        // the current process. Otherwise, check if the handle is the current
        // thread handle.
        //

        if (Handle == NtCurrentProcess()) {   //如果句柄等于当前进程的句柄

            if ((ObjectType == PsProcessType) || (ObjectType == NULL)) {

                Process = PsGetCurrentProcessByThread(Thread);//得到当前Eprocess对象
                GrantedAccess = Process->GrantedAccess;

                if ((SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
                    (AccessMode == KernelMode)) {

                    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);//得到Eprocess对象头

                    if (ARGUMENT_PRESENT(HandleInformation)) {

                        HandleInformation->GrantedAccess = GrantedAccess;
                        HandleInformation->HandleAttributes = 0;
                    }

                    ObpIncrPointerCount(ObjectHeader);//增加对象引用计数
                    *Object = Process;//返回对象体指针

                    ASSERT( *Object != NULL );

                    Status = STATUS_SUCCESS;

                } else {

                    Status = STATUS_ACCESS_DENIED;
                }

            } else {

                Status = STATUS_OBJECT_TYPE_MISMATCH;
            }

            return Status;

        //
        // If the handle is equal to the current thread handle and the object
        // type is NULL or type thread, then attempt to translate a handle to
        // the current thread. Otherwise, the we'll try and translate the
        // handle
        //

        } else if (Handle == NtCurrentThread()) {

            if ((ObjectType == PsThreadType) || (ObjectType == NULL)) {

                GrantedAccess = Thread->GrantedAccess;

                if ((SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
                    (AccessMode == KernelMode)) {

                    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);//得到当前线程的对象头

                    if (ARGUMENT_PRESENT(HandleInformation)) {

                        HandleInformation->GrantedAccess = GrantedAccess;
                        HandleInformation->HandleAttributes = 0;
                    }

                    ObpIncrPointerCount(ObjectHeader);//增加对象头的引用计数
                    *Object = Thread;//返回对象体指针

                    ASSERT( *Object != NULL );

                    Status = STATUS_SUCCESS;

                } else {

                    Status = STATUS_ACCESS_DENIED;
                }

            } else {

                Status = STATUS_OBJECT_TYPE_MISMATCH;
            }

            return Status;

        } else if (AccessMode == KernelMode)//如果是在内核模式调用的
                            {
            //
            // Make the handle look like a regular handle
            //

            Handle = DecodeKernelHandle( Handle );

            //
            // The global kernel handle table
            //

            HandleTable = ObpKernelHandleTable;
        } else {
            //
            // The previous mode was user for this kernel handle value. Reject it here.
            //

            return STATUS_INVALID_HANDLE;
        }

    } else {
        HandleTable = PsGetCurrentProcessByThread(Thread)->ObjectTable;//否则的话等于当前调用进程的句柄表
    }

    ASSERT(HandleTable != NULL);

    //
    // Protect this thread from being suspended while we hold the handle table entry lock
    //

    KeEnterCriticalRegionThread(&Thread->Tcb);

    //
    // Translate the specified handle to an object table index.
    //

    ObjectTableEntry = ExMapHandleToPointerEx ( HandleTable, Handle, AccessMode );//得到Handle_Table_Entry结构指针

    //
    // Make sure the object table entry really does exist
    //

    if (ObjectTableEntry != NULL) {

        ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES);//得到对象头

        //
        // Optimize for a successful reference by bringing the object header
        // into the cache exclusive.
        //

        ReadForWriteAccess(ObjectHeader);
        if ((ObjectHeader->Type == ObjectType) || (ObjectType == NULL)) {

#if i386 
            if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {

                GrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex );

            } else {

                GrantedAccess = ObpDecodeGrantedAccess(ObjectTableEntry->GrantedAccess);
            }
#else
            GrantedAccess = ObpDecodeGrantedAccess(ObjectTableEntry->GrantedAccess);

#endif // i386

            if ((SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
                (AccessMode == KernelMode)) {

                PHANDLE_TABLE_ENTRY_INFO ObjectInfo;

                ObjectInfo = ExGetHandleInfo(HandleTable, Handle, TRUE);

                //
                // Access to the object is allowed. Return the handle
                // information is requested, increment the object
                // pointer count, unlock the handle table and return
                // a success status.
                //
                // Note that this is the only successful return path
                // out of this routine if the user did not specify
                // the current process or current thread in the input
                // handle.
                //

                if (ARGUMENT_PRESENT(HandleInformation)) {

                    HandleInformation->GrantedAccess = GrantedAccess;
                    HandleInformation->HandleAttributes = ObpGetHandleAttributes(ObjectTableEntry);
                }

                //
                // If this object was audited when it was opened, it may
                // be necessary to generate an audit now. Check the audit
                // mask that was saved when the handle was created.
                //
                // It is safe to do this check in a non-atomic fashion,
                // because bits will never be added to this mask once it is
                // created.
                //

                if ( (ObjectTableEntry->ObAttributes & OBJ_AUDIT_OBJECT_CLOSE) &&
                     (ObjectInfo != NULL) &&
                     (ObjectInfo->AuditMask != 0) &&
                     (DesiredAccess != 0)) {

                      
                      ObpAuditObjectAccess( Handle, ObjectInfo, &ObjectHeader->Type->Name, DesiredAccess );
                }

                ObpIncrPointerCount(ObjectHeader);

                ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );

                KeLeaveCriticalRegionThread(&Thread->Tcb);

                *Object = &ObjectHeader->Body;

                ASSERT( *Object != NULL );

                return STATUS_SUCCESS;

            } else {

                Status = STATUS_ACCESS_DENIED;
            }

        } else {

            Status = STATUS_OBJECT_TYPE_MISMATCH;
        }

        ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );

    } else {

        Status = STATUS_INVALID_HANDLE;
    }

    KeLeaveCriticalRegionThread(&Thread->Tcb);


    return Status;
}


« 上一篇:wifi共享上网(至尊版wifi)
« 下一篇:drcom至尊版使用openwrt路由器拨号
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img