一个二进制文件中的两个过滤器驱动程序导致第二个驱动程序

时间:2016-08-25 15:22:44

标签: c windows networking driver ndis

我在同一个二进制文件中有两个NDIS过滤器驱动程序。这似乎基于this MSDN forum thread

我遇到了一个问题:使用NetCfg API成功安装了这两个驱动程序。但是,第二个安装的驱动程序不会启动。它会导致System error 2

C:\Program Files\Npcap>net start npcap
The requested service has already been started.

More help is available by typing NET HELPMSG 2182.


C:\Program Files\Npcap>net start npcap_wifi
System error 2 has occurred.


The system cannot find the file specified.

如果我先安装npcap_wifinpcap秒,则npcap服务无法启动。 DbgView显示永远不会调用第二个驱动程序DriverEntry。并且NetCfg API安装也不会显示任何错误。所以我不知道这里有什么问题?谢谢!

我的源代码:

第一个司机的INF是:npcap.inf。它使用服务名称npcap

第二个驱动程序的INF是:npcap_wifi.inf它使用服务名称npcap_wifi

共享二进制文件是:Packet.c。我使用DriverEntry' s RegistryPath来确定二进制文件运行的服务。

驱动程序安装程序为:NPFInstall.cpp。命令NPFInstall.exe -i用于安装第一个驱动程序,NPFInstall.exe -i2用于安装第二个驱动程序。

更新:

我已根据您的假服务方法修改了npcap.inf

;-------------------------------------------------------------------------
; NPCAP.INF -- Npcap NDIS 6.x LightWeight Filter Driver
;
; Copyright (c) 2015, Insecure.Com LLC.  All rights reserved.
;------------------------------------------------------------------------
[version]
Signature       = "$Windows NT$"
Class           = NetService
ClassGUID       = {4D36E974-E325-11CE-BFC1-08002BE10318}
CatalogFile     = %NPF_DriverName%.cat
Provider        = %Insecure%
DriverVer=05/15/2015,14.48.38.905


[Manufacturer]
%Insecure%=Insecure,NTx86,NTia64,NTamd64

[Insecure.NTx86]
%NPF_Desc_Standard%=FilterStandard, INSECURE_NPCAP
%NPF_Desc_WiFi%=FilterWiFi, INSECURE_NPCAP_WIFI

[Insecure.NTia64]
%NPF_Desc_Standard%=FilterStandard, INSECURE_NPCAP
%NPF_Desc_WiFi%=FilterWiFi, INSECURE_NPCAP_WIFI

[Insecure.NTamd64]
%NPF_Desc_Standard%=FilterStandard, INSECURE_NPCAP
%NPF_Desc_WiFi%=FilterWiFi, INSECURE_NPCAP_WIFI

;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[FilterStandard]
NetCfgInstanceId="{7daf2ac8-e9f6-4765-a842-f1f5d2501341}"
Copyfiles = npf.copyfiles.sys
Characteristics=0x40000
AddReg=FilterStandard.reg

[FilterWiFi]
NetCfgInstanceId="{7daf2ac8-e9f6-4765-a842-f1f5d2501351}"
Characteristics=0x40000
AddReg=FilterWiFi.reg

[SourceDisksNames]
1=%NPF_Desc_Standard%,"",,

[SourceDisksFiles]
npcap.sys=1

[DestinationDirs]
DefaultDestDir=12
npf.copyfiles.sys=12

[npf.copyfiles.sys]
%NPF_DriverName%.sys,,,2


;-------------------------------------------------------------------------
; Ndi installation support for the standard filter
;-------------------------------------------------------------------------
[FilterStandard.reg]
HKR, Ndi,Service,,%NPF_Filter_Name_Standard%
HKR, Ndi,CoServices,0x00010000,%NPF_Filter_Name_Standard%
HKR, Ndi,HelpText,,%NPF_HelpText%
HKR, Ndi,FilterClass,, compression


; For a Monitoring filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 1 ; Monitoring filter
; For a Modifying filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 2 ; Modifying filter
HKR, Ndi,FilterType,0x00010001,2


HKR, Ndi\Interfaces,UpperRange, , noupper
HKR, Ndi\Interfaces,LowerRange, , "ndis5,ndis4"


; TODO: Ensure that the list of media types below is correct.  Typically,
; filters include "ethernet".  Filters may also include "ppip" to include
; native WWAN stacks, but you must be prepared to handle the packet framing.
; Possible values are listed on MSDN, but common values include:
;     ethernet, wan, ppip, wlan
HKR, Ndi\Interfaces, FilterMediaTypes,,"ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"


; For a Mandatory filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 1 ; Mandatory filter
; For an Optional filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter
HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter


; By default, Mandatory filters unbind all protocols when they are
; installed/uninstalled, while Optional filters merely pause the stack.  If you
; would like to override this behavior, you can include these options.  These
; options only take effect with 6.30 filters on Windows "8" or later.
; To prevent a full unbind, and merely pause/restart protocols:
;     HKR, Ndi,UnbindOnAttach,0x00010001, 0 ; Do not unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 0 ; Do not unbind during FilterDetach
; To force a full unbind/bind (which includes pause/restart, of course):
;     HKR, Ndi,UnbindOnAttach,0x00010001, 1 ; Unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 1 ; Unbind during FilterDetach
;

;-------------------------------------------------------------------------
; Ndi installation support for the WiFi filter
;-------------------------------------------------------------------------
[FilterWiFi.reg]
HKR, Ndi,Service,,%NPF_Filter_Name_WiFi%
HKR, Ndi,CoServices,0x00010000,%NPF_Filter_Name_WiFi%
HKR, Ndi,HelpText,,%NPF_HelpText%
HKR, Ndi,FilterClass,, ms_medium_converter_128


; For a Monitoring filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 1 ; Monitoring filter
; For a Modifying filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 2 ; Modifying filter
HKR, Ndi,FilterType,0x00010001,2


HKR, Ndi\Interfaces,UpperRange, , noupper
HKR, Ndi\Interfaces,LowerRange, , "ndis5,ndis4"


; TODO: Ensure that the list of media types below is correct.  Typically,
; filters include "ethernet".  Filters may also include "ppip" to include
; native WWAN stacks, but you must be prepared to handle the packet framing.
; Possible values are listed on MSDN, but common values include:
;     ethernet, wan, ppip, wlan
HKR, Ndi\Interfaces, FilterMediaTypes,,"ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"


; For a Mandatory filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 1 ; Mandatory filter
; For an Optional filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter
HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter


; By default, Mandatory filters unbind all protocols when they are
; installed/uninstalled, while Optional filters merely pause the stack.  If you
; would like to override this behavior, you can include these options.  These
; options only take effect with 6.30 filters on Windows "8" or later.
; To prevent a full unbind, and merely pause/restart protocols:
;     HKR, Ndi,UnbindOnAttach,0x00010001, 0 ; Do not unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 0 ; Do not unbind during FilterDetach
; To force a full unbind/bind (which includes pause/restart, of course):
;     HKR, Ndi,UnbindOnAttach,0x00010001, 1 ; Unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 1 ; Unbind during FilterDetach
;

;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[FilterStandard.Services]
AddService=%NPF_Filter_Name_Standard%,,FilterStandard.svc

[FilterWiFi.Services]
AddService=%NPF_Filter_Name_WiFi%,,FilterWiFi.svc

[FilterStandard.svc]
DisplayName     = %NPF_Desc_Standard%
ServiceType     = 1 ;SERVICE_KERNEL_DRIVER
StartType       = 3 ;SERVICE_DEMAND_START
ErrorControl    = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary   = %12%\%NPF_DriverName%.sys
LoadOrderGroup  = NDIS
Description     = %NPF_Desc_Standard%
AddReg          = Common.Params.reg, NdisImPlatformBindingOptions.reg

[FilterWiFi.svc]
DisplayName     = %NPF_Desc_WiFi%
ServiceType     = 1 ;SERVICE_KERNEL_DRIVER
StartType       = 3 ;SERVICE_DEMAND_START
ErrorControl    = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary   = %12%\%NPF_DriverName%.sys
LoadOrderGroup  = NDIS
Description     = %NPF_Desc_WiFi%
AddReg          = Common.Params.reg, NdisImPlatformBindingOptions.reg

[FilterStandard.Remove.Services]
DelService=%NPF_Filter_Name_Standard%,0x200 ; SPSVCINST_STOPSERVICE

[FilterWiFi.Remove.Services]
DelService=%NPF_Filter_Name_WiFi%,0x200 ; SPSVCINST_STOPSERVICE

[Common.Params.reg]

[NdisImPlatformBindingOptions.reg]
HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,0 ; Subscribe to default behavior

[Strings]
NPF_DriverName = "npcap"
NPF_Filter_Name_Standard = "npcap"
NPF_Filter_Name_WiFi = "npcap_wifi"
Insecure = "Nmap Project"
NPF_Desc_Standard = "Npcap Packet Driver (NPCAP)"
NPF_Desc_WiFi = "Npcap Packet Driver (NPCAP) (Wi-Fi)"
NPF_HelpText = "A NDIS 6 filter driver & WFP callout driver to support packet capturing and sending under Windows 7, 8 & 10"

我的安装程序代码更改为:

HRESULT HrInstallNetComponent(IN INetCfg* pnc, IN LPCTSTR lpszComponentId, IN const GUID* pguidClass, IN LPCTSTR lpszInfFullPath)
{
    DWORD dwError;
    HRESULT hr = S_OK;
    TCHAR szDrive[_MAX_DRIVE];
    TCHAR szDir[_MAX_DIR];
    TCHAR szDirWithDrive[_MAX_DRIVE + _MAX_DIR];

    //
    // If full path to INF has been specified, the INF
    // needs to be copied using Setup API to ensure that any other files
    // that the primary INF copies will be correctly found by Setup API
    //
    if (lpszInfFullPath)
    {
        //
        // Get the path where the INF file is.
        //
        _tsplitpath(lpszInfFullPath, szDrive, szDir, NULL, NULL);

        _tcscpy(szDirWithDrive, szDrive);
        _tcscat(szDirWithDrive, szDir);

        //
        // Copy the Service INF file to the \Windows\Inf Folder
        //
        if (!SetupCopyOEMInfW(lpszInfFullPath, szDirWithDrive, // Other files are in the
            // same dir. as primary INF
            SPOST_PATH,    // First param is path to INF
            0,             // Default copy style
            NULL,          // Name of the INF after
            // it's copied to %windir%\inf
            0,             // Max buf. size for the above
            NULL,          // Required size if non-null
            NULL)          // Optionally get the filename
            // part of Inf name after it is copied.
           )
        {
            dwError = GetLastError();

            hr = HRESULT_FROM_WIN32(dwError);
        }
    }

    if (S_OK == hr)
    {
        //
        // Install the network component.
        //
        hr = HrInstallComponent(pnc, NDISLWF_SERVICE_PNP_DEVICE_ID, pguidClass);

        if (hr == S_OK)
        {
            hr = HrInstallComponent(pnc, NDISLWF_SERVICE_PNP_DEVICE_ID_WIFI, pguidClass);

            if (hr == S_OK)
            {
                //
                // On success, apply the changes
                //
                hr = pnc->Apply();
            }
        }
    }

    return hr;
}

结果是第二个服务npcap_wifi以系统错误2结束:

C:\Program Files\Npcap>sc query npcap

SERVICE_NAME: npcap
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Program Files\Npcap>sc query npcap_wifi
[SC] EnumQueryServicesStatus:OpenService FAILED 1060:

The specified service does not exist as an installed service.


C:\Program Files\Npcap>sc query npcap
SERVICE_NAME: npcap
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Program Files\Npcap>sc query npcap_wifi

SERVICE_NAME: npcap_wifi
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 2  (0x2)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Program Files\Npcap>net start npcap
The requested service has already been started.

More help is available by typing NET HELPMSG 2182.


C:\Program Files\Npcap>net start npcap_wifi
System error 2 has occurred.

The system cannot find the file specified.


C:\Program Files\Npcap>

这看起来不错吗?问题是我仍然没有在DbgView中获得第二个LWF的DriverEntry电话?那么第二个LWF如何运作呢?

更新:

我想这是我接下来应该做的事情?我在NdisFRegisterFilterDriver中拨打了DriverEntry两次来注册2个LWF。 2 FChars结构仅在FriendlyName, UniqueName, ServiceName中有所不同。但第二个NdisFRegisterFilterDriver始终以NDIS_STATUS_FAILURE(0xc0000001)失败。我不知道为什么。

这是我的代码:

//
//  Packet Driver's entry routine.
//
_Use_decl_annotations_
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
    NDIS_FILTER_DRIVER_CHARACTERISTICS FChars_WiFi;
    NTSTATUS Status = STATUS_SUCCESS;

    // Use NonPaged Pool instead of No-Execute (NX) Nonpaged Pool for Win8 and later, this is for security purpose.
    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);

    WCHAR* bindT;
    PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP;
    UNICODE_STRING macName;
    ULONG OsMajorVersion, OsMinorVersion;
    NDISGROUPMAXPROCESSORCOUNT MyNdisGroupMaxProcessorCount;
    NDIS_STRING GroupMaxProcessorCount;
    UNREFERENCED_PARAMETER(RegistryPath);

    TRACE_ENTER();
    FilterDriverObject = DriverObject;

    PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL);
    TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "OS Version: %d.%d\n", OsMajorVersion, OsMinorVersion);

    // RegistryPath = "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\npcap" for standard driver
    // RegistryPath = "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\npcap_wifi" for WiFi driver
    g_Dot11SupportMode = 0;
    for (USHORT i = 0; i < RegistryPath->Length / 2; i ++)
    {
        if (RegistryPath->Buffer[i] == L'_')
        {
            g_Dot11SupportMode = 1;
            break;
        }
    }
    TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "g_Dot11SupportMode (based on RegistryPath) = %d\n", g_Dot11SupportMode);

    if (g_Dot11SupportMode)
        NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer_Wifi);
    else
        NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer);

    //
    // Get number of CPUs and save it
    //
    RtlInitUnicodeString(&GroupMaxProcessorCount, L"NdisGroupMaxProcessorCount");
    MyNdisGroupMaxProcessorCount = (NDISGROUPMAXPROCESSORCOUNT) NdisGetRoutineAddress(&GroupMaxProcessorCount);
    if (MyNdisGroupMaxProcessorCount) // for NDIS620 and later (Win7 and later).
    {
        g_NCpu = MyNdisGroupMaxProcessorCount(ALL_PROCESSOR_GROUPS);
        TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "g_NCpu (NdisGroupMaxProcessorCount): %d, NPF_MAX_CPU_NUMBER: %d\n", g_NCpu, NPF_MAX_CPU_NUMBER);
        if (g_NCpu > NPF_MAX_CPU_NUMBER)
        {
            g_NCpu = NPF_MAX_CPU_NUMBER;
        }
    }
    else // for NDIS6 (Vista)
    {
        g_NCpu = NdisSystemProcessorCount();
    }

    //
    // Register as a service with NDIS
    //
    NPF_registerLWF(&FChars, FALSE);
    NPF_registerLWF(&FChars_WiFi, TRUE);

    DriverObject->DriverUnload = NPF_Unload;

    //
    // Standard device driver entry points stuff.
    //
    DriverObject->MajorFunction[IRP_MJ_CREATE] = NPF_OpenAdapter;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = NPF_CloseAdapter;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NPF_Cleanup;
    DriverObject->MajorFunction[IRP_MJ_READ] = NPF_Read;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = NPF_Write;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl;

    bindP = getAdaptersList();

    if (bindP == NULL)
    {
        TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Adapters not found in the registry, try to copy the bindings of TCP-IP.");

        tcpBindingsP = getTcpBindings();

        if (tcpBindingsP == NULL)
        {
            TRACE_MESSAGE(PACKET_DEBUG_LOUD, "TCP-IP not found, quitting.");
            goto RegistryError;
        }

        bindP = (WCHAR *)tcpBindingsP;
        bindT = (WCHAR *)(tcpBindingsP->Data);
    }
    else
    {
        bindT = bindP;
    }

    for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR))
    {
        RtlInitUnicodeString(&macName, bindT);
        NPF_CreateDevice(DriverObject, &macName);
    }

    // Register the filter to NDIS.
    Status = NdisFRegisterFilterDriver(DriverObject,
        (NDIS_HANDLE) FilterDriverObject,
        &FChars,
        &FilterDriverHandle);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: failed to register filter with NDIS, Status = %x", Status);
        TRACE_EXIT();
        return Status;
    }
    else
    {
        TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: succeed to register filter with NDIS, Status = %x, FilterDriverHandle = %x", Status, FilterDriverHandle);
    }

    // Register the WiFi filter to NDIS.
    Status = NdisFRegisterFilterDriver(DriverObject,
        (NDIS_HANDLE)FilterDriverObject,
        &FChars_WiFi,
        &FilterDriverHandle_WiFi);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: failed to register filter (WiFi) with NDIS, Status = %x", Status);
        TRACE_EXIT();
        return Status;
    }
    else
    {
        TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: succeed to register filter (WiFi) with NDIS, Status = %x, FilterDriverHandle_WiFi = %x", Status, FilterDriverHandle_WiFi);
    }

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
    // Use Winsock Kernel (WSK) to send loopback packets.
    Status = NPF_WSKStartup();
    if (!NT_SUCCESS(Status))
    {
        TRACE_EXIT();
        return Status;
    }

    Status = NPF_WSKInitSockets();
    if (!NT_SUCCESS(Status))
    {
        TRACE_EXIT();
        return Status;
    }
#endif

    NdisAllocateSpinLock(&g_OpenArrayLock);

    TRACE_EXIT();
    return STATUS_SUCCESS;

RegistryError:

    Status = STATUS_UNSUCCESSFUL;
    TRACE_EXIT();
    return(Status);
}
//-------------------------------------------------------------------
VOID
NPF_registerLWF(
    PNDIS_FILTER_DRIVER_CHARACTERISTICS pFChars,
    BOOLEAN bWiFiOrNot
    )
{
    NDIS_STRING FriendlyName = RTL_CONSTANT_STRING(NPF_SERVICE_DESC_WIDECHAR); // display name
    NDIS_STRING UniqueName = RTL_CONSTANT_STRING(FILTER_UNIQUE_NAME); // unique name, quid name
    NDIS_STRING ServiceName = RTL_CONSTANT_STRING(NPF_DRIVER_NAME_SMALL_WIDECHAR); // this to match the service name in the INF
    NDIS_STRING FriendlyName_WiFi = RTL_CONSTANT_STRING(NPF_SERVICE_DESC_WIDECHAR_WIFI); // display name
    NDIS_STRING UniqueName_WiFi = RTL_CONSTANT_STRING(FILTER_UNIQUE_NAME_WIFI); // unique name, quid name
    NDIS_STRING ServiceName_WiFi = RTL_CONSTANT_STRING(NPF_DRIVER_NAME_SMALL_WIDECHAR_WIFI); // this to match the service name in the INF

    NdisZeroMemory(pFChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));
    pFChars->Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
    pFChars->Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
#if NDIS_SUPPORT_NDIS61
    pFChars->Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
#else
    pFChars->Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
#endif

    pFChars->MajorNdisVersion = NDIS_FILTER_MAJOR_VERSION; // NDIS version is 6.2 (Windows 7)
    pFChars->MinorNdisVersion = NDIS_FILTER_MINOR_VERSION;
    pFChars->MajorDriverVersion = 1; // Driver version is 1.0
    pFChars->MinorDriverVersion = 0;
    pFChars->Flags = 0;

    // Use different names for the WiFi driver.
    if (bWiFiOrNot)
    {
        pFChars->FriendlyName = FriendlyName_WiFi;
        pFChars->UniqueName = UniqueName_WiFi;
        pFChars->ServiceName = ServiceName;
        // pFChars->ServiceName = ServiceName_WiFi;
    }
    else
    {
        pFChars->FriendlyName = FriendlyName;
        pFChars->UniqueName = UniqueName;
        pFChars->ServiceName = ServiceName;
    }

    pFChars->SetOptionsHandler = NPF_RegisterOptions;
    pFChars->AttachHandler = NPF_AttachAdapter;
    pFChars->DetachHandler = NPF_DetachAdapter;
    pFChars->RestartHandler = NPF_Restart;
    pFChars->PauseHandler = NPF_Pause;
    pFChars->SetFilterModuleOptionsHandler = NPF_SetModuleOptions;
    pFChars->OidRequestHandler = NPF_OidRequest;
    pFChars->OidRequestCompleteHandler = NPF_OidRequestComplete;
    pFChars->CancelOidRequestHandler = NPF_CancelOidRequest;

    pFChars->SendNetBufferListsHandler = NPF_SendEx;
    pFChars->ReturnNetBufferListsHandler = NPF_ReturnEx;
    pFChars->SendNetBufferListsCompleteHandler = NPF_SendCompleteEx;
    pFChars->ReceiveNetBufferListsHandler = NPF_TapEx;
    pFChars->DevicePnPEventNotifyHandler = NPF_DevicePnPEventNotify;
    pFChars->NetPnPEventHandler = NPF_NetPnPEvent;
    pFChars->StatusHandler = NPF_Status;
    pFChars->CancelSendNetBufferListsHandler = NPF_CancelSendNetBufferLists;
}

对于第二个LWF,我使用了第一个LWF&#39; ServiceNamenpcap),或使用了自己的npcap_wifi,但都没有效果。

整个源代码位于:https://github.com/nmap/npcap/commit/1cac59271a9772ebbfff0db9c8a051b6553c25a2

更新:

我分析了WPP跟踪,它显示:

    [1]0004.015C::08/28/2016-20:26:58.498 [mp]==>NdisFRegisterFilterDriver: DriverObject FFFF8A85572FD6D0, Npcap Packet Driver (NPCAP)
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]==>ndisCreateFilterDriverRegistry, FilterServiceName FFFFCB01F6F617D0
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]Reading DefaultFilterSettings from registry - Status 0xc0000034(STATUS_OBJECT_NAME_NOT_FOUND), Validation = 0 
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]==>ndisSetAllFilterDefaultParameters, FilterServiceName FFFFCB01F6F617D0 FilterRegistryPath FFFFCB01F6F61610 FilterParams FFFFF80DD6A88598
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]<==ndisSetAllFilterDefaultParameters, FilterServiceName FFFFCB01F6F617D0 FilterRegistryPath FFFFCB01F6F61610 FilterParams FFFFF80DD6A88598 Status 0
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]<==ndisCreateFilterDriverRegistry, FilterServiceName FFFFCB01F6F617D0 Status 0
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]>Begin filter driver's SetOptionsHandler. FilterDriver=FFFF8A85532E6010
    [1]0004.015C::08/28/2016-20:26:58.498 [mp]<End filter driver's SetOptionsHandler.   FilterDriver=FFFF8A85532E6010, Status=0x00000000
    [1]0004.015C::08/28/2016-20:26:58.498 [km]Begin PNP operations on miniport FFFF8A85538DC1A0
    [0]0004.015C::08/28/2016-20:26:58.498 [km]End PNP operations on miniport FFFF8A85538DC1A0
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]<==NdisFRegisterFilterDriver, Status 0
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]==>NdisFRegisterFilterDriver: DriverObject FFFF8A85572FD6D0, Npcap Packet Driver (NPCAP) (WiFi version)
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]==>ndisCreateFilterDriverRegistry, FilterServiceName FFFFCB01F6F618B0
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]Reading DefaultFilterSettings from registry - Status STATUS_SUCCESS, Validation = 0 
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]<==ndisCreateFilterDriverRegistry, FilterServiceName FFFFCB01F6F618B0 Status 0
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]NdisFRegisterFilterDriver: Cannot find filter 7daf2ac8-e9f6-4765-a842-f1f5d2501351 in the registry.  Did INetCfg install this filter successfully?
    [0]0004.015C::08/28/2016-20:26:58.499 [mp]<==NdisFRegisterFilterDriver, Status c0000001

因此,似乎NDIS没有找到第二个过滤器的注册表7daf2ac8-e9f6-4765-a842-f1f5d2501351。但我在regedit检查了它。它有这个关键:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501341}]
"InstallTimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,39,00,88,03
"Characteristics"=dword:00040000
"ComponentId"="INSECURE_NPCAP"
"Description"="@oem11.inf,%npf_desc_standard%;Npcap Packet Driver (NPCAP)"
"InfPath"="oem11.inf"
"InfSection"="FilterStandard"
"LocDescription"="@oem11.inf,%npf_desc_standard%;Npcap Packet Driver (NPCAP)"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501341}\Ndi]
"TimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,39,00,88,03
"HelpText"="A NDIS 6 filter driver & WFP callout driver to support packet capturing and sending under Windows 7, 8 & 10"
"Service"="npcap"
"CoServices"=hex(7):6e,00,70,00,63,00,61,00,70,00,00,00,00,00
"FilterClass"="compression"
"FilterType"=dword:00000002
"FilterRunType"=dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501341}\Ndi\Interfaces]
"LowerRange"="ndis5,ndis4"
"UpperRange"="noupper"
"FilterMediaTypes"="ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501351}]
"InstallTimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,3a,00,7e,02
"Characteristics"=dword:00040000
"ComponentId"="INSECURE_NPCAP_WIFI"
"Description"="@oem11.inf,%npf_desc_wifi%;Npcap Packet Driver (NPCAP) (Wi-Fi)"
"InfPath"="oem11.inf"
"InfSection"="FilterWiFi"
"LocDescription"="@oem11.inf,%npf_desc_wifi%;Npcap Packet Driver (NPCAP) (Wi-Fi)"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501351}\Ndi]
"TimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,3a,00,7e,02
"HelpText"="A NDIS 6 filter driver & WFP callout driver to support packet capturing and sending under Windows 7, 8 & 10"
"Service"="npcap_wifi"
"CoServices"=hex(7):6e,00,70,00,63,00,61,00,70,00,5f,00,77,00,69,00,66,00,69,\
  00,00,00,00,00
"FilterClass"="ms_medium_converter_128"
"FilterType"=dword:00000002
"FilterRunType"=dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501351}\Ndi\Interfaces]
"LowerRange"="ndis5,ndis4"
"UpperRange"="noupper"
"FilterMediaTypes"="ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"

所以我不知道为什么NDIS报告NdisFRegisterFilterDriver: Cannot find filter 7daf2ac8-e9f6-4765-a842-f1f5d2501351 in the registry. Did INetCfg install this filter successfully?

1 个答案:

答案 0 :(得分:1)

二进制映像(.sys文件)只能由系统一次加载一次。您无法同时为两个不同的服务加载相同的图像。 (也不能为服务加载一次,为PNP驱动程序加载一次。)这意味着您总是看到DriverEntryDriverUnloadDriverEntryDriverUnload,....您永远不会看到DriverEntryDriverEntryDriverUnloadDriverUnload

使用虚假服务

每个NDIS LWF或协议驱动程序都需要一个服务来保存一些注册表项。但这是第一个技巧:服务不必运行!您可以为LWF创建虚拟服务记录,然后让其他服务实际使用LWF。 NDIS不会验证您传递给ServiceName的{​​{1}}。 (是的,可以依靠这个技巧。我在微软的NDIS所有者的授权下发言。)

有内置驱动程序正是这样做的。看看TCPIP和TCPIP6。这是两种不同的服务,也是两种不同的协议驱动程序,但只有一种映像(tcpip.sys)。 TCPIP服务是真正的服务 - 实际上它将在启动时启动。 TCPIP6服务是假的 - 它被标记为永不启动,如果您尝试手动启动它,它将无法正常工作。

(旁白:不要使用WFPLWFS作为示例。虽然它也有3个过滤器驱动程序共享1个二进制文件,但它会做一些不同的事情,如果你试图这样做会导致一些问题。另外,从Windows 10,TCPIP和TCPIP6使用的INF都是假的,所以你不应该假设它们是如何做这个技巧的好例子。)

您可以选择将所有这些注册为1 INF或2 INF;它对操作系统没有多大影响。让我们说1 INF,只是为了让示例更短。

所以你需要的是:

  • LWF名为FilterA
  • LWF名为FilterB
  • 名为ServiceA的服务
  • 名为ServiceB的服务
  • 名为Driver.sys的驱动程序映像
  • INF命名为Driver.inf

我们假设ServiceA是真正的服务,ServiceB是虚假服务。

Driver.inf会有:

NdisFRegisterFilterDriver

请注意,您注册了2个LWF,创建了2个服务,并复制了1个图像。

对于[Manufacturer] Contoso=Models,NTamd64 [Models.NTamd64] "Cool Filter A"=FilterA, my_filter_a "Awesome Filter B"=FilterB, my_filter_b [FilterA] NetCfgInstanceId="{guid-aaaa-guid}" CopyFiles=copy.driver.sys Characteristics=0x40000 AddReg=FilterA.reg [FilterB] NetCfgInstanceId="{guid-bbbb-guid}" Characteristics=0x40000 AddReg=FilterB.reg [FilterA.reg] HKR,Ndi,Service,,"ServiceA" HKR,etc,etc,etc [FilterB.reg] HKR,Ndi,Service,,"ServiceB" HKR,etc,etc,etc [FilterA.Services] AddService=ServiceA,,FilterA.svc [FilterB.Services] AddService=ServiceB,,FilterB.svc [FilterA.svc] StartType = Demand ServiceBinary = Driver.sys [FilterB.svc] StartType = Demand ServiceBinary = Driver.sys [copy.driver.sys] driver.sys,,,2 SetupCopyOEMInf中的每一个,您只需拨打一次INetCfgClassSetup::Install次电话,然后拨打my_filter_a两次电话即可安装。

要启动驱动程序,只启动1个服务ServiceA。永远不要启动其他虚拟服务。

但是,如果您不希望两个过滤器同时运行,该怎么办?轻松 - 不要打{{1​​}}直到你想要实际启动LWF。您始终可以从ioctl处理程序注册/取消注册过滤器驱动程序。所以你的my_filter_b会相当空 - 只需创建一个设备对象来监听ioctls。

使用导出驱动程序

另一种选择是创建2个服务,每个服务都有自己的驱动程序映像。但是对于单个共享导出驱动程序(如DLL)的调用,驱动程序映像将是一个很薄的包装器。您可以将所有实际工作放在该共享导出驱动程序中。

NdisFRegisterFilterDriver

这样可以保持简单,尽管最终会有一堆额外的司机。