您的位置:首页 > Web前端

(转) ObReferenceObjectByHandle 的使用

2012-12-28 10:52 633 查看
http://blog.sina.com.cn/s/blog_62a630640100gost.html

NTSTATUS ObReferenceObjectByHandle(
IN HANDLE Handle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
OUT PVOID *Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation
);


  这个函数的目的是:根据提供的 Handle 值得到 Object!

  调用方传递给驱动程序的句柄不会经过 I/O 管理器,因此 I/O 管理器不对这类句柄执行任何验证检查。决不要假设一个句柄有效;始终确保句柄拥有正确的对象类型、对于所需任务的合适的访问权、正确的访问模式,并且访问模式与请求的访问兼容。

  驱动程序应该谨慎使用句柄,特别是那些从用户模式应用程序接收到的句柄。
  第一,这种句柄特定于进程上下文,因此它们仅在打开句柄的进程中有效。当从不同的进程上下文或工作线程使用时,句柄可以引用不同的对象或者只是变得无效。
  第二,在驱动程序使用句柄期间,攻击者可以关闭和重新打开句柄来改变其引用的内容。
  第三,攻击者可以传入这样一个句柄来引诱驱动程序执行对于应用程序非法的操作,例如调用 ZwXxx 函数。对于这些函数的内核模式调用方,访问检查被跳过,因此攻击者可以使用这种机制绕过验证。

  驱动程序还应该确保用户模式应用程序不能误用驱动程序创建的句柄。为一个句柄设置 OBJ_KERNEL_HANDLE 属性使其成为内核句柄,内核句柄可以在任何进程上下文中使用,但是只能从内核模式进行访问(对于传递给ZwXxx 例程的句柄,这特别重要)。用户模式的进程不能访问、关闭或替换内核句柄。

您应该做什么?

接收到任何句柄之后,立即调用 ObReferenceObjectByHandle 来为对象指针交换用户模式句柄:

始终指定期望的对象类型,从而您可以使用 ObReferenceObjectByHandle 提供的类型检查。

对于用户模式句柄,将 AccessMode 指定为 UserMode(假设期望用户对文件对象的访问权限与您的驱动程序相同)。

始终检查 ObReferenceObjectByHandle 返回的状态码,并且当它为 STATUS_SUCCESS 时进行处理。

当您完成对 ObReferenceObjectByHandle 提供的对象指针的使用时,调用 ObDereferenceObject 来释放指针并避免资源泄漏。

创建在内核模式中使用的句柄之前,调用 InitializeObjectAttributes 来初始化一个 OBJECT_ATTRIBUTES 结构,其中Attributes 值设置为 OBJ_KERNEL_HANDLE。

下列代码片段显示 ObReferenceObjectByHandle 的正确用法,在这个例子中为一个事件的句柄。

NTSTATUS    status;
PKEVENT      userEvent;
HANDLE        handle;

handle = RetrieveHandleFromIrpBuffer(…);
status = ObReferenceObjectByHandle(handle,
EVENT_MODIFY_STATE,
*ExEventObjectType,
UserMode,
(PVOID*) &userEvent,
NULL);
if (NT_SUCCESS(status))
{
// do something interesting here
KeSetEvent(userEvent, IO_NO_INCREMENT, FALSE);
ObDereferenceObject(userEvent);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: