Dissecting the Windows Kernel - 关于ObReferenceObjectByHandle中对句柄的处理(二)
ObpIncrPointerCount(ObjectHeader);
*Object = Process;
ASSERT( *Object!= NULL );
Status = STATUS_SUCCESS;
} else {
Status = STATUS_ACCESS_DENIED;
}
} else {
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
returnStatus;
} elseif (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;
}
returnStatus;
} elseif (AccessMode== KernelMode) {
//
//这里才是真正处理内核句柄的地方。
//注意:内核句柄只能在内核模式访问。
//#define KERNEL_HANDLE_MASK\
// ((ULONG_PTR)((LONG)0x80000000))
//#define EncodeKernelHandle(H) \
// (HANDLE)(KERNEL_HANDLE_MASK | (ULONG_PTR)(H))
//#define DecodeKernelHandle(H) \
// (HANDLE)(KERNEL_HANDLE_MASK ^ (ULONG_PTR)(H))
//内核句柄是还KERNEL_HANDLE_MASK标识的(即最高位为1)。
//记住,这里的Handle不是一个真正的Handle,
// 在使用前必须转化成正规Handle。
//这里的DecodeKernelHandle就是将最高位的标识去除。
//
Handle = DecodeKernelHandle(Handle );
//
// 这里得到的句柄表就是全局的内核句柄表ObpKernelHandleTable。
//
HandleTable = ObpKernelHandleTable;
} else{
//
//The previous mode was user for this kernel handle value.
//Reject it here.
//
returnSTATUS_INVALID_HANDLE;
}
} else{
//
// 如果Handle大于0(即没有KERNEL_HANDLE_MASK标识),
// 说明不是System进程的句柄,
// 就从当前ETHREAD得到EPROCESS,从而得到HandleTable。
//
//#definePsGetCurrentProcessByThread(xCurrentThread) \
// (ASSERT((xCurrentThread) == PsGetCurrentThread()),\
// CONTAINING_RECORD(\
// ((xCurrentThread)->Tcb.ApcState.Process),\
// EPROCESS,Pcb))
//
HandleTable= PsGetCurrentProcessByThread(Thread)->ObjectTable;
}
//
// 这之后便是在得到的HandleTable里查找ObjectHeader和Object。
//
// 以下代码引用省略……
//
returnStatus;
}
从以上代码可以看出:在Windows XP 32位下无论从何种途径获取到的内核句柄(最高位有或没有KERNEL_HANDLE_MASK标识),在正确Attach到内核句柄和内核句柄表所在的System 进程,通过ObR