win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

内核句柄和用户句柄

内核句柄的值有KERNEL_HANDLE_MASK标识(小于0),用户句柄的值没有KERNEL_HANDLE_MASK(大于0)。

ObReferenceObjectByHandle

当句柄值不含有KERNEL_HANDLE_MASK标志时(用户句柄)

win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

当句柄值为-1或-2时

win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

当句柄值含有KERNEL_HANDLE_MASK标志时(内核句柄)

win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

内核中使用ObReferenceObjectByHandle获取Object

在内核中不能利用3环的handle来获取Object

ObReferenceObject在执行到SuccessToHandleTable后,通过调用ExMapHandleToPointerEx函数来得到对应的Object。
ExMapHandleToPointerEx函数通过调用ExpLookupHandleTableEntry从句柄表HandleTable里寻找Object

win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

ExpLookupHandleTableEntry函数会清除Handle的属性位后,判断handle的值是否大于句柄表中最大的句柄值。
(如果使用3环的句柄值,一直都会判断handle的值大于句柄表中最大的句柄值)

win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

到最后ExMapHandleToPointerEx就会返回0,导致ObReferenceObjectByHandle返回0xC0000008(STATUS_INVALID_HANDLE)。

win7 x86中ObReferenceObjectByHandle对内核句柄和用户句柄的处理

在内核中利用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
);

上一篇:Signal QQmlEngine::quit() emitted, but no receivers connected to handle it quit


下一篇:前端设计模式之状态模式