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 來為對象指針交換用戶模式句柄:
|
||||||||
• | 創建在內核模式中使用的句柄之前,調用 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); }