目标进程用户模式句柄转换为内核句柄
网上很多方法都是Ring0内核进程和句柄互相转换的方法,查了一下没怎么看到说怎么将用户模式句柄转换为内核句柄的。如果内核获取到的是目标进程的句柄,拷贝到内核模式是不能直接使用的,会引发异常。
目前想到的实现思路是:
- 如果是伪句柄,直接返回后面再来处理。
- 调用
ObReferenceObjectByHandle
指定用户模式句柄获取任意对象的体指针 (EProcess、EThread )
- 调用
ObOpenObjectByPointer
打开指针所引用的对象,并返回对象的句柄,此时设置为内核句柄。就获取到啦。
本人是菜鸟,各位师傅如果知道其他的方法跪求指点!!!
实现代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| NTSTATUS ConvertKernelHandle( IN HANDLE UserHandle, OUT PHANDLE KernelHandle, POBJECT_TYPE ObjectType ) { NTSTATUS Status = STATUS_SUCCESS; PVOID Object = NULL; LONG v1 = (LONG)UserHandle;
if (KernelHandle == NULL) { Status = STATUS_INVALID_PARAMETER; goto Exit; }
if (v1 <= 0) { *KernelHandle = UserHandle; Status = STATUS_SUCCESS; goto Exit; }
Status = ObReferenceObjectByHandle( UserHandle, 0, ObjectType, UserMode, &Object, NULL );
if (Status != STATUS_SUCCESS) { goto Exit; }
Status = ObOpenObjectByPointer( Object, OBJ_KERNEL_HANDLE, 0, 0, NULL, KernelMode, KernelHandle );
if (*KernelHandle == UserHandle) { Status = STATUS_UNSUCCESSFUL; }
Exit: if (Object != NULL) { ObDereferenceObject(Object); }
return Status; }
|
伪句柄转换为真实句柄,可以调用复制对象句柄的DuplicateHandle
。
1 2 3 4 5 6 7 8 9
| BOOL DuplicateHandle( [in] HANDLE hSourceProcessHandle, [in] HANDLE hSourceHandle, [in] HANDLE hTargetProcessHandle, [out] LPHANDLE lpTargetHandle, [in] DWORD dwDesiredAccess, [in] BOOL bInheritHandle, [in] DWORD dwOptions );
|
微软官方在对此函数的解释中,说明了如果 hSourceHandle 是伪句柄, 会将其转换为进程或线程的实际句柄。
参考
ObOpenObjectByPointer 函数 (ntifs.h) - Windows drivers | Microsoft Learn
ObReferenceObjectByHandle 函数 (wdm.h) - Windows drivers | Microsoft Learn
DuplicateHandle 函数 (handleapi.h) - Win32 apps | Microsoft Learn
伪句柄转换为真正的句柄 - 沉疴 - 博客园 (cnblogs.com)