NTSTATUS WallRegisterCallouts() { NTSTATUS status = STATUS_SUCCESS; BOOLEAN bInTransaction = FALSE; BOOLEAN bEngineOpened = FALSE; FWPM_SESSION session = {0}; session.flags = FWPM_SESSION_FLAG_DYNAMIC; //开启WFP引擎 status = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &gEngineHandle ); if( !NT_SUCCESS(status)) goto exit; bEngineOpened = TRUE; //确认过滤权限 status = FwpmTransactionBegin( gEngineHandle,0 ); if( !NT_SUCCESS(status)) goto exit; bInTransaction = TRUE; //注册回调函数 status = RegisterCalloutForLayer( &FWPM_LAYER_ALE_AUTH_CONNECT_V4, &GUID_ALE_AUTH_CONNECT_CALLOUT_V4, WallALEConnectClassify, WallNotifyFn, WallFlowDeleteFn, &gAleConnectCalloutId, &gAleConnectFilterId); if( !NT_SUCCESS(status)) { DbgPrint("RegisterCalloutForLayer-FWPM_LAYER_ALE_AUTH_CONNECT_V4 failed!\n"); goto exit; } //确认所有内容并提交,让回调函数正式发挥作用 status = FwpmTransactionCommit(gEngineHandle ); if( !NT_SUCCESS(status)) goto exit; bInTransaction = FALSE; exit: if( !NT_SUCCESS(status)) { if( bInTransaction) { FwpmTransactionAbort( gEngineHandle ); } if( bEngineOpened ) { FwpmEngineClose( gEngineHandle ); gEngineHandle = 0; } } return status; }
DWORD NetHashProtection::MonitorAppDoMonitoring() { HANDLE monitorDevice = NULL; DWORD result; FWPM_SESSION session; RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"HASH File Monitor Session"; session.displayData.description = L"Monitor HASH File Messenger Activity"; // Let the Base Filtering Engine cleanup after us. session.flags = FWPM_SESSION_FLAG_DYNAMIC; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &GlobalengineHandle ); if (NO_ERROR != result) { goto cleanup; GlobalengineHandle=NULL; } printf("Successfully opened Filtering Engine\n"); printf("Adding Filters through the Filtering Engine\n"); result = MonitorAppAddFilters(GlobalengineHandle); if (NO_ERROR != result) { goto cleanup; } printf("Successfully added Filters through the Filtering Engine\n"); cleanup: if (NO_ERROR != result) { printf("Monitor.\tError 0x%x occurred during execution\n", result); } return result; }
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; }
DWORD NetHashProtection::RemoveCallouts() { DWORD result; 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 Removing callouts\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully started the Transaction\n"); printf("Deleting Flow Established callout\n"); result = FwpmCalloutDeleteByKey(engineHandle, &HASH_MONITOR_FLOW_ESTABLISHED_CALLOUT_V4); if (NO_ERROR != result) { goto abort; } printf("Successfully Deleted Flow Established callout\n"); printf("Deleting 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; }
DWORD MonitorAppDoMonitoring(PCWSTR AppPath) { HANDLE monitorDevice = NULL; HANDLE engineHandle = NULL; DWORD result; MONITOR_SETTINGS monitorSettings; FWPM_SESSION session; FWP_BYTE_BLOB* applicationId = NULL; RtlZeroMemory(&monitorSettings, sizeof(MONITOR_SETTINGS)); RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"Monitor Sample Session"; session.displayData.description = L"Monitors traffic at the Stream layer."; // Let the Base Filtering Engine cleanup after us. session.flags = FWPM_SESSION_FLAG_DYNAMIC; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle ); if (NO_ERROR != result) { goto cleanup; } printf("Successfully opened Filtering Engine\n"); printf("Looking up Application ID from BFE\n"); result = MonitorAppIDFromPath(AppPath, &applicationId); if (NO_ERROR != result) { goto cleanup; } printf("Successfully retrieved Application ID\n"); printf("Opening Monitor Sample Device\n"); result = MonitorAppOpenMonitorDevice(&monitorDevice); if (NO_ERROR != result) { goto cleanup; } printf("Successfully opened Monitor Device\n"); printf("Adding Filters through the Filtering Engine\n"); result = MonitorAppAddFilters(engineHandle, applicationId); if (NO_ERROR != result) { goto cleanup; } printf("Successfully added Filters through the Filtering Engine\n"); printf("Enabling monitoring through the Monitor Sample Device\n"); monitorSettings.monitorOperation = monitorTraffic; result = MonitorAppEnableMonitoring(monitorDevice, &monitorSettings); if (NO_ERROR != result) { goto cleanup; } printf("Successfully enabled monitoring.\n"); printf("Events will be traced through WMI. Please press any key to exit and cleanup filters.\n"); #pragma prefast(push) #pragma prefast(disable:6031, "by design the return value of _getch() is ignored here") _getch(); #pragma prefast(pop) cleanup: if (NO_ERROR != result) { printf("Monitor.\tError 0x%x occurred during execution\n", result); } if (monitorDevice) { MonitorAppCloseMonitorDevice(monitorDevice); } // // Free the application Id that we retrieved. // if (applicationId) { FwpmFreeMemory((void**)&applicationId); } if (engineHandle) { result = FwpmEngineClose(engineHandle); engineHandle = NULL; } return result; }
DWORD MonitorAppRemoveCallouts() /*++ Routine Description: Sets the kernel callout ID's through the Monitor Sample device Arguments: [in] HANDLE monitorDevice - Monitor Sample device [in] CALLOUTS* callouts - Callout structure with ID's set [in] DWORD size - Size of the callout structure. Return Value: NO_ERROR or a specific DeviceIoControl result. --*/ { DWORD result; 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 Removing callouts\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully started the Transaction\n"); printf("Deleting Flow Established callout\n"); result = FwpmCalloutDeleteByKey(engineHandle, &MONITOR_SAMPLE_FLOW_ESTABLISHED_CALLOUT_V4); if (NO_ERROR != result) { goto abort; } printf("Successfully Deleted Flow Established callout\n"); printf("Deleting Stream callout\n"); result = FwpmCalloutDeleteByKey(engineHandle, &MONITOR_SAMPLE_STREAM_CALLOUT_V4); if (NO_ERROR != result) { goto abort; } printf("Successfully Deleted 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; }
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 StreamEditRegisterCallout( const STREAM_EDITOR* streamEditor, _Inout_ void* deviceObject ) /* ++ This function registers dynamic callouts and filters that intercept TCP traffic at WFP FWPM_LAYER_STREAM_V4 and FWPM_LAYER_STREAM_V6 layer. Callouts and filters will be removed during DriverUnload. -- */ { NTSTATUS status = STATUS_SUCCESS; BOOLEAN engineOpened = FALSE; BOOLEAN inTransaction = FALSE; FWPM_SESSION session = {0}; UNREFERENCED_PARAMETER(streamEditor); session.flags = FWPM_SESSION_FLAG_DYNAMIC; status = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &gEngineHandle ); if (!NT_SUCCESS(status)) { goto Exit; } engineOpened = TRUE; status = FwpmTransactionBegin(gEngineHandle, 0); if (!NT_SUCCESS(status)) { goto Exit; } inTransaction = TRUE; status = RegisterCalloutForLayer( &FWPM_LAYER_STREAM_V4, &STREAM_EDITOR_STREAM_CALLOUT_V4, deviceObject, &gCalloutIdV4 ); if (!NT_SUCCESS(status)) { goto Exit; } status = RegisterCalloutForLayer( &FWPM_LAYER_STREAM_V6, &STREAM_EDITOR_STREAM_CALLOUT_V6, deviceObject, &gCalloutIdV6 ); if (!NT_SUCCESS(status)) { goto Exit; } status = FwpmTransactionCommit(gEngineHandle); if (!NT_SUCCESS(status)) { goto Exit; } inTransaction = FALSE; Exit: if (!NT_SUCCESS(status)) { if (inTransaction) { NTSTATUS abortStatus; abortStatus = FwpmTransactionAbort(gEngineHandle); _Analysis_assume_(NT_SUCCESS(abortStatus)); } if (engineOpened) { FwpmEngineClose(gEngineHandle); gEngineHandle = NULL; } } return status; }