遍历系统中所有的驱动对象

admin · · Windows程序设计
1

本文共计3599个字,预计阅读时长14.4分钟。

原理 首先我们要知道驱动加载后, 会向对象目录表中的\driver 与\FileSystem 写入 驱动服务名, 那么我们只需要遍历这两张表拿到名称, 通过ObReferenceObjectByName函数即可获取驱动对象。而在这里我们可以使用微软提供的ZwQueryDirectoryObject函数获取对应的对象目录表。 遍历驱动代码 ``` auto EnumerateObject = [&](UNICODE_STRING* Directory) { NTSTATUS ntStatus = STATUS_SUCCESS; OBJECT_ATTRIBUTES ObjAttr = { 0 }; HANDLE FileHandle = 0; IO_STATUS_BLOCK IoStatusBlock = { 0 }; PVOID FileInformation = 0; ULONG Length = sizeof(FILE_DIRECTORY_INFORMATION); // 这个数设置的太小会导致ZwQueryDirectoryFile蓝屏。 UNICODE_STRING driverName = RTL_CONSTANT_STRING(L"Driver"); InitializeObjectAttributes(&ObjAttr, Directory, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); ntStatus = ZwOpenDirectoryObject(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjAttr); if (!NT_SUCCESS(ntStatus)) return ntStatus; Length = Length + 520; // 为何加这个数字,请看ZwEnumerateFile1的说明。 FileInformation = ExAllocatePool(NonPagedPool, Length); if (NULL == FileInformation) { ZwClose(FileHandle); return STATUS_UNSUCCESSFUL; } RtlZeroMemory(FileInformation, Length); BOOLEAN RestartScan; ULONG Context = 0; ULONG ReturnedLength = 0; do { UNICODE_STRING FileName = { 0 }; POBJECT_DIRECTORY_INFORMATION podi = 0; UNICODE_STRING FullName = { 0 }; RestartScan = FALSE; // 为TRUE会导致死循环; ntStatus = ZwQueryDirectoryObject(FileHandle, FileInformation, Length, TRUE, RestartScan, &Context, &ReturnedLength); if (STATUS_NO_MORE_FILES != ntStatus && STATUS_SUCCESS != ntStatus) return ntStatus; podi = (POBJECT_DIRECTORY_INFORMATION)FileInformation; // 不是驱动对象就放过。 if (RtlCompareUnicodeString(&podi->TypeName, &driverName, TRUE) != 0) { continue; } // 申请要显示的内存,另一思路是格式化。 FullName.MaximumLength = (USHORT)Length + Directory->MaximumLength; FullName.Buffer = (PWCH)ExAllocatePool(NonPagedPool, FullName.MaximumLength); if (NULL == FullName.Buffer) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; break; } RtlZeroMemory(FullName.Buffer, FullName.MaximumLength); RtlCopyUnicodeString(&FullName, Directory); ntStatus = RtlAppendUnicodeToString(&FullName, L"\\"); if (!NT_SUCCESS(ntStatus)) { ExFreePool(FullName.Buffer); break; } ntStatus = RtlAppendUnicodeStringToString(&FullName, &podi->Name); if (!NT_SUCCESS(ntStatus)) { ExFreePool(FullName.Buffer); break; } //DBG_PRINT("Name %wZ\n", &FullName); PDRIVER_OBJECT DriverObject = nullptr; /* 对比查找 */ ntStatus = ObReferenceObjectByName( &FullName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, FILE_ANY_ACCESS, *IoDriverObjectType, KernelMode, NULL, (PVOID*)&DriverObject ); if (NT_SUCCESS(ntStatus)) { /* Add */ Mylist->push(DriverObject); } ExFreePool(FullName.Buffer); } while (STATUS_NO_MORE_FILES != ntStatus); if (STATUS_NO_MORE_FILES == ntStatus) ntStatus = STATUS_SUCCESS; if (FileInformation) { ExFreePool(FileInformation); FileInformation = NULL; } ZwClose(FileHandle); return ntStatus; }; ``` 测试用例 分别遍历 driver 与 FileSystem 两个目录 ``` UNICODE_STRING directory = RTL_CONSTANT_STRING(L"\\driver"); UNICODE_STRING FileSystem = RTL_CONSTANT_STRING(L"\\FileSystem"); ntStatus = EnumerateObject(&directory); ntStatus = EnumerateObject(&FileSystem); ```

最新回复 ( 1 )
全部楼主