当使用SERVICE_SYSTEM_START启动WFP标注驱动程序时,FwpmEngineOpen返回EPT_NT_CANT_PERFORM_OP

时间:2015-07-27 03:57:07

标签: c windows driver wfp

我正在编写基于Microsoft Inspect 示例的基于WDM的WFP标注,Inspect基于 WDF ,并且可以与SERVICE_DEMAND_START或SERVICE_SYSTEM_START一起运行良好。我的示例已将WDF更改为WDM,并在我的INF中使用 SERVICE_SYSTEM_START ,但当系统重新启动时,我的驱动程序的 FwpmEngineOpen 功能会因 EPT_NT_CANT_PERFORM_OP 而失败。在我的示例中,我刚刚打开并关闭了WFP引擎,因此与持久标注或过滤器没有任何关系。

我还发现与设备有关系。如果我创建了一个设备(使用 NPF_CreateDevice 调用),则会发生此错误,但如果我发表评论 NPF_CreateDevice ,则此错误消失。并且考虑到WDM和WDF在设备创建代码方面有所不同。所以我认为我的设备代码肯定有问题?谢谢!

lbtest.c

#include "stdafx.h"

#include <ntddk.h>

#include "Loopback.h"
#include "lbtest.h"
#include "debug.h"

extern HANDLE gWFPEngineHandle;

#ifdef ALLOC_PRAGMA
#pragma NDIS_INIT_FUNCTION(DriverEntry)
#endif // ALLOC_PRAGMA

#if DBG
// Declare the global debug flag for this driver.
ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;

#endif

// 
// Configurable parameters (addresses and ports are in host order)
//

WCHAR g_NPF_PrefixBuffer[512] = L"NPCAP" L"_";

WCHAR* bindT = NULL;

NDIS_STRING g_NPF_Prefix;
NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\");
NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\");


/*!
\brief Port device extension.

Structure containing some data relative to every adapter on which NPF is bound.
*/
typedef struct _DEVICE_EXTENSION
{
    NDIS_STRING AdapterName;            ///< Name of the adapter.
    PWSTR       ExportString;           ///< Name of the exported device, i.e. name that the applications will use 
    ///< to open this adapter through WinPcap.
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;



BOOLEAN
NPF_CreateDevice(
IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP
)
{
    NTSTATUS status;
    PDEVICE_OBJECT devObjP;
    UNICODE_STRING deviceName;
    UNICODE_STRING deviceSymLink;

    TRACE_ENTER();

    IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
    if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer, devicePrefix.Length) < devicePrefix.Length)
    {
        TRACE_EXIT();
        return FALSE;
    }

    deviceName.Length = 0;
    deviceName.MaximumLength = (USHORT)(amacNameP->Length + g_NPF_Prefix.Length + sizeof(UNICODE_NULL));
    deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA');

    if (deviceName.Buffer == NULL)
    {
        TRACE_EXIT();
        return FALSE;
    }

    deviceSymLink.Length = 0;
    deviceSymLink.MaximumLength = (USHORT)(amacNameP->Length - devicePrefix.Length + symbolicLinkPrefix.Length + g_NPF_Prefix.Length + sizeof(UNICODE_NULL));

    deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, '3PWA');

    if (deviceSymLink.Buffer == NULL)
    {
        ExFreePool(deviceName.Buffer);
        TRACE_EXIT();
        return FALSE;
    }

    RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
    RtlAppendUnicodeStringToString(&deviceName, &g_NPF_Prefix);
    RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer + devicePrefix.Length / sizeof(WCHAR));

    RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
    RtlAppendUnicodeStringToString(&deviceSymLink, &g_NPF_Prefix);
    RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer + devicePrefix.Length / sizeof(WCHAR));

    IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)

//  status = IoCreateDevice(adriverObjectP, sizeof(DEVICE_EXTENSION), &deviceName, FILE_DEVICE_TRANSPORT,
//      FILE_DEVICE_SECURE_OPEN, FALSE, &devObjP);
status = IoCreateDevice(adriverObjectP, sizeof(DEVICE_EXTENSION), &deviceName, FILE_DEVICE_UNKNOWN,
    FILE_DEVICE_SECURE_OPEN, FALSE, &devObjP);
//      UNICODE_STRING sddl = RTL_CONSTANT_STRING(L"D:P(A;;GA;;;SY)(A;;GA;;;BA)");
//  const GUID guidClassNPF = { 0x26e0d1e0L, 0x8189, 0x12e0, { 0x99, 0x14, 0x08, 0x00, 0x22, 0x30, 0x19, 0x04 } };
//  status = IoCreateDeviceSecure(adriverObjectP, sizeof(DEVICE_EXTENSION), &deviceName, FILE_DEVICE_TRANSPORT,
//      FILE_DEVICE_SECURE_OPEN, FALSE, &sddl, (LPCGUID)&guidClassNPF, &devObjP);

    if (NT_SUCCESS(status))
    {
        PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;

        IF_LOUD(DbgPrint("Device created successfully\n"););

        devObjP->Flags |= DO_DIRECT_IO;
        RtlInitUnicodeString(&devExtP->AdapterName, amacNameP->Buffer);

        IF_LOUD(DbgPrint("Trying to create SymLink %ws\n", deviceSymLink.Buffer););

        if (IoCreateSymbolicLink(&deviceSymLink, &deviceName) != STATUS_SUCCESS)
        {
            IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););

            ExFreePool(deviceName.Buffer);
            ExFreePool(deviceSymLink.Buffer);

            devExtP->ExportString = NULL;

            TRACE_EXIT();
            return FALSE;
        }

        IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););

        devExtP->ExportString = deviceSymLink.Buffer;

        ExFreePool(deviceName.Buffer);

        TRACE_EXIT();
        return TRUE;
    }
    else
    {
        IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););

        ExFreePool(deviceName.Buffer);
        ExFreePool(deviceSymLink.Buffer);

        TRACE_EXIT();
        return FALSE;
    }
}

_Use_decl_annotations_
VOID
NPF_Unload(
    IN PDRIVER_OBJECT      DriverObject
    )
{
    PDEVICE_OBJECT DeviceObject;
    PDEVICE_OBJECT OldDeviceObject;
    PDEVICE_EXTENSION DeviceExtension;
    NDIS_STRING SymLink;

    TRACE_ENTER();

    NPF_UnregisterCallouts();

    DeviceObject = DriverObject->DeviceObject;

    while (DeviceObject != NULL)
    {
        OldDeviceObject = DeviceObject;

        DeviceObject = DeviceObject->NextDevice;

        DeviceExtension = OldDeviceObject->DeviceExtension;

        TRACE_MESSAGE3(PACKET_DEBUG_LOUD, "Deleting Adapter %ws, Protocol Handle=xxx, Device Obj=%p (%p)", DeviceExtension->AdapterName.Buffer, DeviceObject, OldDeviceObject);

        if (DeviceExtension->ExportString)
        {
            RtlInitUnicodeString(&SymLink, DeviceExtension->ExportString);

            TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Deleting SymLink at %p", SymLink.Buffer);

            IoDeleteSymbolicLink(&SymLink);
            ExFreePool(DeviceExtension->ExportString);
        }

        IF_LOUD(DbgPrint("Device successfully deleted.\n\n"););
        IoDeleteDevice(OldDeviceObject);
    }

    // Free the adapters names
    ExFreePool(bindT);

    TRACE_EXIT();
}

_Use_decl_annotations_
NTSTATUS
DriverEntry(
    DRIVER_OBJECT* DriverObject,
    UNICODE_STRING* RegistryPath
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING macName;

    UNREFERENCED_PARAMETER(RegistryPath);

    TRACE_ENTER();

    IF_LOUD(DbgPrint("\n\nThis is version [2]!!!.\n");)

    bindT = (PWCHAR)ExAllocatePoolWithTag(PagedPool, 4096, 'NPCA');
    //RtlCopyUnicodeString(bindT, L"\\Device\\{A22932C9-82CB-4080-993B-D5E82CAD06A7}"); //0006, Microsoft KM-TEST Loopback Adapter;
    wcscpy(bindT, L"\\Device\\{A22932C9-82CB-4080-993B-D5E82CAD06A7}");
    RtlInitUnicodeString(&macName, bindT);

    NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer);

    DriverObject->DriverUnload = NPF_Unload;

    // 
    // Standard device driver entry points stuff.
    //
//  DriverObject->MajorFunction[IRP_MJ_CREATE] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_CLOSE] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_READ] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_WRITE] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NULL;

    Status = NPF_CreateDevice(DriverObject, &macName) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
    if (Status != STATUS_SUCCESS)
    {
        IF_LOUD(DbgPrint("Failed to create WFP device.\n");)
        TRACE_EXIT();
        return STATUS_SUCCESS;
    }

//  if (DriverObject->DeviceObject)
//  {
//      Status = NPF_RegisterCallouts(DriverObject->DeviceObject);
//      if (!NT_SUCCESS(Status))
//      {
//          if (gWFPEngineHandle != NULL)
//          {
//              FwpmEngineClose(gWFPEngineHandle);
//              gWFPEngineHandle = NULL;
//          }
//          TRACE_EXIT();
//          return Status;
//      }
//  }

    Status = NPF_RegisterCallouts(NULL);
    if (!NT_SUCCESS(Status))
    {
        if (gWFPEngineHandle != NULL)
        {
            FwpmEngineClose(gWFPEngineHandle);
            gWFPEngineHandle = NULL;
        }
        TRACE_EXIT();
        return Status;
    }

    TRACE_EXIT();
    return STATUS_SUCCESS;
};

loopback.c

NTSTATUS
NPF_RegisterCallouts(
_Inout_ void* deviceObject
)
/* ++

This function registers dynamic callouts and filters that intercept
transport traffic at ALE AUTH_CONNECT/AUTH_RECV_ACCEPT and
INBOUND/OUTBOUND transport layers.

Callouts and filters will be removed during DriverUnload.

-- */
{
    TRACE_ENTER();
    NTSTATUS status = STATUS_SUCCESS;
    FWPM_SUBLAYER NPFSubLayer;

    BOOLEAN engineOpened = FALSE;
    BOOLEAN inTransaction = FALSE;

    FWPM_SESSION session = { 0 };

    session.flags = 0;// FWPM_SESSION_FLAG_DYNAMIC;

    status = FwpmEngineOpen(
        NULL,
        RPC_C_AUTHN_WINNT,
        NULL,
        &session,
        &gWFPEngineHandle
        );
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }
    engineOpened = TRUE;


Exit:

    if (!NT_SUCCESS(status))
    {
        IF_LOUD(DbgPrint("NPF_RegisterCallouts: failed to register callouts\n");)
            if (inTransaction)
            {
                FwpmTransactionAbort(gWFPEngineHandle);
                _Analysis_assume_lock_not_held_(gWFPEngineHandle); // Potential leak if "FwpmTransactionAbort" fails
            }
        if (engineOpened)
        {
            FwpmEngineClose(gWFPEngineHandle);
            gWFPEngineHandle = NULL;
        }
    }

    TRACE_EXIT();
    return status;
}

void
NPF_UnregisterCallouts(
)
{
    NTSTATUS status;

    TRACE_ENTER();

    FwpmEngineClose(gWFPEngineHandle);

    TRACE_EXIT();
}

1 个答案:

答案 0 :(得分:0)

当您尝试打开引擎时,似乎没有加载BFE。

尝试进行更改:

  1. 在driverEntry函数中注册 FwpmBfeStateSubscribeChanges0 。您可以参考此https://msdn.microsoft.com/en-us/library/ff550062(v=vs.85).aspx
  2. 收到BFE正在运行的通知后,请调用 FwpmEngineOpen API并设置过滤器。