日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Win64 驱动内核编程-33.枚举与删除对象回调

發(fā)布時間:2025/6/17 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Win64 驱动内核编程-33.枚举与删除对象回调 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

枚舉與刪除對象回調(diào)

????對象回調(diào)存儲在對應對象結(jié)構(gòu)體里,簡單來說,就是存儲在?ObjectType.?CallbackList?這

個雙向鏈表里。但對象結(jié)構(gòu)體在每個系統(tǒng)上都不一定相同。比如?WIN7X64?的結(jié)構(gòu)體如下:

ntdll!_OBJECT_TYPE

+0x000?TypeList?:?_LIST_ENTRY

+0x010?Name?:?_UNICODE_STRING

+0x020?DefaultObject?:?Ptr64?Void

+0x028?Index?:?UChar

+0x02c?TotalNumberOfObjects?:?Uint4B

+0x030?TotalNumberOfHandles?:?Uint4B

+0x034?HighWaterNumberOfObjects?:?Uint4B

+0x038?HighWaterNumberOfHandles?:?Uint4B

+0x040?TypeInfo?:?_OBJECT_TYPE_INITIALIZER

+0x0b0?TypeLock?:?_EX_PUSH_LOCK

+0x0b8?Key?:?Uint4B

+0x0c0?CallbackList?:?_LIST_ENTRY

?

Object.CallbackList->FLink?指向的地址,是一個結(jié)構(gòu)體鏈表,它的定義如下:

?

typedef?struct?_OB_CALLBACK

{

LIST_ENTRY??ListEntry;

ULONG64?Unknown;

ULONG64?ObHandle;

ULONG64?ObjTypeAddr;

ULONG64?PreCall;

ULONG64?PostCall;

}?OB_CALLBACK,?*POB_CALLBACK

?

微軟沒有公開這個結(jié)構(gòu)體的定義,這個結(jié)構(gòu)體是資料作者逆向出來的。但是至少在?WIN7、WIN8和?WIN8.1?上通用。知道了結(jié)構(gòu)體的定義,枚舉就方便了(WINDOWS?目前僅有進程對象回調(diào)和線程對象回調(diào),但就算以后有了其它回調(diào),也是通用的):

?

ULONG EnumObCallbacks() { ULONG c=0; PLIST_ENTRY CurrEntry=NULL; POB_CALLBACK pObCallback; BOOLEAN IsTxCallback; ULONG64 ObProcessCallbackListHead = *(ULONG64*)PsProcessType + ObjectCallbackListOffset; ULONG64 ObThreadCallbackListHead = *(ULONG64*)PsThreadType + ObjectCallbackListOffset; // dprintf("ObProcessCallbackListHead: %p\n",ObProcessCallbackListHead); CurrEntry=((PLIST_ENTRY)ObProcessCallbackListHead)->Flink; //list_head的數(shù)據(jù)是垃圾數(shù)據(jù),忽略 do { pObCallback=(POB_CALLBACK)CurrEntry; if(pObCallback->ObHandle!=0) { dprintf("ObHandle: %p\n",pObCallback->ObHandle); dprintf("PreCall: %p\n",pObCallback->PreCall); dprintf("PostCall: %p\n",pObCallback->PostCall); c++; } CurrEntry = CurrEntry->Flink; } while(CurrEntry != (PLIST_ENTRY)ObProcessCallbackListHead); // dprintf("ObThreadCallbackListHead: %p\n",ObThreadCallbackListHead); CurrEntry=((PLIST_ENTRY)ObThreadCallbackListHead)->Flink; //list_head的數(shù)據(jù)是垃圾數(shù)據(jù),忽略 do { pObCallback=(POB_CALLBACK)CurrEntry; if(pObCallback->ObHandle!=0) { dprintf("ObHandle: %p\n",pObCallback->ObHandle); dprintf("PreCall: %p\n",pObCallback->PreCall); dprintf("PostCall: %p\n",pObCallback->PostCall); c++; } CurrEntry = CurrEntry->Flink; } while(CurrEntry != (PLIST_ENTRY)ObThreadCallbackListHead); dprintf("ObCallback count: %ld\n",c); return c; }


執(zhí)行結(jié)果:

?

?

對付對象回調(diào),方法還是老三套

1.用?ObUnRegisterCallbacks?傳入?ObHandle?注銷回調(diào);

2.把記錄的回調(diào)函數(shù)地址改為自己的設置的空回調(diào);

3.給對方設置的回調(diào)函數(shù)地址寫入?RET。

????不過這次使用第三種方法要注意,必須先禁掉?PostCall,再禁用?PreCall,否則容易藍屏。

?

完整代碼:

?

#define dprintf DbgPrint#define DEVICE_NAME L"\\Device\\MyDriver" #define LINK_NAME L"\\DosDevices\\MyDriver" #define LINK_GLOBAL_NAME L"\\DosDevices\\Global\\MyDriver"ULONG NtBuildNumber=0; ULONG ObjectCallbackListOffset=0;typedef struct _OB_CALLBACK {LIST_ENTRY ListEntry;ULONG64 Unknown;ULONG64 ObHandle;ULONG64 ObjTypeAddr;ULONG64 PreCall;ULONG64 PostCall; } OB_CALLBACK, *POB_CALLBACK;BOOLEAN GetVersionAndHardCode() {BOOLEAN b=FALSE;RTL_OSVERSIONINFOW osi;osi.dwOSVersionInfoSize=sizeof(RTL_OSVERSIONINFOW);RtlFillMemory(&osi,sizeof(RTL_OSVERSIONINFOW),0);RtlGetVersion(&osi);NtBuildNumber=osi.dwBuildNumber;DbgPrint("NtBuildNumber: %ld\n",NtBuildNumber);switch (NtBuildNumber){case 7600:case 7601:{ObjectCallbackListOffset=0xC0;b=TRUE;break;}case 9200:{ObjectCallbackListOffset=0xC8; //OBJECT_TYPE.CallbackListb=TRUE;break;}case 9600:{ObjectCallbackListOffset=0xC8; //OBJECT_TYPE.CallbackListb=TRUE;break;}default:break;}return b; }KIRQL WPOFFx64() {KIRQL irql=KeRaiseIrqlToDpcLevel();UINT64 cr0=__readcr0();cr0 &= 0xfffffffffffeffff;__writecr0(cr0);_disable();return irql; }void WPONx64(KIRQL irql) {UINT64 cr0=__readcr0();cr0 |= 0x10000;_enable();__writecr0(cr0);KeLowerIrql(irql); }VOID DisableObcallbacks(PVOID Address) {KIRQL irql;CHAR patchCode[] = "\x33\xC0\xC3"; //xor eax,eax + retif(!Address)return;if(MmIsAddressValid(Address)){irql=WPOFFx64();memcpy(Address,patchCode,3);WPONx64(irql);} }ULONG EnumObCallbacks() {ULONG c=0;PLIST_ENTRY CurrEntry=NULL;POB_CALLBACK pObCallback;BOOLEAN IsTxCallback;ULONG64 ObProcessCallbackListHead = *(ULONG64*)PsProcessType + ObjectCallbackListOffset;ULONG64 ObThreadCallbackListHead = *(ULONG64*)PsThreadType + ObjectCallbackListOffset;//dprintf("ObProcessCallbackListHead: %p\n",ObProcessCallbackListHead);CurrEntry=((PLIST_ENTRY)ObProcessCallbackListHead)->Flink; //list_head的數(shù)據(jù)是垃圾數(shù)據(jù),忽略do{pObCallback=(POB_CALLBACK)CurrEntry;if(pObCallback->ObHandle!=0){dprintf("ObHandle: %p\n",pObCallback->ObHandle);dprintf("PreCall: %p\n",pObCallback->PreCall);dprintf("PostCall: %p\n",pObCallback->PostCall);c++;}CurrEntry = CurrEntry->Flink;}while(CurrEntry != (PLIST_ENTRY)ObProcessCallbackListHead);//dprintf("ObThreadCallbackListHead: %p\n",ObThreadCallbackListHead);CurrEntry=((PLIST_ENTRY)ObThreadCallbackListHead)->Flink; //list_head的數(shù)據(jù)是垃圾數(shù)據(jù),忽略do{pObCallback=(POB_CALLBACK)CurrEntry;if(pObCallback->ObHandle!=0){dprintf("ObHandle: %p\n",pObCallback->ObHandle);dprintf("PreCall: %p\n",pObCallback->PreCall);dprintf("PostCall: %p\n",pObCallback->PostCall);c++;}CurrEntry = CurrEntry->Flink;}while(CurrEntry != (PLIST_ENTRY)ObThreadCallbackListHead);dprintf("ObCallback count: %ld\n",c);return c; }

宋孖健,13

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的Win64 驱动内核编程-33.枚举与删除对象回调的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。