遍历Windows操作系统的NDIS网络过滤驱动
字数 1412 2025-08-05 08:19:10

Windows NDIS网络过滤驱动遍历技术详解

导言

本文详细讲解如何遍历Windows操作系统中通过NdisFRegisterFilterDriver注册的轻量级网络过滤驱动(Light-weight filter, LWF)。这种技术适用于当你知道系统中存在某些网络过滤驱动但无法卸载时,如何识别并使其失效。

技术背景

NDIS(Network Driver Interface Specification)是Windows网络驱动架构的核心。网络过滤驱动通过NdisFRegisterFilterDriver注册后,会被加入到ndisFilterDriverList链表中。本文重点分析如何遍历这个链表来枚举所有已注册的过滤驱动。

关键数据结构

_NDIS_FILTER_DRIVER_BLOCK结构

这是NDIS过滤驱动的主要数据结构,包含以下关键字段:

_NDIS_FILTER_DRIVER_BLOCK
   +0x000 Header           : _NDIS_OBJECT_HEADER
   +0x008 NextFilterDriver : _NDIS_FILTER_DRIVER_BLOCK*  // 指向下一个过滤驱动
   +0x010 DriverObject     : _DRIVER_OBJECT*             // 驱动对象
   +0x018 FilterQueue      : _NDIS_FILTER_BLOCK*         // 过滤模块队列
   +0x020 FilterDriverContext : Void*                   // 驱动上下文
   +0x028 Lock             : ULONG
   +0x030 Flags            : ULONG
   +0x038 DeviceList       : _LIST_ENTRY
   +0x048 Ref              : _REFERENCE_EX
   +0x060 DefaultFilterCharacteristics : _NDIS_FILTER_DRIVER_CHARACTERISTICS
   +0x150 Bind             : KRef<NDIS_BIND_FILTER_DRIVER>
   +0x158 ImageName        : _UNICODE_STRING            // 驱动映像名称

_NDIS_FILTER_DRIVER_CHARACTERISTICS结构

包含过滤驱动注册的所有回调函数:

_NDIS_FILTER_DRIVER_CHARACTERISTICS
   +0x000 Header           : _NDIS_OBJECT_HEADER
   +0x004 MajorNdisVersion : UCHAR
   +0x005 MinorNdisVersion : UCHAR
   +0x006 MajorDriverVersion : UCHAR
   +0x007 MinorDriverVersion : UCHAR
   +0x008 Flags            : ULONG
   +0x010 FriendlyName     : _UNICODE_STRING            // 友好名称
   +0x020 UniqueName       : _UNICODE_STRING            // 唯一名称
   +0x030 ServiceName      : _UNICODE_STRING            // 服务名称
   // 以下为各种回调函数指针
   +0x040 SetOptionsHandler : PVOID
   +0x048 SetFilterModuleOptionsHandler : PVOID
   +0x050 AttachHandler    : PVOID
   +0x058 DetachHandler    : PVOID
   +0x060 RestartHandler   : PVOID
   +0x068 PauseHandler     : PVOID
   +0x070 SendNetBufferListsHandler : PVOID
   +0x078 SendNetBufferListsCompleteHandler : PVOID
   +0x080 CancelSendNetBufferListsHandler : PVOID
   +0x088 ReceiveNetBufferListsHandler : PVOID
   +0x090 ReturnNetBufferListsHandler : PVOID
   +0x098 OidRequestHandler : PVOID
   +0x0a0 OidRequestCompleteHandler : PVOID
   +0x0a8 CancelOidRequestHandler : PVOID
   +0x0b0 DevicePnPEventNotifyHandler : PVOID
   +0x0b8 NetPnPEventHandler : PVOID
   +0x0c0 StatusHandler    : PVOID
   +0x0c8 DirectOidRequestHandler : PVOID
   +0x0d0 DirectOidRequestCompleteHandler : PVOID
   +0x0d8 CancelDirectOidRequestHandler : PVOID
   +0x0e0 SynchronousOidRequestHandler : PVOID
   +0x0e8 SynchronousOidRequestCompleteHandler : PVOID

枚举原理

  1. NDIS在注册过滤驱动时会将驱动信息加入全局链表:

    Irql = KeAcquireSpinLockRaiseToDpc(&ndisFilterDriverListLock);
    FilterDriver->NextFilterDriver = ndisFilterDriverList;
    ndisFilterDriverList = FilterDriver;
    KeReleaseSpinLock(&ndisFilterDriverListLock, Irql);
    
  2. 枚举方法有两种:

    • 通过自己安装的过滤驱动获取句柄(_NDIS_FILTER_DRIVER_BLOCK*),然后遍历NextFilterDriver链表
    • 直接定位未导出的全局变量ndisFilterDriverList(_NDIS_FILTER_DRIVER_BLOCK*)
  3. 遍历时需要注意获取自旋锁ndisFilterDriverListLock以保证线程安全

实现代码

以下是关键代码实现:

#include "MiniDriver.h"

PKSPIN_LOCK ndisMiniDriverListLock;  // 自旋锁指针
PNDIS_M_DRIVER_BLOCK ndisMiniDriverList; // 驱动链表头指针

void DumpOneMiniDriverInfo(PNDIS_M_DRIVER_BLOCK MiniDriver) {
    // 打印驱动基本信息
    Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "NdisVersion:%d:%d", 
          MiniDriver->MiniportDriverCharacteristics.MajorNdisVersion, 
          MiniDriver->MiniportDriverCharacteristics.MinorNdisVersion);
    Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "DriverVersion:%d:%d", 
          MiniDriver->MiniportDriverCharacteristics.MajorDriverVersion, 
          MiniDriver->MiniportDriverCharacteristics.MinorDriverVersion);
    Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "Flags:%d", 
          MiniDriver->MiniportDriverCharacteristics.Flags);

    // 打印所有回调函数
    Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SetOptionsHandler:%p", 
          MiniDriver->MiniportDriverCharacteristics.SetOptionsHandler);
    Print(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "InitializeHandlerEx:%p", 
          MiniDriver->MiniportDriverCharacteristics.InitializeHandlerEx);
    // ... 其他回调函数打印
}

void DumpMiniDriverInfo() {
    if (!ndisMiniDriverListLock || !ndisMiniDriverList) {
        return;
    }

    // 获取自旋锁保证线程安全
    KIRQL Irql = KeAcquireSpinLockRaiseToDpc(ndisMiniDriverListLock);
    
    // 遍历链表
    for (PNDIS_M_DRIVER_BLOCK Tmp = ndisMiniDriverList; Tmp; Tmp = Tmp->NextDriver) {
        DumpOneMiniDriverInfo(Tmp);
    }
    
    // 释放自旋锁
    KeReleaseSpinLock(ndisMiniDriverListLock, Irql);
}

实际案例

通过WinDBG可以看到系统中常见的过滤驱动:

  1. QoS Packet Scheduler (pacer.sys)

    • 友好名称: "QoS Packet Scheduler"
    • 服务名称: "Psched"
    • 唯一名称: "{B5F4D659-7DAA-4565-8E41-BE220ED60542}"
  2. Virtual WiFi Filter Driver (vwififlt.sys)

    • 友好名称: "Virtual WiFi Filter Driver"
    • 服务名称: "vwififlt"
    • 唯一名称: "{5CBF81BF-5055-47CD-9055-A76B2B4E3698}"
  3. WFP相关驱动 (wfplwfs.sys)

    • WFP vSwitch Layers LightWeight Filter
    • WFP Native MAC Layer LightWeight Filter
    • WFP 802.3 MAC Layer LightWeight Filter

注意事项

  1. 遍历时需要获取自旋锁ndisFilterDriverListLock以保证线程安全
  2. 不同版本的Windows可能结构体偏移有所不同,需要根据实际情况调整
  3. 某些字段如回调函数指针可能为NULL,需要做空指针检查
  4. 在驱动开发中,需要正确处理IRQL级别

总结

通过分析NDIS内部数据结构,我们可以枚举系统中所有注册的网络过滤驱动,获取它们的详细信息,包括驱动名称、版本、注册的回调函数等。这项技术在安全分析、驱动开发和系统调试中都有重要应用价值。

参考资源

  1. AntiHook工具 - 实现本文技术的示例工具
  2. 安全客文章 - 关于WFP函数枚举的技术文章
Windows NDIS网络过滤驱动遍历技术详解 导言 本文详细讲解如何遍历Windows操作系统中通过 NdisFRegisterFilterDriver 注册的轻量级网络过滤驱动(Light-weight filter, LWF)。这种技术适用于当你知道系统中存在某些网络过滤驱动但无法卸载时,如何识别并使其失效。 技术背景 NDIS(Network Driver Interface Specification)是Windows网络驱动架构的核心。网络过滤驱动通过 NdisFRegisterFilterDriver 注册后,会被加入到 ndisFilterDriverList 链表中。本文重点分析如何遍历这个链表来枚举所有已注册的过滤驱动。 关键数据结构 _ NDIS_ FILTER_ DRIVER_ BLOCK结构 这是NDIS过滤驱动的主要数据结构,包含以下关键字段: _ NDIS_ FILTER_ DRIVER_ CHARACTERISTICS结构 包含过滤驱动注册的所有回调函数: 枚举原理 NDIS在注册过滤驱动时会将驱动信息加入全局链表: 枚举方法有两种: 通过自己安装的过滤驱动获取句柄(_ NDIS_ FILTER_ DRIVER_ BLOCK* ),然后遍历NextFilterDriver链表 直接定位未导出的全局变量 ndisFilterDriverList (_ NDIS_ FILTER_ DRIVER_ BLOCK* ) 遍历时需要注意获取自旋锁 ndisFilterDriverListLock 以保证线程安全 实现代码 以下是关键代码实现: 实际案例 通过WinDBG可以看到系统中常见的过滤驱动: QoS Packet Scheduler (pacer.sys) 友好名称: "QoS Packet Scheduler" 服务名称: "Psched" 唯一名称: "{B5F4D659-7DAA-4565-8E41-BE220ED60542}" Virtual WiFi Filter Driver (vwififlt.sys) 友好名称: "Virtual WiFi Filter Driver" 服务名称: "vwififlt" 唯一名称: "{5CBF81BF-5055-47CD-9055-A76B2B4E3698}" WFP相关驱动 (wfplwfs.sys) WFP vSwitch Layers LightWeight Filter WFP Native MAC Layer LightWeight Filter WFP 802.3 MAC Layer LightWeight Filter 注意事项 遍历时需要获取自旋锁 ndisFilterDriverListLock 以保证线程安全 不同版本的Windows可能结构体偏移有所不同,需要根据实际情况调整 某些字段如回调函数指针可能为NULL,需要做空指针检查 在驱动开发中,需要正确处理IRQL级别 总结 通过分析NDIS内部数据结构,我们可以枚举系统中所有注册的网络过滤驱动,获取它们的详细信息,包括驱动名称、版本、注册的回调函数等。这项技术在安全分析、驱动开发和系统调试中都有重要应用价值。 参考资源 AntiHook工具 - 实现本文技术的示例工具 安全客文章 - 关于WFP函数枚举的技术文章