• ObReferenceObjectByHandle内核函数


    大槪就是看这个句柄是当前进程的句柄还是当前线程的句柄,最后再看看这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;
    }

  • 相关阅读:
    如何阅读大型代码库?
    发现一个时隐时现的bug!
    写给开发者:记录日志的10个建议
    教你一眼认出英语单词的意思
    为什么我要使用一个20年前的IBM老键盘
    有了screen,妈妈再也不用担心我的学习啦
    一次优秀的代码提交应该包含什么?
    你需要的不是重构,而是理清业务逻辑
    Android中监听ListView滑动到底部
    Android中的Handler,Looper,Message机制
  • 原文地址:https://www.cnblogs.com/guanlaiy/p/2594543.html
Copyright © 2020-2023  润新知