2025-05-13 19:49:49 +03:00

789 lines
29 KiB
C

/*
* Process Hacker Extra Plugins -
* Firewall Monitor
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fwmon.h"
#define FWP_DIRECTION_IN 0x00003900L
#define FWP_DIRECTION_OUT 0x00003901L
#define FWP_DIRECTION_FORWARD 0x00003902L
PH_CALLBACK_DECLARE(FwItemAddedEvent);
PH_CALLBACK_DECLARE(FwItemModifiedEvent);
PH_CALLBACK_DECLARE(FwItemRemovedEvent);
PH_CALLBACK_DECLARE(FwItemsUpdatedEvent);
static PH_CALLBACK_REGISTRATION ProcessesUpdatedCallbackRegistration;
static PPH_OBJECT_TYPE FwObjectType = NULL;
static HANDLE FwEngineHandle = NULL;
static HANDLE FwEventHandle = NULL;
static HANDLE FwEnumHandle = NULL;
static _FwpmNetEventSubscribe1 FwpmNetEventSubscribe1_I = NULL;
static VOID NTAPI FwObjectTypeDeleteProcedure(
_In_ PVOID Object,
_In_ ULONG Flags
)
{
PhClearReference(&Object);
}
PFW_EVENT_ITEM EtCreateFirewallEntryItem(
VOID
)
{
static ULONG itemCount = 0;
PFW_EVENT_ITEM diskItem;
diskItem = PhCreateObject(sizeof(FW_EVENT_ITEM), FwObjectType);
memset(diskItem, 0, sizeof(FW_EVENT_ITEM));
diskItem->Index = itemCount;
diskItem->IndexString = PhFormatString(L"%lu", itemCount);
itemCount++;
return diskItem;
}
static VOID CALLBACK DropEventCallback(
_Inout_ PVOID FwContext,
_In_ const FWPM_NET_EVENT* FwEvent
)
{
PFW_EVENT_ITEM fwEventItem = EtCreateFirewallEntryItem();
SYSTEMTIME systemTime;
PhQuerySystemTime(&fwEventItem->AddedTime);
PhLargeIntegerToLocalSystemTime(&systemTime, &fwEventItem->AddedTime);
fwEventItem->TimeString = PhFormatDateTime(&systemTime);
switch (FwEvent->type)
{
case FWPM_NET_EVENT_TYPE_CLASSIFY_DROP:
{
FWPM_FILTER* fwFilterItem = NULL;
FWPM_LAYER* fwLayerItem = NULL;
FWPM_NET_EVENT_CLASSIFY_DROP* fwDropEvent = FwEvent->classifyDrop;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"DROP");
if (FwpmFilterGetById(FwEngineHandle, fwDropEvent->filterId, &fwFilterItem) == ERROR_SUCCESS)
{
if (fwFilterItem->displayData.name)
{
fwEventItem->FwRuleNameString = PhCreateString(fwFilterItem->displayData.name);
}
if (fwFilterItem->displayData.description)
{
fwEventItem->FwRuleDescriptionString = PhCreateString(fwFilterItem->displayData.description);
}
if ((fwFilterItem->action.type & FWP_ACTION_BLOCK) != 0)
{
}
FwpmFreeMemory(&fwFilterItem);
}
if (FwpmLayerGetById(FwEngineHandle, fwDropEvent->layerId, &fwLayerItem) == ERROR_SUCCESS)
{
if (fwLayerItem->displayData.name)
{
fwEventItem->FwRuleLayerNameString = PhCreateString(fwLayerItem->displayData.name);
}
//fwEventItem->FwRuleLayerDescriptionString = PhCreateString(fwLayerRuleItem->displayData.description);
for (UINT32 i = 0; i < fwLayerItem->numFields; i++)
{
FWPM_FIELD fwRuleField = fwLayerItem->field[i];
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363996.aspx
if (memcmp(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_APP_ID, sizeof(GUID)) == 0)
{
//The fully qualified device path of the application, as returned by the FwpmGetAppIdFromFileName0 function.
// (For example, "\device0\hardiskvolume1\Program Files\Application.exe".)
// Data type : FWP_BYTE_BLOB_TYPE
//fwDropEvent->
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_ORIGINAL_APP_ID))
{
// The fully qualified device path of the application, such as "\device0\hardiskvolume1\Program Files\Application.exe".
// When a connection has been redirected, this will be the identifier of the originating app,
// otherwise this will be the same as FWPM_CONDITION_ALE_APP_ID.
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_USER_ID))
{
//The identification of the local user.
//Data type : FWP_SECURITY_DESCRIPTOR_TYPE
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS))
{
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS_TYPE))
{
//The local IP address type.
//Possible values : Any of the following NL_ADDRESS_TYPE enumeration values.
//NlatUnspecified
//NlatUnicast
//NlatAnycast
//NlatMulticast
//NlatBroadcast
//Data type : FWP_UINT8
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_PORT))
{
//The local transport protocol port number.
//Data type : FWP_UINT16
}
//else
//{
// PhInitializeStringRef(&fwEventItem->FwRuleModeString, L"UNKNOWN");
//}
}
FwpmFreeMemory(&fwLayerItem);
}
if (fwDropEvent->isLoopback)
{
PhInitializeStringRef(&fwEventItem->DirectionString, L"Loopback");
}
else
{
switch (fwDropEvent->msFwpDirection)
{
case FWP_DIRECTION_IN:
case FWP_DIRECTION_INBOUND:
PhInitializeStringRef(&fwEventItem->DirectionString, L"In");
break;
case FWP_DIRECTION_OUT:
case FWP_DIRECTION_OUTBOUND:
PhInitializeStringRef(&fwEventItem->DirectionString, L"Out");
break;
case FWP_DIRECTION_FORWARD:
PhInitializeStringRef(&fwEventItem->DirectionString, L"Forward");
break;
default:
PhInitializeStringRef(&fwEventItem->DirectionString, L"");
break;
}
}
}
break;
case FWPM_NET_EVENT_TYPE_CLASSIFY_ALLOW:
{
FWPM_FILTER* fwFilterItem = NULL;
FWPM_LAYER* fwLayerItem = NULL;
FWPM_NET_EVENT_CLASSIFY_ALLOW* fwAllowEvent = FwEvent->classifyAllow;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"ALLOW");
if (FwpmFilterGetById(FwEngineHandle, fwAllowEvent->filterId, &fwFilterItem) == ERROR_SUCCESS)
{
if (fwFilterItem->displayData.name)
{
fwEventItem->FwRuleNameString = PhCreateString(fwFilterItem->displayData.name);
}
if (fwFilterItem->displayData.description)
{
fwEventItem->FwRuleDescriptionString = PhCreateString(fwFilterItem->displayData.description);
}
if ((fwFilterItem->action.type & FWP_ACTION_BLOCK) != 0)
{
}
FwpmFreeMemory(&fwFilterItem);
}
if (FwpmLayerGetById(FwEngineHandle, fwAllowEvent->layerId, &fwLayerItem) == ERROR_SUCCESS)
{
for (UINT32 i = 0; i < fwLayerItem->numFields; i++)
{
FWPM_FIELD fwRuleField = fwLayerItem->field[i];
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363996.aspx
if (memcmp(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_APP_ID, sizeof(GUID)) == 0)
{
//The fully qualified device path of the application, as returned by the FwpmGetAppIdFromFileName0 function.
// (For example, "\device0\hardiskvolume1\Program Files\Application.exe".)
// Data type : FWP_BYTE_BLOB_TYPE
//fwAllowEvent->
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_ORIGINAL_APP_ID))
{
// The fully qualified device path of the application, such as "\device0\hardiskvolume1\Program Files\Application.exe".
// When a connection has been redirected, this will be the identifier of the originating app,
// otherwise this will be the same as FWPM_CONDITION_ALE_APP_ID.
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_USER_ID))
{
//The identification of the local user.
//Data type : FWP_SECURITY_DESCRIPTOR_TYPE
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS))
{
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS_TYPE))
{
//The local IP address type.
//Possible values : Any of the following NL_ADDRESS_TYPE enumeration values.
//NlatUnspecified
//NlatUnicast
//NlatAnycast
//NlatMulticast
//NlatBroadcast
//Data type : FWP_UINT8
}
else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_PORT))
{
//The local transport protocol port number.
//Data type : FWP_UINT16
}
//else
//{
// PhInitializeStringRef(&fwEventItem->FwRuleModeString, L"UNKNOWN");
//}
}
fwEventItem->FwRuleLayerNameString = PhCreateString(fwLayerItem->displayData.name);
//fwEventItem->FwRuleLayerDescriptionString = PhCreateString(fwLayerRuleItem->displayData.description);
FwpmFreeMemory(&fwLayerItem);
}
if (fwAllowEvent->isLoopback)
{
PhInitializeStringRef(&fwEventItem->DirectionString, L"Loopback");
}
else
{
switch (fwAllowEvent->msFwpDirection)
{
case FWP_DIRECTION_IN:
case FWP_DIRECTION_INBOUND:
PhInitializeStringRef(&fwEventItem->DirectionString, L"In");
break;
case FWP_DIRECTION_OUT:
case FWP_DIRECTION_OUTBOUND:
PhInitializeStringRef(&fwEventItem->DirectionString, L"Out");
break;
case FWP_DIRECTION_FORWARD:
PhInitializeStringRef(&fwEventItem->DirectionString, L"Forward");
break;
default:
PhInitializeStringRef(&fwEventItem->DirectionString, L"");
break;
}
}
}
break;
case FWPM_NET_EVENT_TYPE_CAPABILITY_DROP:
//FWPM_NET_EVENT_CAPABILITY_DROP* fwCapDropEvent = FwEvent->capabilityDrop;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"CAPABILITY_DROP");
return;
case FWPM_NET_EVENT_TYPE_CAPABILITY_ALLOW:
//FWPM_NET_EVENT_CAPABILITY_ALLOW* fwCapAllowEvent = FwEvent->capabilityAllow;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"CAPABILITY_ALLOW");
return;
case FWPM_NET_EVENT_TYPE_CLASSIFY_DROP_MAC:
//FWPM_NET_EVENT_CLASSIFY_DROP_MAC* fwMacDropEvent = FwEvent->classifyDropMac;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"CLASSIFY_DROP_MAC");
break;
case FWPM_NET_EVENT_TYPE_IPSEC_KERNEL_DROP:
//FWPM_NET_EVENT_IPSEC_KERNEL_DROP* fwIpSecDropEvent = FwEvent->ipsecDrop;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"IPSEC_KERNEL_DROP");
break;
case FWPM_NET_EVENT_TYPE_IPSEC_DOSP_DROP:
//FWPM_NET_EVENT_IPSEC_DOSP_DROP* fwIpSecDoSDropEvent = FwEvent->idpDrop;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"IPSEC_DOSP_DROP");
break;
case FWPM_NET_EVENT_TYPE_IKEEXT_MM_FAILURE:
//FWPM_NET_EVENT_IKEEXT_MM_FAILURE* fwIkeextMMFailureEvent = FwEvent->ikeMmFailure;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"IKEEXT_MM_FAILURE");
break;
case FWPM_NET_EVENT_TYPE_IKEEXT_QM_FAILURE:
//FWPM_NET_EVENT_IKEEXT_QM_FAILURE* fwIkeextQMFailureEvent = FwEvent->ikeQmFailure;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"QM_FAILURE");
break;
case FWPM_NET_EVENT_TYPE_IKEEXT_EM_FAILURE:
//FWPM_NET_EVENT_IKEEXT_EM_FAILURE* fwIkeextEMFailureEvent = FwEvent->ikeEmFailure;
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"EM_FAILURE");
break;
default:
PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"unknown");
break;
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_PORT_SET) != 0)
{
fwEventItem->LocalPort = FwEvent->header.localPort;
fwEventItem->LocalPortString = PhFormatString(L"%u", FwEvent->header.localPort);
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_PORT_SET) != 0)
{
fwEventItem->RemotePort = FwEvent->header.remotePort;
fwEventItem->RemotePortString = PhFormatString(L"%u", FwEvent->header.remotePort);
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_IP_VERSION_SET) != 0)
{
if (FwEvent->header.ipVersion == FWP_IP_VERSION_V4)
{
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_ADDR_SET) != 0)
{
//IN_ADDR ipv4Address = { 0 };
//PWSTR ipv4StringTerminator = 0;
//WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
//
//ULONG localAddrV4 = _byteswap_ulong(FwEvent->header.localAddrV4);
//
//RtlIpv4AddressToString((PIN_ADDR)&localAddrV4, ipv4AddressString);
//RtlIpv4StringToAddress(ipv4AddressString, TRUE, &ipv4StringTerminator, &ipv4Address);
//
//fwEventItem->LocalAddressString = PhFormatString(L"%s", ipv4AddressString);
fwEventItem->LocalAddressString = PhFormatString(
L"%lu.%lu.%lu.%lu",
((PBYTE)&FwEvent->header.localAddrV4)[3],
((PBYTE)&FwEvent->header.localAddrV4)[2],
((PBYTE)&FwEvent->header.localAddrV4)[1],
((PBYTE)&FwEvent->header.localAddrV4)[0]
);
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_ADDR_SET) != 0)
{
//IN_ADDR ipv4Address = { 0 };
//PWSTR ipv4StringTerminator = 0;
//WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
//
//ULONG remoteAddrV4 = _byteswap_ulong(FwEvent->header.remoteAddrV4);
//
//RtlIpv4AddressToString((PIN_ADDR)&remoteAddrV4, ipv4AddressString);
//RtlIpv4StringToAddress(ipv4AddressString, TRUE, &ipv4StringTerminator, &ipv4Address);
//
//fwEventItem->RemoteAddressString = PhFormatString(L"%s", ipv4AddressString);
fwEventItem->RemoteAddressString = PhFormatString(
L"%lu.%lu.%lu.%lu",
((PBYTE)&FwEvent->header.remoteAddrV4)[3],
((PBYTE)&FwEvent->header.remoteAddrV4)[2],
((PBYTE)&FwEvent->header.remoteAddrV4)[1],
((PBYTE)&FwEvent->header.remoteAddrV4)[0]
);
}
}
else if (FwEvent->header.ipVersion == FWP_IP_VERSION_V6)
{
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_ADDR_SET) != 0)
{
IN6_ADDR ipv6Address = { 0 };
PWSTR ipv6StringTerminator = 0;
WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
RtlIpv6AddressToString((struct in6_addr*)&FwEvent->header.localAddrV6, ipv6AddressString);
RtlIpv6StringToAddress(ipv6AddressString, &ipv6StringTerminator, &ipv6Address);
fwEventItem->LocalAddressString = PhFormatString(L"%s", ipv6AddressString);
//fwEventItem->LocalAddressString = PhFormatString(
// L"%x:%x:%x:%x%x:%x:%x:%x",
// ((WORD*)&FwEvent->header.localAddrV6)[7],
// ((WORD*)&FwEvent->header.localAddrV6)[6],
// ((WORD*)&FwEvent->header.localAddrV6)[5],
// ((WORD*)&FwEvent->header.localAddrV6)[4],
// ((WORD*)&FwEvent->header.localAddrV6)[3],
// ((WORD*)&FwEvent->header.localAddrV6)[2],
// ((WORD*)&FwEvent->header.localAddrV6)[1],
// ((WORD*)&FwEvent->header.localAddrV6)[0]
// );
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_ADDR_SET) != 0)
{
WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
PWSTR ipv6StringTerminator = 0;
IN6_ADDR ipv6Address = { 0 };
RtlIpv6AddressToString((struct in6_addr*)&FwEvent->header.remoteAddrV6, ipv6AddressString);
RtlIpv6StringToAddress(ipv6AddressString, &ipv6StringTerminator, &ipv6Address);
fwEventItem->RemoteAddressString = PhFormatString(L"%s", ipv6AddressString);
//fwEventItem->RemoteAddressString = PhFormatString(
// L"%x:%x:%x:%x%x:%x:%x:%x",
// ((WORD*)&FwEvent->header.remoteAddrV6)[7],
// ((WORD*)&FwEvent->header.remoteAddrV6)[6],
// ((WORD*)&FwEvent->header.remoteAddrV6)[5],
// ((WORD*)&FwEvent->header.remoteAddrV6)[4],
// ((WORD*)&FwEvent->header.remoteAddrV6)[3],
// ((WORD*)&FwEvent->header.remoteAddrV6)[2],
// ((WORD*)&FwEvent->header.remoteAddrV6)[1],
// ((WORD*)&FwEvent->header.remoteAddrV6)[0]
// );
}
}
else
{
//FwEvent->header.addressFamily Available when ipVersion is FWP_IP_VERSION_NONE.
}
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_APP_ID_SET) != 0)
{
PPH_STRING fileName = NULL;
PPH_STRING resolvedName = NULL;
if (FwEvent->header.appId.data && FwEvent->header.appId.size > 0)
{
fileName = PhCreateStringEx((PWSTR)FwEvent->header.appId.data, (SIZE_T)FwEvent->header.appId.size);
resolvedName = PhResolveDevicePrefix(fileName);
PhDereferenceObject(fileName);
}
if (resolvedName)
{
fwEventItem->ProcessNameString = PhGetFileName(resolvedName);
fwEventItem->ProcessBaseString = PhGetBaseName(resolvedName);
//FWP_BYTE_BLOB* fwpApplicationByteBlob = NULL;
//if (FwpmGetAppIdFromFileName(fileNameString->Buffer, &fwpApplicationByteBlob) == ERROR_SUCCESS)
//fwEventItem->ProcessBaseString = PhCreateStringEx(fwpApplicationByteBlob->data, fwpApplicationByteBlob->size);
//fwEventItem->Icon = PhGetFileShellIcon(PhGetString(resolvedName), L".exe", FALSE);
PhDereferenceObject(resolvedName);
}
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_USER_ID_SET) != 0)
{
if (RtlValidSid(FwEvent->header.userId))
{
fwEventItem->UserNameString = PhGetSidFullName(FwEvent->header.userId, TRUE, NULL);
}
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_IP_PROTOCOL_SET))
{
// The ipProtocol member is set.
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_SCOPE_ID_SET))
{
// The scopeId member is set.
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REAUTH_REASON_SET) != 0)
{
// Indicates an existing connection was reauthorized.
}
if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_PACKAGE_ID_SET) != 0)
{
// The packageSid member is set.
}
switch (FwEvent->header.ipProtocol)
{
case IPPROTO_HOPOPTS:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"HOPOPTS");
break;
case IPPROTO_ICMP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ICMP");
break;
case IPPROTO_IGMP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IGMP");
break;
case IPPROTO_GGP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"GGP");
break;
case IPPROTO_IPV4:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPv4");
break;
case IPPROTO_ST:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ST");
break;
case IPPROTO_TCP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"TCP");
break;
case IPPROTO_CBT:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"CBT");
break;
case IPPROTO_EGP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"EGP");
break;
case IPPROTO_IGP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IGP");
break;
case IPPROTO_PUP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"PUP");
break;
case IPPROTO_UDP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"UDP");
break;
case IPPROTO_IDP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IDP");
break;
case IPPROTO_RDP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"RDP");
break;
case IPPROTO_IPV6:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPv6");
break;
case IPPROTO_ROUTING:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ROUTING");
break;
case IPPROTO_FRAGMENT:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"FRAGMENT");
break;
case IPPROTO_ESP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ESP");
break;
case IPPROTO_AH:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"AH");
break;
case IPPROTO_ICMPV6:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ICMPv6");
break;
case IPPROTO_DSTOPTS:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"DSTOPTS");
break;
case IPPROTO_ND:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ND");
break;
case IPPROTO_ICLFXBM:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"ICLFXBM");
break;
case IPPROTO_PIM:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"PIM");
break;
case IPPROTO_PGM:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"PGM");
break;
case IPPROTO_L2TP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"L2TP");
break;
case IPPROTO_SCTP:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"SCTP");
break;
case IPPROTO_RESERVED_IPSEC:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPSEC");
break;
case IPPROTO_RESERVED_IPSECOFFLOAD:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPSECOFFLOAD");
break;
case IPPROTO_RESERVED_WNV:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"WNV");
break;
case IPPROTO_RAW:
case IPPROTO_RESERVED_RAW:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"RAW");
break;
case IPPROTO_NONE:
default:
PhInitializeStringRef(&fwEventItem->ProtocalString, L"Unknown");
break;
}
PhInvokeCallback(&FwItemAddedEvent, fwEventItem);
}
static VOID NTAPI ProcessesUpdatedCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
static LARGE_INTEGER systemTime;
PhQuerySystemTime(&systemTime);
for (ULONG i = 0; i < FwNodeList->Count; i++)
{
PFW_EVENT_NODE node = (PFW_EVENT_NODE)FwNodeList->Items[i];
if (systemTime.QuadPart > (node->EventItem->AddedTime.QuadPart + (60 * PH_TIMEOUT_SEC)))
{
PhInvokeCallback(&FwItemRemovedEvent, node);
}
}
PhInvokeCallback(&FwItemsUpdatedEvent, NULL);
}
BOOLEAN StartFwMonitor(
VOID
)
{
FWP_VALUE value = { FWP_EMPTY };
FWPM_SESSION session = { 0 };
FWPM_NET_EVENT_SUBSCRIPTION subscription = { 0 };
FWPM_NET_EVENT_ENUM_TEMPLATE eventTemplate = { 0 };
FwpmNetEventSubscribe1_I = PhGetModuleProcAddress(L"fwpuclnt.dll", "FwpmNetEventSubscribe1");
FwNodeList = PhCreateList(100);
FwObjectType = PhCreateObjectType(L"FwObject", 0, FwObjectTypeDeleteProcedure);
session.flags = 0;
session.displayData.name = L"PhFirewallMonitoringSession";
session.displayData.description = L"Non-Dynamic session for Process Hacker";
// Create a non-dynamic BFE session
if (FwpmEngineOpen(
NULL,
RPC_C_AUTHN_WINNT,
NULL,
&session,
&FwEngineHandle
) != ERROR_SUCCESS)
{
return FALSE;
}
value.type = FWP_UINT32;
value.uint32 = 1;
// Enable collection of NetEvents
if (FwpmEngineSetOption(
FwEngineHandle,
FWPM_ENGINE_COLLECT_NET_EVENTS,
&value
) != ERROR_SUCCESS)
{
return FALSE;
}
if (WindowsVersion > WINDOWS_7)
{
value.type = FWP_UINT32;
value.uint32 = FWPM_NET_EVENT_KEYWORD_CAPABILITY_DROP | FWPM_NET_EVENT_KEYWORD_CAPABILITY_ALLOW | FWPM_NET_EVENT_KEYWORD_CLASSIFY_ALLOW; // FWPM_NET_EVENT_KEYWORD_INBOUND_MCAST | FWPM_NET_EVENT_KEYWORD_INBOUND_BCAST
if (FwpmEngineSetOption(
FwEngineHandle,
FWPM_ENGINE_NET_EVENT_MATCH_ANY_KEYWORDS,
&value
) != ERROR_SUCCESS)
{
return FALSE;
}
value.type = FWP_UINT32;
value.uint32 = 1;
if (FwpmEngineSetOption(
FwEngineHandle,
FWPM_ENGINE_MONITOR_IPSEC_CONNECTIONS,
&value
) != ERROR_SUCCESS)
{
return FALSE;
}
}
eventTemplate.numFilterConditions = 0; // get events for all conditions
subscription.sessionKey = session.sessionKey;
subscription.enumTemplate = &eventTemplate;
// Subscribe to the events
if (FwpmNetEventSubscribe1_I)
{
if (FwpmNetEventSubscribe1_I(
FwEngineHandle,
&subscription,
DropEventCallback,
NULL,
&FwEventHandle
) != ERROR_SUCCESS)
{
return FALSE;
}
}
else
{
if (FwpmNetEventSubscribe0(
FwEngineHandle,
&subscription,
(FWPM_NET_EVENT_CALLBACK0)DropEventCallback, // TODO: Use correct function.
NULL,
&FwEventHandle
) != ERROR_SUCCESS)
{
return FALSE;
}
}
PhRegisterCallback(
&PhProcessesUpdatedEvent,
ProcessesUpdatedCallback,
NULL,
&ProcessesUpdatedCallbackRegistration
);
return TRUE;
}
VOID StopFwMonitor(
VOID
)
{
if (FwEventHandle)
{
FwpmNetEventUnsubscribe(FwEngineHandle, FwEventHandle);
FwEventHandle = NULL;
}
if (FwEngineHandle)
{
//FWP_VALUE value = { FWP_EMPTY };
//value.type = FWP_UINT32;
//value.uint32 = 0;
// TODO: return to previous state if other applications require event collection enabled??
// Disable collection of NetEvents
//FwpmEngineSetOption(FwEngineHandle, FWPM_ENGINE_COLLECT_NET_EVENTS, &value);
FwpmEngineClose(FwEngineHandle);
FwEngineHandle = NULL;
}
}