内核句柄和用户句柄
内核句柄的值有KERNEL_HANDLE_MASK标识(小于0),用户句柄的值没有KERNEL_HANDLE_MASK(大于0)。
ObReferenceObjectByHandle
当句柄值不含有KERNEL_HANDLE_MASK标志时(用户句柄)
当句柄值为-1或-2时
当句柄值含有KERNEL_HANDLE_MASK标志时(内核句柄)
内核中使用ObReferenceObjectByHandle获取Object
在内核中不能利用3环的handle来获取Object
ObReferenceObject在执行到SuccessToHandleTable后,通过调用ExMapHandleToPointerEx函数来得到对应的Object。
ExMapHandleToPointerEx函数通过调用ExpLookupHandleTableEntry从句柄表HandleTable里寻找Object
ExpLookupHandleTableEntry函数会清除Handle的属性位后,判断handle的值是否大于句柄表中最大的句柄值。
(如果使用3环的句柄值,一直都会判断handle的值大于句柄表中最大的句柄值)
到最后ExMapHandleToPointerEx就会返回0,导致ObReferenceObjectByHandle返回0xC0000008(STATUS_INVALID_HANDLE)。
在内核中利用0环的handle(内核handle)来获取Object
以文件对象为例:利用文件对象名称获得对应的内核句柄,然后通过内核句柄获取对应的文件对象Object。
IO_STATUS_BLOCK IoStatusBlock = { 0 };
NTSTATUS Status;
//通过对象名称,得到对象内核句柄
InitializeObjectAttributes(
&TempObjectAttributes,
In_ObjectAttributes->ObjectName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
TempRootDirectory,
NULL
);
Status = IoCreateFile(FileHandle,
GENERIC_READ | SYNCHRONIZE,
&TempObjectAttributes,
&IoStatusBlock,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
0,
0,
CreateFileTypeNone,
0,
IO_NO_PARAMETER_CHECKING
);