DWORD NetHashProtection::AddCallouts() { FWPM_CALLOUT callout; DWORD result; FWPM_DISPLAY_DATA displayData; HANDLE engineHandle = NULL; FWPM_SESSION session; RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"Monitor Non-Dynamic Session"; session.displayData.description = L"For Adding callouts"; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle ); if (NO_ERROR != result) { goto cleanup; } printf("Starting Transaction for adding callouts\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully started the Transaction\n"); RtlZeroMemory(&callout, sizeof(FWPM_CALLOUT)); displayData.description = MONITOR_FLOW_ESTABLISHED_CALLOUT_DESCRIPTION; displayData.name = MONITOR_FLOW_ESTABLISHED_CALLOUT_NAME; callout.calloutKey = HASH_MONITOR_FLOW_ESTABLISHED_CALLOUT_V4; callout.displayData = displayData; callout.applicableLayer = FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4; callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT; // Make this a persistent callout. printf("Adding Persistent Flow Established callout through the Filtering Engine\n"); result = FwpmCalloutAdd(engineHandle, &callout, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully Added Persistent Flow Established callout.\n"); printf("Committing Transaction\n"); result = FwpmTransactionCommit(engineHandle); if (NO_ERROR == result) { printf("Successfully Committed Transaction.\n"); } goto cleanup; abort: printf("Aborting Transaction\n"); result = FwpmTransactionAbort(engineHandle); if (NO_ERROR == result) { printf("Successfully Aborted Transaction.\n"); } cleanup: if (engineHandle) { FwpmEngineClose(engineHandle); } return result; }
NTSTATUS RegisterCalloutForLayer ( IN const GUID* layerKey, IN const GUID* calloutKey, IN FWPS_CALLOUT_CLASSIFY_FN classifyFn, IN FWPS_CALLOUT_NOTIFY_FN notifyFn, IN FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN flowDeleteNotifyFn, OUT UINT32* calloutId, OUT UINT64* filterId ) { NTSTATUS status = STATUS_SUCCESS; FWPS_CALLOUT sCallout = {0}; FWPM_FILTER mFilter = {0}; FWPM_FILTER_CONDITION mFilter_condition[1] = {0}; FWPM_CALLOUT mCallout = {0}; FWPM_DISPLAY_DATA mDispData = {0}; BOOLEAN bCalloutRegistered = FALSE; sCallout.calloutKey = *calloutKey; sCallout.classifyFn = classifyFn; sCallout.flowDeleteFn = flowDeleteNotifyFn; sCallout.notifyFn = notifyFn; //要使用哪个设备对象注册 status = FwpsCalloutRegister( gDevObj,&sCallout,calloutId ); if( !NT_SUCCESS(status)) goto exit; bCalloutRegistered = TRUE; mDispData.name = L"WFP TEST"; mDispData.description = L"TESLA.ANGELA's WFP TEST"; //你感兴趣的内容 mCallout.applicableLayer = *layerKey; //你感兴趣的内容的GUID mCallout.calloutKey = *calloutKey; mCallout.displayData = mDispData; //添加回调函数 status = FwpmCalloutAdd( gEngineHandle,&mCallout,NULL,NULL); if( !NT_SUCCESS(status)) goto exit; mFilter.action.calloutKey = *calloutKey; //在callout里决定 mFilter.action.type = FWP_ACTION_CALLOUT_TERMINATING; mFilter.displayData.name = L"WFP TEST"; mFilter.displayData.description = L"TESLA.ANGELA's WFP TEST"; mFilter.layerKey = *layerKey; mFilter.numFilterConditions = 0; mFilter.filterCondition = mFilter_condition; mFilter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL; mFilter.weight.type = FWP_EMPTY; //添加过滤器 status = FwpmFilterAdd( gEngineHandle,&mFilter,NULL,filterId ); if( !NT_SUCCESS( status)) goto exit; exit: if( !NT_SUCCESS(status)) { if( bCalloutRegistered ) { FwpsCalloutUnregisterById( *calloutId ); } } return status; }
DWORD MonitorAppAddCallouts() /*++ Routine Description: Adds the callouts during installation Arguments: [in] PCWSTR AppPath - The path to the application to monitor. Return Value: NO_ERROR or a specific FWP result. --*/ { FWPM_CALLOUT callout; DWORD result; FWPM_DISPLAY_DATA displayData; HANDLE engineHandle = NULL; FWPM_SESSION session; RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"Monitor Sample Non-Dynamic Session"; session.displayData.description = L"For Adding callouts"; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle ); if (NO_ERROR != result) { goto cleanup; } printf("Starting Transaction for adding callouts\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully started the Transaction\n"); RtlZeroMemory(&callout, sizeof(FWPM_CALLOUT)); displayData.description = MONITOR_FLOW_ESTABLISHED_CALLOUT_DESCRIPTION; displayData.name = MONITOR_FLOW_ESTABLISHED_CALLOUT_NAME; callout.calloutKey = MONITOR_SAMPLE_FLOW_ESTABLISHED_CALLOUT_V4; callout.displayData = displayData; callout.applicableLayer = FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4; callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT; // Make this a persistent callout. printf("Adding Persistent Flow Established callout through the Filtering Engine\n"); result = FwpmCalloutAdd(engineHandle, &callout, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully Added Persistent Flow Established callout.\n"); RtlZeroMemory(&callout, sizeof(FWPM_CALLOUT)); displayData.description = MONITOR_STREAM_CALLOUT_DESCRIPTION; displayData.name = MONITOR_STREAM_CALLOUT_DESCRIPTION; callout.calloutKey = MONITOR_SAMPLE_STREAM_CALLOUT_V4; callout.displayData = displayData; callout.applicableLayer = FWPM_LAYER_STREAM_V4; callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT; // Make this a persistent callout. printf("Adding Persistent Stream callout through the Filtering Engine\n"); result = FwpmCalloutAdd(engineHandle, &callout, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully Added Persistent Stream callout.\n"); printf("Committing Transaction\n"); result = FwpmTransactionCommit(engineHandle); if (NO_ERROR == result) { printf("Successfully Committed Transaction.\n"); } goto cleanup; abort: printf("Aborting Transaction\n"); result = FwpmTransactionAbort(engineHandle); if (NO_ERROR == result) { printf("Successfully Aborted Transaction.\n"); } cleanup: if (engineHandle) { FwpmEngineClose(engineHandle); } return result; }
NTSTATUS NPF_RegisterCallout( _In_ const GUID* layerKey, _In_ const GUID* calloutKey, _Inout_ void* deviceObject, _Out_ UINT32* calloutId ) /* ++ This function registers callouts and filters that intercept transport traffic at the following layers -- FWPM_LAYER_INBOUND_IPPACKET_V4 FWPM_LAYER_INBOUND_IPPACKET_V6 FWPM_LAYER_OUTBOUND_IPPACKET_V4 FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD -- */ { TRACE_ENTER(); NTSTATUS status = STATUS_SUCCESS; FWPS_CALLOUT sCallout = { 0 }; FWPM_CALLOUT mCallout = { 0 }; FWPM_DISPLAY_DATA displayData = { 0 }; BOOLEAN calloutRegistered = FALSE; sCallout.calloutKey = *calloutKey; sCallout.classifyFn = NPF_NetworkClassify; sCallout.notifyFn = NPF_NetworkNotify; status = FwpsCalloutRegister( deviceObject, &sCallout, calloutId ); if (!NT_SUCCESS(status)) { goto Exit; } calloutRegistered = TRUE; displayData.name = L"Npcap Network Callout"; displayData.description = L"Npcap inbound/outbound network traffic"; mCallout.calloutKey = *calloutKey; mCallout.displayData = displayData; mCallout.applicableLayer = *layerKey; status = FwpmCalloutAdd( g_WFPEngineHandle, &mCallout, NULL, NULL ); if (!NT_SUCCESS(status)) { goto Exit; } status = NPF_AddFilter(layerKey, calloutKey, 0); if (!NT_SUCCESS(status)) { goto Exit; } status = NPF_AddFilter(layerKey, calloutKey, 1); if (!NT_SUCCESS(status)) { goto Exit; } status = NPF_AddFilter(layerKey, calloutKey, 2); if (!NT_SUCCESS(status)) { goto Exit; } status = NPF_AddFilter(layerKey, calloutKey, 3); if (!NT_SUCCESS(status)) { goto Exit; } Exit: if (!NT_SUCCESS(status)) { IF_LOUD(DbgPrint("NPF_RegisterCallout: failed to register callout\n");) if (calloutRegistered)
NTSTATUS RegisterCalloutForLayer( const GUID* layerKey, const GUID* calloutKey, _Inout_ void* deviceObject, _Out_ UINT32* calloutId ) /* ++ This function registers callouts and filters that intercept TCP traffic at WFP FWPM_LAYER_STREAM_V4 or FWPM_LAYER_STREAM_V6 layer. -- */ { NTSTATUS status = STATUS_SUCCESS; FWPS_CALLOUT sCallout = {0}; FWPM_FILTER filter = {0}; FWPM_FILTER_CONDITION filterConditions[1] = {0}; FWPM_CALLOUT mCallout = {0}; FWPM_DISPLAY_DATA displayData = {0}; BOOLEAN calloutRegistered = FALSE; sCallout.calloutKey = *calloutKey; sCallout.classifyFn = (configEditInline ? StreamInlineEditClassify : StreamOobEditClassify); sCallout.notifyFn = StreamEditNotify; status = FwpsCalloutRegister( deviceObject, &sCallout, calloutId ); if (!NT_SUCCESS(status)) { goto Exit; } calloutRegistered = TRUE; displayData.name = L"Stream Edit Callout"; displayData.description = L"Callout that finds and replaces a token from a TCP stream"; mCallout.calloutKey = *calloutKey; mCallout.displayData = displayData; mCallout.applicableLayer = *layerKey; status = FwpmCalloutAdd( gEngineHandle, &mCallout, NULL, NULL ); if (!NT_SUCCESS(status)) { goto Exit; } filter.layerKey = *layerKey; filter.displayData.name = L"Stream Edit Filter"; filter.displayData.description = L"Filter that finds and replaces a token from a TCP stream"; filter.action.type = FWP_ACTION_CALLOUT_TERMINATING; filter.action.calloutKey = *calloutKey; filter.filterCondition = filterConditions; filter.numFilterConditions = 1; filter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL; filter.weight.type = FWP_EMPTY; // auto-weight. filterConditions[0].fieldKey = (configInspectionOutbound ? FWPM_CONDITION_IP_REMOTE_PORT : FWPM_CONDITION_IP_LOCAL_PORT); filterConditions[0].matchType = FWP_MATCH_EQUAL; filterConditions[0].conditionValue.type = FWP_UINT16; filterConditions[0].conditionValue.uint16 = configInspectionPort; status = FwpmFilterAdd( gEngineHandle, &filter, NULL, NULL); if (!NT_SUCCESS(status)) { goto Exit; } Exit: if (!NT_SUCCESS(status)) { if (calloutRegistered) { FwpsCalloutUnregisterById(*calloutId); } } return status; }