繁体   English   中英

在 WFP 中的 DATAGRAM_DATA 层重写数据包时出现蓝屏

[英]Blue screen when rewriting packets at DATAGRAM_DATA layer in WFP

我一直在尝试通过 WFP 中的DATAGRAM_DATA层修改传出的 DNS 数据包,但是在传出数据包中重写目标 ip 时出现蓝屏错误。 我究竟做错了什么?

我承认我发现FwpsInjectTransportSendAsync的参数有点令人困惑,并且不确定到底应该为 sendParams arg 输入什么 - 尽管我认为我所拥有的看起来是正确的。

RtlIpv4StringToAddressExW(
L"1.1.1.1", // hard-coding the new (rewritten) dns server for now
FALSE,
&sin4.sin_addr,
&sin4.sin_port);

RtlIpv4StringToAddressExW(
    L"8.8.8.8",        // hard-coding the original dns server for now
    FALSE,
    &origSin4.sin_addr,
    &origSin4.sin_port);
if ((Direction == FWP_DIRECTION_OUTBOUND) && (PacketInjectionState == FWPS_PACKET_NOT_INJECTED) && (RemotePort == 53) && (RemoteAddress == origSin4.sin_addr.S_un.S_addr))
{

    UINT32 IpHeaderSize = inMetaValues->ipHeaderSize;
    UINT32 TransportHeaderSize = inMetaValues->transportHeaderSize;
    UINT64 endpointHandle = inMetaValues->transportEndpointHandle;

    PNET_BUFFER NetBuffer = NET_BUFFER_LIST_FIRST_NB((PNET_BUFFER_LIST)layerData);
    NdisRetreatNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, 0, NULL);

    PNET_BUFFER_LIST NetBufferList = NULL;
    NTSTATUS Status = FwpsAllocateCloneNetBufferList(layerData, NULL, NULL, 0, &NetBufferList);
    if (!NT_SUCCESS(Status))
    {
        return;
    }

    NdisAdvanceNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, FALSE, NULL);

    if (!NetBufferList)
    {
        return;
    }

    NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);

    PIPV4_HEADER IpHeader = NdisGetDataBuffer(NetBuffer, sizeof(IPV4_HEADER), NULL, 1, 0);

    // Rewriting the dest ip
    IpHeader->DestinationAddress = sin4.sin_addr.S_un.S_addr;

    // Updating the IP checksum
    UpdateIpv4HeaderChecksum(IpHeader, sizeof(IPV4_HEADER));

    // not 100% sure the sendParams argument is setup correctly, the docs are slightly unclear
    FWPS_TRANSPORT_SEND_PARAMS sendParams = {
        .remoteAddress = (UCHAR*)IpHeader->DestinationAddress,
        .remoteScopeId = inMetaValues->remoteScopeId,
        .controlData = inMetaValues->controlData,
        .controlDataLength = inMetaValues->controlDataLength,
        .headerIncludeHeader = inMetaValues->headerIncludeHeader,
        .headerIncludeHeaderLength = inMetaValues->headerIncludeHeaderLength
    };

    Status = FwpsInjectTransportSendAsync(g_InjectionHandle, NULL, endpointHandle, 0, &sendParams, AF_INET, inMetaValues->compartmentId, NetBufferList, DriverDatagramDataInjectComplete, NULL);
    if (!NT_SUCCESS(Status))
    {
        FwpsFreeCloneNetBufferList(NetBufferList, 0);
    }

    classifyOut->actionType = FWP_ACTION_BLOCK;
    classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
    classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
}

有两件事对我来说很突出,都在sendParams中。

首先, remoteAddress不正确。 它需要一个指向地址的指针,所以它应该是(UCHAR*)&IpHeader->DestinationAddress

其次, FwpsInjectTransportSendAsync()是异步的,因此您传递给它的任何参数都需要保持有效,直到它完成,这可能是在您调用 function 返回之后。 通常,您分配一些上下文结构,其中包含sendParams和相关成员的深层副本( remoteAddresscontrolData )。 你把它作为上下文传递给你释放它的完成例程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM