This commit is contained in:
parent
f8534d56da
commit
d6e300f7bf
|
@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- fixed issue with fake admin and some nsi installers [#1052](https://github.com/sandboxie-plus/Sandboxie/issues/1052)
|
||||
- fixed more issued with FileDispositionInformation behavioure, which resulted in bogus file deletion handling
|
||||
- fixed issue with checking WFP status
|
||||
- fixed issue WFP failing to initialize at boot
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -98,6 +98,10 @@ typedef struct _WFP_PROCESS {
|
|||
// Functions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
BOOLEAN WFP_Install_Callbacks(void);
|
||||
|
||||
void WFP_Uninstall_Callbacks(void);
|
||||
|
||||
NTSTATUS WFP_RegisterSubLayer();
|
||||
|
||||
NTSTATUS WFP_RegisterCallout(const GUID* calloutKey, const GUID* applicableLayer, UINT32* callout_id, UINT64* filter_id);
|
||||
|
@ -110,6 +114,9 @@ ULONG Process_GetTraceFlag(PROCESS *proc, const WCHAR *setting);;
|
|||
#pragma alloc_text (INIT, WFP_Init)
|
||||
#endif // ALLOC_PRAGMA
|
||||
|
||||
void WFP_state_changed(
|
||||
_Inout_ void* context,
|
||||
_In_ FWPM_SERVICE_STATE newState);
|
||||
|
||||
/* The "classifyFn" callout function for this Callout.
|
||||
For more information about a Callout's classifyFn, see:
|
||||
|
@ -156,6 +163,12 @@ void GetNetwork5TupleIndexesForLayer(
|
|||
// Variables
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
BOOLEAN WFP_Enabled = FALSE;
|
||||
PERESOURCE WFP_InitLock = NULL;
|
||||
|
||||
static HANDLE WFP_state_handle = NULL;
|
||||
|
||||
// Global handle to the WFP Base Filter Engine
|
||||
static HANDLE WFP_engine_handle = NULL;
|
||||
|
||||
|
@ -206,9 +219,12 @@ _FX VOID WFP_Free(void* pool, void* ptr)
|
|||
|
||||
_FX BOOLEAN WFP_Init(void)
|
||||
{
|
||||
if (!Conf_Get_Boolean(NULL, L"NetworkEnableWFP", 0, FALSE))
|
||||
WFP_Enabled = Conf_Get_Boolean(NULL, L"NetworkEnableWFP", 0, FALSE);
|
||||
if (!WFP_Enabled)
|
||||
return TRUE;
|
||||
|
||||
DbgPrint("Sbie WFP enabled\r\n");
|
||||
|
||||
map_init(&WFP_Processes, NULL);
|
||||
WFP_Processes.func_malloc = &WFP_Alloc;
|
||||
WFP_Processes.func_free = &WFP_Free;
|
||||
|
@ -216,88 +232,142 @@ _FX BOOLEAN WFP_Init(void)
|
|||
|
||||
KeInitializeSpinLock(&WFP_MapLock);
|
||||
|
||||
if (!Mem_GetLockResource(&WFP_InitLock, TRUE))
|
||||
return FALSE;
|
||||
|
||||
NTSTATUS status = FwpmBfeStateSubscribeChanges((void*)Api_DeviceObject, WFP_state_changed, NULL, &WFP_state_handle);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrint("Sbie WFP failed to install state change callback\r\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (FwpmBfeStateGet() == FWPM_SERVICE_RUNNING)
|
||||
WFP_Install_Callbacks();
|
||||
else
|
||||
DbgPrint("Sbie WFP is not ready\r\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WFP_state_changed
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void WFP_state_changed(_Inout_ void* context, _In_ FWPM_SERVICE_STATE newState)
|
||||
{
|
||||
if (newState == FWPM_SERVICE_STOP_PENDING)
|
||||
WFP_Uninstall_Callbacks();
|
||||
else if (newState == FWPM_SERVICE_RUNNING)
|
||||
WFP_Install_Callbacks();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WFP_Install_Callbacks
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN WFP_Install_Callbacks(void)
|
||||
{
|
||||
ExAcquireResourceSharedLite(WFP_InitLock, TRUE);
|
||||
|
||||
if (WFP_engine_handle != NULL) {
|
||||
ExReleaseResourceLite(WFP_InitLock);
|
||||
return TRUE; // already initialized
|
||||
}
|
||||
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
DWORD stage = 0;
|
||||
|
||||
FWPM_SESSION wdf_session = { 0 };
|
||||
BOOLEAN in_transaction = FALSE;
|
||||
BOOLEAN callout_registered = FALSE;
|
||||
|
||||
|
||||
// Begin a transaction to the FilterEngine. You must register objects (filter, callouts, sublayers)
|
||||
//to the filter engine in the context of a 'transaction'
|
||||
wdf_session.flags = FWPM_SESSION_FLAG_DYNAMIC; // <-- Automatically destroys all filters and removes all callouts after this wdf_session ends
|
||||
status = FwpmEngineOpen(NULL, RPC_C_AUTHN_WINNT, NULL, &wdf_session, &WFP_engine_handle);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x10; if (!NT_SUCCESS(status)) goto Exit;
|
||||
status = FwpmTransactionBegin(WFP_engine_handle, 0);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x20; if (!NT_SUCCESS(status)) goto Exit;
|
||||
in_transaction = TRUE;
|
||||
|
||||
// Register a new sublayer to the filter engine
|
||||
status = WFP_RegisterSubLayer();
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x30; if (!NT_SUCCESS(status)) goto Exit;
|
||||
|
||||
//status = WFP_RegisterCallout(&WPF_CALLOUT_GUID_V4, &FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4, &WFP_callout_id_v4, &WFP_filter_id_v4);
|
||||
//if (!NT_SUCCESS(status)) goto Exit;
|
||||
//status = WFP_RegisterCallout(&WPF_CALLOUT_GUID_V6, &FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V6, &WFP_callout_id_v6, &WFP_filter_id_v6);
|
||||
//if (!NT_SUCCESS(status)) goto Exit;
|
||||
status = WFP_RegisterCallout(&WPF_SEND_CALLOUT_GUID_V4, &FWPM_LAYER_ALE_AUTH_CONNECT_V4, &WFP_send_callout_id_v4, &WFP_send_filter_id_v4);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x41; if (!NT_SUCCESS(status)) goto Exit;
|
||||
callout_registered = TRUE;
|
||||
status = WFP_RegisterCallout(&WPF_SEND_CALLOUT_GUID_V6, &FWPM_LAYER_ALE_AUTH_CONNECT_V6, &WFP_send_callout_id_v6, &WFP_send_filter_id_v6);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x42; if (!NT_SUCCESS(status)) goto Exit;
|
||||
status = WFP_RegisterCallout(&WPF_RECV_CALLOUT_GUID_V4, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, &WFP_recv_callout_id_v4, &WFP_recv_filter_id_v4);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x43; if (!NT_SUCCESS(status)) goto Exit;
|
||||
status = WFP_RegisterCallout(&WPF_RECV_CALLOUT_GUID_V6, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, &WFP_recv_callout_id_v6, &WFP_recv_filter_id_v6);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x44; if (!NT_SUCCESS(status)) goto Exit;
|
||||
|
||||
// note: we could also setup FWPM_LAYER_ALE_AUTH_LISTEN_V4 but since we block all accepts we dont have to
|
||||
|
||||
|
||||
// Commit transaction to the Filter Engine
|
||||
status = FwpmTransactionCommit(WFP_engine_handle);
|
||||
if (!NT_SUCCESS(status)) goto Exit;
|
||||
stage = 0x50; if (!NT_SUCCESS(status)) goto Exit;
|
||||
in_transaction = FALSE;
|
||||
|
||||
// Cleanup and handle any errors
|
||||
Exit:
|
||||
if (!NT_SUCCESS(status)){
|
||||
//DbgPrint("WFP initialization failed, status 0x%08x\r\n", status);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrint("Sbie WFP initialization failed, stage %02x, status 0x%08x\r\n", stage, status);
|
||||
|
||||
if (in_transaction == TRUE){
|
||||
if (in_transaction == TRUE) {
|
||||
FwpmTransactionAbort(WFP_engine_handle);
|
||||
_Analysis_assume_lock_not_held_(WFP_engine_handle); // Potential leak if "FwpmTransactionAbort" fails
|
||||
}
|
||||
if (WFP_engine_handle){
|
||||
FwpmEngineClose(WFP_engine_handle);
|
||||
WFP_engine_handle = NULL;
|
||||
}
|
||||
if (callout_registered) {
|
||||
FwpsCalloutUnregisterById(WFP_send_callout_id_v4);
|
||||
FwpsCalloutUnregisterById(WFP_send_callout_id_v6);
|
||||
FwpsCalloutUnregisterById(WFP_recv_callout_id_v4);
|
||||
FwpsCalloutUnregisterById(WFP_recv_callout_id_v6);
|
||||
}
|
||||
if (WFP_engine_handle) {
|
||||
FwpmEngineClose(WFP_engine_handle);
|
||||
WFP_engine_handle = NULL;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(WFP_InitLock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//DbgPrint("--- WFP initialized successfully ---\r\n");
|
||||
DbgPrint("Sbie WFP initialized successfully\r\n");
|
||||
ExReleaseResourceLite(WFP_InitLock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WFP_Unload
|
||||
// WFP_Uninstall_Callbacks
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void WFP_Unload(void)
|
||||
_FX void WFP_Uninstall_Callbacks(void)
|
||||
{
|
||||
ExAcquireResourceSharedLite(WFP_InitLock, TRUE);
|
||||
|
||||
if (WFP_engine_handle == NULL) {
|
||||
ExReleaseResourceLite(WFP_InitLock);
|
||||
return; // not initialized
|
||||
}
|
||||
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
UNICODE_STRING symlink = { 0 };
|
||||
|
||||
if (WFP_engine_handle == NULL)
|
||||
return;
|
||||
|
||||
//status = FwpsCalloutUnregisterById(WFP_callout_id_v4);
|
||||
//if (!NT_SUCCESS(status)) DbgPrint("Failed to unregister callout, status: 0x%08x\r\n", status);
|
||||
//status = FwpsCalloutUnregisterById(WFP_callout_id_v6);
|
||||
|
@ -312,14 +382,32 @@ _FX void WFP_Unload(void)
|
|||
//if (!NT_SUCCESS(status)) DbgPrint("Failed to unregister callout, status: 0x%08x\r\n", status);
|
||||
|
||||
// Close handle to the WFP Filter Engine
|
||||
if (WFP_engine_handle){
|
||||
if (WFP_engine_handle) {
|
||||
FwpmEngineClose(WFP_engine_handle);
|
||||
WFP_engine_handle = NULL;
|
||||
}
|
||||
|
||||
//DbgPrint("--- WFP uninitialized ---\r\n");
|
||||
DbgPrint("Sbie WFP uninitialized\r\n");
|
||||
ExReleaseResourceLite(WFP_InitLock);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// WFP_Unload
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void WFP_Unload(void)
|
||||
{
|
||||
if (!WFP_Enabled)
|
||||
return; // nothing to do
|
||||
|
||||
map_deinit(&WFP_Processes);
|
||||
|
||||
if (WFP_state_handle != NULL)
|
||||
FwpmBfeStateUnsubscribeChanges(WFP_state_handle);
|
||||
|
||||
WFP_Uninstall_Callbacks();
|
||||
}
|
||||
|
||||
|
||||
|
@ -468,9 +556,12 @@ BOOLEAN WFP_LoadRules(LIST* NetFwRules, PROCESS* proc)
|
|||
|
||||
BOOLEAN WFP_InitProcess(PROCESS* proc)
|
||||
{
|
||||
if (WFP_engine_handle == NULL)
|
||||
if (!WFP_Enabled)
|
||||
return TRUE; // nothing to do
|
||||
|
||||
if (WFP_engine_handle == NULL)
|
||||
return FALSE; // WFP was not ready report failure, cancel process creation
|
||||
|
||||
BOOLEAN ok = TRUE;
|
||||
KIRQL irql;
|
||||
|
||||
|
@ -512,8 +603,8 @@ finish:
|
|||
|
||||
BOOLEAN WFP_UpdateProcess(PROCESS* proc)
|
||||
{
|
||||
if (WFP_engine_handle == NULL)
|
||||
return TRUE; // feature disabled all ok
|
||||
if (!WFP_Enabled)
|
||||
return TRUE; // nothing to do
|
||||
|
||||
BOOLEAN ok = FALSE;
|
||||
KIRQL irql;
|
||||
|
@ -581,8 +672,8 @@ BOOLEAN WFP_UpdateProcess(PROCESS* proc)
|
|||
|
||||
void WFP_DeleteProcess(PROCESS* proc)
|
||||
{
|
||||
if (WFP_engine_handle == NULL)
|
||||
return; // nothing to go
|
||||
if (!WFP_Enabled)
|
||||
return; // nothing to do
|
||||
|
||||
KIRQL irql;
|
||||
WFP_PROCESS* wfp_proc;
|
||||
|
|
Loading…
Reference in New Issue