Why do some functions in the callback function in WFP fail to be called normally?
Well, actually the demand is not troublesome. I need to use the TOS coverage of all IP packets sent by this machine as a custom field. So I modified the TOS field in the filtered callback function, and then recalculated the checksum. Everything is fine at this point. However, when I try to call an external function that generates a hash in the callback, something goes wrong - it compiles fine, but the WFP driver cannot be started at all in the test environment.
VOID generate_sign( _In_ unsigned char* key, _In_ unsigned int t, _Out_ unsigned char* result) { unsigned char input[SHA_DIGEST_LENGTH + 1]; memset(input, 0, sizeof(input)); input[0] = *key; unsigned char hash[SHA_DIGEST_LENGTH]; SHA1(input, sizeof(input), hash); *result = 0; for (int i = 0; i < SHA_DIGEST_LENGTH; i++) { *result ^= hash[i]; } } VOID FilterCallback_Sec( const FWPS_INCOMING_VALUES0* pInFixedValues, const FWPS_INCOMING_METADATA_VALUES* pInMetaValues, PVOID pLayerData, const VOID* context, const FWPS_FILTER* pFilter, UINT64 flowContext, FWPS_CLASSIFY_OUT* pClassifyOut) { UNREFERENCED_PARAMETER(pInFixedValues); UNREFERENCED_PARAMETER(pFilter); UNREFERENCED_PARAMETER(flowContext); UNREFERENCED_PARAMETER(pClassifyOut); if (pInMetaValues->currentMetadataValues & FWPS_METADATA_FIELD_IP_HEADER_SIZE) { PNET_BUFFER_LIST nbl = (PNET_BUFFER_LIST)pLayerData; PNET_BUFFER nb = NET_BUFFER_LIST_FIRST_NB(nbl); ULONG ipHeaderSize = pInMetaValues->ipHeaderSize; PVOID ipHeader = NdisGetDataBuffer(nb, ipHeaderSize, NULL, 1, 0); if (ipHeader != NULL) { UINT32 pid = (UINT32)pInMetaValues->processId; UINT32 srcAddr = ((PIPV4_HEADER)ipHeader)->SourceAddress; UINT32 dstAddr = ((PIPV4_HEADER)ipHeader)->DestinationAddress; unsigned char key[] = "secret"; unsigned int timestamp = GetKernelTimestamp() / 10; unsigned int sign = 0; KIRQL oldIrql, newIrql; oldIrql = KeGetCurrentIrql(); if (oldIrql > DISPATCH_LEVEL) { KeLowerIrql(DISPATCH_LEVEL); } // Here👇 generate_sign(key, timestamp, &sign); KeRaiseIrql(oldIrql, &newIrql); ((PIPV4_HEADER)ipHeader)->TypeOfService = sign; ((PIPV4_HEADER)ipHeader)->HeaderChecksum = 0; ((PIPV4_HEADER)ipHeader)->HeaderChecksum = ComputeIpHeaderChecksum(ipHeader, ipHeaderSize); KdPrint(("[WFP Driver]PID: %d\tSrcAddr: %d.%d.%d.%d\tDstAddr:%d.%d.%d.%d\tNew TOS:0x%x\tHeaderChecksum:0x%x\r\n", pid, srcAddr & 0xFF, (srcAddr >> 8) & 0xFF, (srcAddr >> 16) & 0xFF, (srcAddr >> 24) & 0xFF, dstAddr & 0xFF, (dstAddr >> 8) & 0xFF, (dstAddr >> 16) & 0xFF, (dstAddr >> 24) & 0xFF, ((PIPV4_HEADER)ipHeader)->TypeOfService, ((PIPV4_HEADER)ipHeader)->HeaderChecksum)); } } }
As long as I call these functions, the above situation will occur, and when I don't call, the driver starts normally. I tried changing the IRQL level, but it didn't work.
This title and content for this question was made by "Windroid Xie" at this link: https://stackoverflow.com/questions/77590185/why-do-some-functions-in-the-callback-function-in-wfp-fail-to-be-called-normally. Contributions on stackoverflow.com are made under this license.