美文网首页
使用WFP做转发,将流量转发到localhost的某个端口上

使用WFP做转发,将流量转发到localhost的某个端口上

作者: zhjwang | 来源:发表于2019-10-29 17:03 被阅读0次

    FWPM_LAYER_ALE_CONNECT_REDIRECT 在这一层做转发。

    VOID NTAPI
    ALEConnectRedirectClassifyFn(
        IN const FWPS_INCOMING_VALUES  *inFixedValues,
        IN const FWPS_INCOMING_METADATA_VALUES  *inMetaValues,
        IN OUT VOID  *layerData,
        _In_opt_ const void* classifyContext,
        IN const FWPS_FILTER *filter,
        IN UINT64  flowContext,
        IN OUT FWPS_CLASSIFY_OUT *classifyOut
    ) {
        UINT64 classifyHandle = 0;
        NTSTATUS status;
        FWPS_CONNECT_REQUEST0* connectRequest;
    
        UNREFERENCED_PARAMETER(inFixedValues);
        UNREFERENCED_PARAMETER(flowContext);
        UNREFERENCED_PARAMETER(layerData);
    
        status = FwpsAcquireClassifyHandle((void*)classifyContext, (UINT32)0, &classifyHandle);
        if (!NT_SUCCESS(status)) {
            log("SMBRedirect: Failure to aquire classify handle.\n");
            goto Fail;
        }
    
    #if(NTDDI_VERSION >= NTDDI_WIN8)
        FWPS_CONNECTION_REDIRECT_STATE redirectState = FwpsQueryConnectionRedirectState(
            inMetaValues->redirectRecords,
            redirectHandle,
            NULL
        );
        if (redirectState != FWPS_CONNECTION_NOT_REDIRECTED) {
            log("SMBRedirect: Connection was already redirected (presumably by us). Ignoring it.\n");
            goto Exit;
        }
    #else
        UNREFERENCED_PARAMETER(inMetaValues);
    #endif
    
        status = FwpsAcquireWritableLayerDataPointer(classifyHandle, filter->filterId, 0, &connectRequest, classifyOut);
        if (!NT_SUCCESS(status)) {
            log("SMBRedirect: Failure to aquire classify handle.\n");
            goto Fail;
        }
    
        SOCKADDR_IN* remoteAddr = (SOCKADDR_IN*)&connectRequest->remoteAddressAndPort;
        SOCKADDR_IN* localAddr = (SOCKADDR_IN*)&connectRequest->localAddressAndPort;
    
        UINT32 localAddrIp = localAddr->sin_addr.S_un.S_addr;
        UINT16 localAddrPort = localAddr->sin_port;
        UINT32 remoteAddrIp = remoteAddr->sin_addr.S_un.S_addr;
        UINT16 remoteAddrPort = remoteAddr->sin_port;
        log("SMBRedirect: In ALEConnectRedirectClassifyFn, intercepting connection from %08x:%d to %08x:%d.\n",
            ntohl(localAddrIp), ntohs(localAddrPort), ntohl(remoteAddrIp),ntohs(remoteAddrPort));
    
        int port = ntohs(remoteAddr->sin_port);
        if (port == PORT_1) {
            remoteAddr->sin_port = htons(PORT_2);
            log("SMBRedirect: Redirecting connection from port %d to %d.\n", PORT_1, PORT_2);
        }
    
    #if(NTDDI_VERSION >= NTDDI_WIN8)
        connectRequest->localRedirectHandle = redirectHandle;
    #endif
    
        connectRequest->localRedirectTargetPID = 0xFFFF;
        FwpsApplyModifiedLayerData(classifyHandle, connectRequest,0);
    Exit:
        if (classifyHandle != 0) {
            FwpsReleaseClassifyHandle(classifyHandle);
        }
        return;
    Fail:
        goto Exit;
    }
    

    参考:
    https://social.msdn.microsoft.com/Forums/vstudio/en-US/4e005df1-7e10-46e9-b1dc-29df842adf90/understanding-fwpmlayeraleconnectredirect?forum=wfp

    https://docs.microsoft.com/en-us/windows-hardware/drivers/network/using-bind-or-connect-redirection?redirectedfrom=MSDN

    相关文章

      网友评论

          本文标题:使用WFP做转发,将流量转发到localhost的某个端口上

          本文链接:https://www.haomeiwen.com/subject/dlygvctx.html