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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Win64 驱动内核编程-13.回调监控模块加载

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

回調(diào)監(jiān)控模塊加載

????模塊加載包括用戶層模塊(.DLL)和內(nèi)核模塊(.SYS)的加載。傳統(tǒng)方法要監(jiān)控這兩者加在必須?HOOK?好幾個函數(shù),比如?NtCreateSection?和?NtLoadDriver

等,而且這些方法還不能監(jiān)控未知的驅(qū)動加載方法。其實為了監(jiān)控模塊加載而HOOK?API?是非常傻的,因為微軟已經(jīng)提供了一對標(biāo)準(zhǔn)的?API?實現(xiàn)此功能。它們

分別是?PsSetLoadImageNotifyRoutine?和?PsRemoveLoadImageNotifyRoutine可以設(shè)置/取消一個“映像加載通告例程”,當(dāng)有驅(qū)動或者?DLL?被加載時,回調(diào)函

數(shù)就會被調(diào)用。有人可能認(rèn)為這個標(biāo)準(zhǔn)方法的監(jiān)控非常表層,其實恰恰相反,這個方法非常底層,大部分隱秘的加載驅(qū)動的方法都可以繞過?NtLoadDriver,但

是無法繞過“映像加載通告例程”。所以用此方法監(jiān)控驅(qū)動加載是最合適的了。

????之前說過,這個通告例程不僅僅管加載驅(qū)動,連進(jìn)程加載?DLL?也管,那我們怎么判斷到底是加載驅(qū)動還是加載?DLL?呢?如果說根據(jù)后綴名判斷則很明顯是一個挫方法。我的方

法是,?根據(jù)回調(diào)函數(shù)?e?LoadImageNotifyRoutine??的第二個參數(shù)判斷,如果?D?PID??0?0?,則表示加載驅(qū)動,如果?D?PID??位非零,則?表示加載??DLL?。原因很簡單,我之前說過這個函數(shù)很底層,到了一定的深度之后就無法判斷到底是誰主動引發(fā)的行為了,一切都是系統(tǒng)的行為。當(dāng)然,你也可以認(rèn)為這是通過回調(diào)來監(jiān)控驅(qū)動加載的缺點(diǎn)。判斷了是驅(qū)動后,就通過?ImageInfo->ImageBase?來獲取驅(qū)動的映像基址。過?如果不想讓這個驅(qū)動加載,就通過?e?ImageBase?得?來獲得?y?DriverEntry??的地址(ImageBase?就是?DOS?頭,根據(jù)?DOS?頭找到?NT?頭,然后在?NT?頭的?OptionalHeader里就能找到入口點(diǎn)了。入口點(diǎn)的數(shù)據(jù)就是?DriverEntry?的地址)?,?并?寫入?“拒絕訪問?”?的機(jī)器碼?即可。

//添加: PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine); //刪除: PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine);其中 NotifyRoutine 是一個函數(shù)指針,此回調(diào)函數(shù)的原型是: VOID (*PLOAD_IMAGE_NOTIFY_ROUTINE) ( __in_opt PUNICODE_STRING FullImageName, __in HANDLE ProcessId, __in PIMAGE_INFO ImageInfo ); 下面是實現(xiàn)模塊監(jiān)控,并且拒絕Powertool的驅(qū)動加載的例子代碼: #include <ntddk.h> #include <ntimage.h>#define dprintf DbgPrintBOOLEAN VxkCopyMemory( PVOID pDestination, PVOID pSourceAddress, SIZE_T SizeOfCopy ) {PMDL pMdl = NULL;PVOID pSafeAddress = NULL;pMdl = IoAllocateMdl( pSourceAddress, (ULONG)SizeOfCopy, FALSE, FALSE, NULL );if( !pMdl ) return FALSE;__try{MmProbeAndLockPages( pMdl, KernelMode, IoReadAccess );}__except(EXCEPTION_EXECUTE_HANDLER){IoFreeMdl( pMdl );return FALSE;}pSafeAddress = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority );if( !pSafeAddress ) return FALSE;RtlCopyMemory( pDestination, pSafeAddress, SizeOfCopy );MmUnlockPages( pMdl );IoFreeMdl( pMdl );return TRUE; }VOID UnicodeToChar(PUNICODE_STRING dst, char *src) {ANSI_STRING string;RtlUnicodeStringToAnsiString(&string,dst, TRUE);strcpy(src,string.Buffer);RtlFreeAnsiString(&string); }void DenyLoadDriver(PVOID DriverEntry) { UCHAR fuck[]="\xB8\x22\x00\x00\xC0\xC3"; VxkCopyMemory(DriverEntry,fuck,sizeof(fuck)); }PVOID GetDriverEntryByImageBase(PVOID ImageBase) { PIMAGE_DOS_HEADER pDOSHeader; PIMAGE_NT_HEADERS64 pNTHeader; PVOID pEntryPoint; pDOSHeader = (PIMAGE_DOS_HEADER)ImageBase; pNTHeader = (PIMAGE_NT_HEADERS64)((ULONG64)ImageBase + pDOSHeader->e_lfanew); pEntryPoint = (PVOID)((ULONG64)ImageBase + pNTHeader->OptionalHeader.AddressOfEntryPoint); return pEntryPoint; }VOID LoadImageNotifyRoutine (__in_opt PUNICODE_STRING FullImageName,__in HANDLE ProcessId,__in PIMAGE_INFO ImageInfo ) { PVOID pDrvEntry; char szFullImageName[260]={0}; if(FullImageName!=NULL && MmIsAddressValid(FullImageName)) { if(ProcessId==0) { DbgPrint("[MyDriver]%wZ\n", FullImageName); pDrvEntry=GetDriverEntryByImageBase(ImageInfo->ImageBase); DbgPrint("[MyDriver]DriverEntry: %p\n",pDrvEntry); UnicodeToChar(FullImageName,szFullImageName); if(strstr(_strlwr(szFullImageName),"kevp64.sys")) { DbgPrint("[MyDriver]Deny load [WIN64AST.SYS]"); //禁止加載win64ast.sys DenyLoadDriver(pDrvEntry); } } } }加載: PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine); 注銷: PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine);

????執(zhí)行結(jié)果,通過Pchunter看監(jiān)控當(dāng)前驅(qū)動信息,PowerTool驅(qū)動被拒絕加載之后不但自己沒有提示,而且還在桌面上留下了自己的驅(qū)動文件,這相當(dāng)于是你雙擊了一個exe,結(jié)果在exe入口函數(shù)的地方內(nèi)存編程不可操作了,這種很難檢測出問題來:



禁止加載驅(qū)動的方式也可以用來禁止加載dll


總結(jié)

以上是生活随笔為你收集整理的Win64 驱动内核编程-13.回调监控模块加载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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