wfp驱动实现流量监控

最近在使用wfp驱动写了个流量监控的功能,测试可以后,找了两个笔记本,开成测试模式。把驱动加载起来,其中一台可以监控到上网应用的流量信息。另一台把驱动加载成功后,电脑直接不可以上网了,从驱动代码看并没有数据包劫持的动作。如果有问题的话,两个笔记本应该都上不了网。请教下有遇到过这种场景吗?

以下内容引用CHATGPT:

可能是因为驱动在另一台笔记本上与某些网络配置不兼容。建议检查驱动与网络配置之间的冲突,并针对不同的网络配置进行测试和适配。

另外,可以使用网络抓包工具(如Wireshark)来分析驱动是否成功捕获数据包,并检查数据包的格式和内容是否正确。如果发现数据包捕获不正确,可以调试驱动代码以解决问题。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
遇到这种情况很可能是因为新安装的驱动与系统或其他已安装的软件或驱动存在冲突或不兼容。建议先卸载掉不可以上网的笔记本上安装的驱动,再重新安装一遍,看能否解决问题。另外请确保驱动的代码逻辑没有问题,可以参考下面的代码:

#include <ntddk.h>
#include <wdf.h>
#include <ntstrsafe.h>
#include <netioddk.h>

DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL KmdfHelloWorldEvtIoDeviceControl;

typedef struct _FLOW_ENTRY {
    HANDLE ProcessId;
    ULONGLONG InBytes;
    ULONGLONG OutBytes;
} FLOW_ENTRY, *PFLOW_ENTRY;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FLOW_ENTRY, FlowEntryGetContext)

#define DEVICE_NAME L"\\\\.\\FlowMonitor"
#define IOCTL_FLOWMONITOR_GET_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_FLOWMONITOR_GET_ENTRIES CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FLOW_ENTRY, FlowEntryGetContext)

NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT  DriverObject,
    _In_ PUNICODE_STRING RegistryPath
)
{
    WDF_DRIVER_CONFIG config;
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.SynchronizationScope = WdfSynchronizationScopeNone;

    WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd);

    status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE);

    return status;
}

NTSTATUS
KmdfHelloWorldEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,
    _Inout_ PWDFDEVICE_INIT DeviceInit
)
{
    UNREFERENCED_PARAMETER(Driver);
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;
    WDFDEVICE hDevice;
    WDF_IO_QUEUE_CONFIG ioQueueConfig;

    PAGED_CODE();

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, FLOW_ENTRY);

    status = WdfDeviceCreate(&DeviceInit, &attributes, &hDevice);

    if (!NT_SUCCESS(status)) {
        return status;
    }

    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchSequential);

    ioQueueConfig.EvtIoDeviceControl = KmdfHelloWorldEvtIoDeviceControl;

    status = WdfIoQueueCreate(hDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, WDF_NO_HANDLE);

    if (!NT_SUCCESS(status)) {
        return status;
    }

    return status;
}

NTSTATUS
KmdfHelloWorldEvtIoDeviceControl(
    _In_    WDFQUEUE        Queue,
    _In_    WDFREQUEST      Request,
    _In_    size_t          OutputBufferLength,
    _In_    size_t          InputBufferLength,
    _In_    ULONG           IoControlCode
)
{
    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);

    NTSTATUS status = STATUS_SUCCESS;

    switch (IoControlCode) {
    case IOCTL_FLOWMONITOR_GET_COUNT:
        status = FlowMonitorIoctlGetCount(Queue, Request);
        break;

    case IOCTL_FLOWMONITOR_GET_ENTRIES:
        status = FlowMonitorIoctlGetEntries(Queue, Request);
        break;
    }

    return status;
}

NTSTATUS
FlowMonitorIoctlGetCount(
    _In_    WDFQUEUE        Queue,
    _In_    WDFREQUEST      Request
)
{
    NTSTATUS                status = STATUS_SUCCESS;
    size_t                  outputBufferLength = 0;
    PUCHAR                  pOutputBuffer = NULL;

    UNREFERENCED_PARAMETER(Queue);

    PAGED_CODE();

    outputBufferLength = sizeof(ULONG);

    status = WdfRequestRetrieveOutputBuffer(Request, outputBufferLength, &pOutputBuffer, NULL);

    if (!NT_SUCCESS(status)) {
        WdfRequestComplete(Request, status);
        return status;
    }

    *((PULONG)pOutputBuffer) = FlowMonitorGetCount();

    WdfRequestCompleteWithInformation(Request, status, outputBufferLength);

    return status;
}

NTSTATUS
FlowMonitorIoctlGetEntries(
    _In_    WDFQUEUE        Queue,
    _In_    WDFREQUEST      Request
)
{
    NTSTATUS                status = STATUS_SUCCESS;
    size_t                  outputBufferLength = 0;
    PUCHAR                  pOutputBuffer = NULL;

    UNREFERENCED_PARAMETER(Queue);

    PAGED_CODE();

    outputBufferLength = sizeof(FLOW_ENTRY) * FlowMonitorGetCount();

    status = WdfRequestRetrieveOutputBuffer(Request, outputBufferLength, &pOutputBuffer, NULL);

    if (!NT_SUCCESS(status)) {
        WdfRequestComplete(Request, status);
        return status;
    }

    FlowMonitorGetEntries(pOutputBuffer, outputBufferLength);

    WdfRequestCompleteWithInformation(Request, status, outputBufferLength);

    return status;
}

ULONG
FlowMonitorGetCount()
{
    return 0;
}

VOID
FlowMonitorGetEntries(
    _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer,
    _In_ ULONG OutputBufferLength
)
{
}

这里只是提供一个简单的框架代码,可以根据自己的需要具体实现,如实现对数据包的监视和统计,实现通过设备控制通道获取流量监控的统计信息等。
如果我的回答解决了您的问题,请采纳!

引用chatGPT作答,从您提供的信息来看,您的驱动可能与第二台笔记本电脑的某些硬件或配置不兼容,导致该笔记本电脑无法上网。您可以尝试检查第二台笔记本电脑的网络设置和驱动加载情况,以确定是否存在配置问题或驱动加载问题。

此外,您还可以查看系统日志,以查找可能导致问题的错误或警告消息。另外,您可以使用调试工具来分析问题,例如使用调试器或使用内核调试工具来跟踪系统中的进程和线程。

最后,您还可以考虑更改驱动代码,以便更好地适应不同的硬件和配置。这可能需要进行一些深入的分析和调试,但可以帮助您解决兼容性问题并使驱动更加健壮。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^