Win64 驱动内核编程-25.X64枚举和隐藏内核模块
生活随笔
收集整理的这篇文章主要介绍了
Win64 驱动内核编程-25.X64枚举和隐藏内核模块
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
X64枚举和隐藏内核模块
在 WIN64 上枚举内核模块的人方法:使用 ZwQuerySystemInformation 的第 11 号功能和枚举 KLDR_DATA_TABLE_ENTRY 中的 InLoadOrderLinks 双向链表;隐藏内核模块的通用方法是把指定的驱动对象从 KLDR_DATA_TABLE_ENTRY中的 InLoadOrderLinks 双向链表上摘除。
X64内核模块枚举(注意是在R3)
#include <stdio.h> #include <Windows.h>typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION) (IN ULONG SystemInformationClass,OUT PVOID SystemInformation,IN ULONG Length,OUT PULONG ReturnLength );typedef unsigned long DWORD;typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {ULONG Unknow1;ULONG Unknow2;ULONG Unknow3;ULONG Unknow4;PVOID Base;ULONG Size;ULONG Flags;USHORT Index;USHORT NameLength;USHORT LoadCount;USHORT ModuleNameOffset;char ImageName[256]; } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;typedef struct _SYSTEM_MODULE_INFORMATION {ULONG Count;//内核中以加载的模块的个数SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;BOOLEAN EnumKM(char *HighlightDrvName) {ULONG NeedSize, i, ModuleCount, HLed=0, BufferSize = 0x5000;PVOID pBuffer = NULL;PCHAR pDrvName = NULL;NTSTATUS Result;PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;do{//分配内存pBuffer = malloc( BufferSize );if( pBuffer == NULL )return 0;//查询模块信息Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );if( Result == 0xC0000004L ){free( pBuffer );BufferSize *= 2;}else if( Result<0 ){//查询失败则退出free( pBuffer );return 0;}}while( Result == 0xC0000004L );pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;//获得模块的总数量ModuleCount = pSystemModuleInformation->Count;//遍历所有的模块for( i = 0; i < ModuleCount; i++ ){if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000){pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;printf("0x%llx\t%s",(ULONG64)pSystemModuleInformation->Module[i].Base,pDrvName);if( _stricmp(pDrvName,HighlightDrvName)==0 ){printf("\t\t<--------------------");HLed=1;}printf("\n");}}if(HLed==0)printf("\n[%s] NOT FOUND!",HighlightDrvName);free(pBuffer);return 1; }int main() { ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(LoadLibraryW(L"ntdll.dll"),"ZwQuerySystemInformation");EnumKM("win32k.sys");getchar();return 0; }然后是R0 隐藏内核模块,摘链问题。也就是要注意结构定义细节就行了。 #include <ntddk.h>#define kprintf DbgPrint #define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ') #define kfree(_p) ExFreePool(_p)NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation (IN ULONG SystemInformationClass,OUT PVOID SystemInformation,IN ULONG Length,OUT PULONG ReturnLength );typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {ULONG Unknow1;ULONG Unknow2;ULONG Unknow3;ULONG Unknow4;PVOID Base;ULONG Size;ULONG Flags;USHORT Index;USHORT NameLength;USHORT LoadCount;USHORT ModuleNameOffset;char ImageName[256]; } SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;typedef struct _SYSTEM_MODULE_INFORMATION {ULONG Count;//内核中以加载的模块的个数SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;typedef struct _KLDR_DATA_TABLE_ENTRY {LIST_ENTRY64 InLoadOrderLinks;ULONG64 __Undefined1;ULONG64 __Undefined2;ULONG64 __Undefined3;ULONG64 NonPagedDebugInfo;ULONG64 DllBase;ULONG64 EntryPoint;ULONG SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT __Undefined5;ULONG64 __Undefined6;ULONG CheckSum;ULONG __padding1;ULONG TimeDateStamp;ULONG __padding2; }KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;PDRIVER_OBJECT pDriverObject = NULL;ULONG64 GetSystemModuleBase(char* lpModuleName) {ULONG NeedSize, i, ModuleCount, BufferSize = 0x5000;PVOID pBuffer = NULL;PCHAR pDrvName = NULL;NTSTATUS Result;PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;do{//分配内存pBuffer = kmalloc( BufferSize );if( pBuffer == NULL )return 0;//查询模块信息Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );if( Result == STATUS_INFO_LENGTH_MISMATCH ){kfree( pBuffer );BufferSize *= 2;}else if( !NT_SUCCESS(Result) ){//查询失败则退出kfree( pBuffer );return 0;}}while( Result == STATUS_INFO_LENGTH_MISMATCH );pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;//获得模块的总数量ModuleCount = pSystemModuleInformation->Count;//遍历所有的模块for( i = 0; i < ModuleCount; i++ ){if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000){pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;if( _stricmp(pDrvName,lpModuleName)==0 )return (ULONG64)pSystemModuleInformation->Module[i].Base;}}kfree(pBuffer);return 0; }VOID HideDriver(char *pDrvName) {PKLDR_DATA_TABLE_ENTRY entry=(PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;PKLDR_DATA_TABLE_ENTRY firstentry;ULONG64 pDrvBase=0;KIRQL OldIrql;firstentry = entry;pDrvBase = GetSystemModuleBase(pDrvName);while((PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink != firstentry){if( entry->DllBase==pDrvBase ){//typedef struct LIST_ENTRY64 {// ULONGLONG Flink;// ULONGLONG Blink;//} LIST_ENTRY64;//typedef LIST_ENTRY64 *PLIST_ENTRY64;//le->Flink->Blink=le->Blink;//le->Blink->Flink=le->Flink;OldIrql = KeRaiseIrqlToDpcLevel();((LIST_ENTRY64*)(entry->InLoadOrderLinks.Flink))->Blink=entry->InLoadOrderLinks.Blink;((LIST_ENTRY64*)(entry->InLoadOrderLinks.Blink))->Flink=entry->InLoadOrderLinks.Flink;entry->InLoadOrderLinks.Flink=0;entry->InLoadOrderLinks.Blink=0;KeLowerIrql(OldIrql);DbgPrint("Remove LIST_ENTRY64 OK!");break;}//kprintf("%llx\t%wZ\t%wZ",entry->DllBase,entry->BaseDllName,entry->FullDllName);entry = (PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink;} }NTSTATUS UnloadDriver(IN PDRIVER_OBJECT DriverObject) {return STATUS_SUCCESS; }NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {DriverObject->DriverUnload = UnloadDriver;pDriverObject = DriverObject;HideDriver("win32k.sys"); //hidekm64.sysreturn STATUS_SUCCESS; }
总结
以上是生活随笔为你收集整理的Win64 驱动内核编程-25.X64枚举和隐藏内核模块的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Win64 驱动内核编程-24.64位驱
- 下一篇: Win64 驱动内核编程-26.强制结束