NTSTATUS
ObpReferenceProcessObjectByHandle (
IN HANDLE Handle,
...... OUT PVOID *Object,
......
) {
//获取当前线程
Thread = PsGetCurrentThread ();
*Object = NULL;
// HANDLE为负数 说明才是内核使用句柄? if ((LONG)(ULONG_PTR) Handle < 0) {
//句柄就是当前进程 直接获取进程的对象头 增加引用计数并返回PROCESS即可
if (Handle == NtCurrentProcess()) { GrantedAccess = Process->GrantedAccess; ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process); HandleInformation->GrantedAccess = GrantedAccess;
HandleInformation->HandleAttributes = 0; *AuditMask = 0; ObpIncrPointerCount(ObjectHeader);
*Object = Process; ASSERT( *Object != NULL ); Status = STATUS_SUCCESS; return Status; //如果句柄是当前线程 也是增加引用计数和返回线程即可
} else if (Handle == NtCurrentThread()) { GrantedAccess = Thread->GrantedAccess; ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread); HandleInformation->GrantedAccess = GrantedAccess;
HandleInformation->HandleAttributes = 0; *AuditMask = 0; ObpIncrPointerCount(ObjectHeader);
*Object = Thread; ASSERT( *Object != NULL ); Status = STATUS_SUCCESS; return Status; } else if (AccessMode == KernelMode) {
//
// 除开上述两种情况 如果是在内核模式下调用此函数的话 // Handle = DecodeKernelHandle( Handle ); // 解析内核句柄 // #define EncodeKernelHandle(H) (HANDLE)(KERNEL_HANDLE_MASK | (ULONG_PTR)(H)) // #define DecodeKernelHandle(H) (HANDLE)(KERNEL_HANDLE_MASK ^ (ULONG_PTR)(H))
// 句柄表是内核句柄表 即SYSTEM句柄表 HandleTable = ObpKernelHandleTable;
} else { ...... }
//
// 之后进入线程的EnterCriticalRegion // // Translate the specified handle to an object table index.
// 将句柄翻译成句柄表项 ExMapHandleToPointer 是此函数重点 ObjectTableEntry = ExMapHandleToPointer ( HandleTable, Handle ); // 有了句柄表项就获取对象头 增加引用计数和文件头BODY部分复制到OBJECT参数传出。 ........
return Status;
} NTKERNELAPI
PHANDLE_TABLE_ENTRY
ExMapHandleToPointer ( )主要 通过句柄索引在句柄表中查找句柄表项 HandleTableEntry = ExpLookupHandleTableEntry( HandleTable,
LocalHandle ); PHANDLE_TABLE_ENTRY
ExpLookupHandleTableEntry (
IN PHANDLE_TABLE HandleTable,
IN EXHANDLE tHandle
){ CapturedTable = *(volatile ULONG_PTR *) &HandleTable->TableCode;
TableLevel = (ULONG)(CapturedTable & LEVEL_CODE_MASK); // 这样就可以知道句柄表是1层表 还是2层表 还是3层表 //下面是SWITCH CASE结构来根据几层表来计算其在稀疏数组的偏移,返回我们需要的句柄表项 //句柄表内存分配是按页面大小4K来分配 一个句柄表项是8B 所以每申请一个页面来存放句柄表项就是增加512个句柄表项
//} ObpReferenceProcessObjectByHandle 整个流程就是分析给出句柄是否是当前的进程或者线程 然后直接返回CURRENTTHREAD或者CURRENTPROCESS ,否则获取句柄表进行查询,通过句柄与对象的对应关系返回对应对象指针。注意此函数增加了引用计数,所以还需要解引用。(省略权限检测等过程)
ObpReferenceProcessObjectByHandle 学习
最新推荐文章于 2023-07-16 19:03:01 发布