#define NDIS_SUPPORT_NDIS6 1 #define DEV_NAME L"\\Device\\MY_WFP_DEV_NAME" #define SYM_NAME L"\\DosDevices\\MY_WFP_SYM_NAME"
#include <ntifs.h> #include <fwpsk.h> #include <fwpmk.h> #include <stdio.h>
HANDLE g_hEngine;
ULONG32 g_AleConnectCalloutId;
ULONG64 g_AleConnectFilterId;
GUID GUID_ALE_AUTH_CONNECT_CALLOUT_V4 = { 0x6812fc83, 0x7d3e, 0x499a, 0xa0, 0x12, 0x55, 0xe0, 0xd8, 0x5f, 0x34, 0x8b };
NTSTATUS RegisterCalloutForLayer( IN PDEVICE_OBJECT pDevObj, 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 ULONG32 *calloutId, OUT ULONG64 *filterId, OUT HANDLE *engine);
NTSTATUS RegisterCallout( PDEVICE_OBJECT pDevObj, 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 ULONG32 *calloutId);
NTSTATUS SetFilter( IN const GUID *layerKey, IN const GUID *calloutKey, OUT ULONG64 *filterId, OUT HANDLE *engine);
VOID NTAPI flowDeleteFn( _In_ UINT16 layerId, _In_ UINT32 calloutId, _In_ UINT64 flowContext );
#if (NTDDI_VERSION >= NTDDI_WIN8) VOID NTAPI classifyFn( _In_ const FWPS_INCOMING_VALUES0* inFixedValues, _In_ const FWPS_INCOMING_METADATA_VALUES0* inMetaValues, _Inout_opt_ void* layerData, _In_opt_ const void* classifyContext, _In_ const FWPS_FILTER2* filter, _In_ UINT64 flowContext, _Inout_ FWPS_CLASSIFY_OUT0* classifyOut ); #elif (NTDDI_VERSION >= NTDDI_WIN7) VOID NTAPI classifyFn( _In_ const FWPS_INCOMING_VALUES0* inFixedValues, _In_ const FWPS_INCOMING_METADATA_VALUES0* inMetaValues, _Inout_opt_ void* layerData, _In_opt_ const void* classifyContext, _In_ const FWPS_FILTER1* filter, _In_ UINT64 flowContext, _Inout_ FWPS_CLASSIFY_OUT0* classifyOut ); #else VOID NTAPI classifyFn( _In_ const FWPS_INCOMING_VALUES0* inFixedValues, _In_ const FWPS_INCOMING_METADATA_VALUES0* inMetaValues, _Inout_opt_ void* layerData, _In_ const FWPS_FILTER0* filter, _In_ UINT64 flowContext, _Inout_ FWPS_CLASSIFY_OUT0* classifyOut ); #endif
#if (NTDDI_VERSION >= NTDDI_WIN8) NTSTATUS NTAPI notifyFn( _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType, _In_ const GUID* filterKey, _Inout_ FWPS_FILTER2* filter ); #elif (NTDDI_VERSION >= NTDDI_WIN7) NTSTATUS NTAPI notifyFn( _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType, _In_ const GUID* filterKey, _Inout_ FWPS_FILTER1* filter ); #else NTSTATUS NTAPI notifyFn( _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType, _In_ const GUID* filterKey, _Inout_ FWPS_FILTER0* filter ); #endif
NTSTATUS ProtocalIdToName(UINT16 protocalId, PCHAR lpszProtocalName) { NTSTATUS status = STATUS_SUCCESS;
switch (protocalId) { case 1: { RtlCopyMemory(lpszProtocalName, "ICMP", 5); break; } case 2: { RtlCopyMemory(lpszProtocalName, "IGMP", 5); break; } case 6: { RtlCopyMemory(lpszProtocalName, "TCP", 4); break; } case 17: { RtlCopyMemory(lpszProtocalName, "UDP", 4); break; } case 27: { RtlCopyMemory(lpszProtocalName, "RDP", 6); break; } default: { RtlCopyMemory(lpszProtocalName, "UNKNOWN", 8); break; } }
return status; }
NTSTATUS WfpLoad(PDEVICE_OBJECT pDevObj) { NTSTATUS status = STATUS_SUCCESS;
status = RegisterCalloutForLayer(pDevObj, &FWPM_LAYER_ALE_AUTH_CONNECT_V4, &GUID_ALE_AUTH_CONNECT_CALLOUT_V4, classifyFn, notifyFn, flowDeleteFn, &g_AleConnectCalloutId, &g_AleConnectFilterId, &g_hEngine); if (!NT_SUCCESS(status)) { DbgPrint("注册回调失败 \n"); return status; }
return status; }
NTSTATUS WfpUnload() { if (NULL != g_hEngine) { FwpmFilterDeleteById(g_hEngine, g_AleConnectFilterId); FwpmCalloutDeleteById(g_hEngine, g_AleConnectCalloutId); g_AleConnectFilterId = 0; FwpsCalloutUnregisterById(g_AleConnectCalloutId); g_AleConnectCalloutId = 0; FwpmEngineClose(g_hEngine); g_hEngine = NULL; }
return STATUS_SUCCESS; }
NTSTATUS RegisterCalloutForLayer(IN PDEVICE_OBJECT pDevObj, 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 ULONG32 *calloutId, OUT ULONG64 *filterId, OUT HANDLE *engine) { NTSTATUS status = STATUS_SUCCESS;
status = RegisterCallout(pDevObj, calloutKey, classifyFn, notifyFn, flowDeleteNotifyFn, calloutId); if (!NT_SUCCESS(status)) { return status; }
status = SetFilter(layerKey, calloutKey, filterId, engine); if (!NT_SUCCESS(status)) { return status; }
return status; }
NTSTATUS RegisterCallout(PDEVICE_OBJECT pDevObj, 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 ULONG32 *calloutId) { NTSTATUS status = STATUS_SUCCESS; FWPS_CALLOUT sCallout = { 0 };
sCallout.calloutKey = *calloutKey; sCallout.classifyFn = classifyFn; sCallout.flowDeleteFn = flowDeleteNotifyFn; sCallout.notifyFn = notifyFn;
status = FwpsCalloutRegister(pDevObj, &sCallout, calloutId); if (!NT_SUCCESS(status)) { DbgPrint("注册Callout失败 \n"); return status; }
return status; }
NTSTATUS SetFilter(IN const GUID *layerKey, IN const GUID *calloutKey, OUT ULONG64 *filterId, OUT HANDLE *engine) { HANDLE hEngine = NULL; NTSTATUS status = STATUS_SUCCESS; FWPM_SESSION session = { 0 }; FWPM_FILTER mFilter = { 0 }; FWPM_CALLOUT mCallout = { 0 }; FWPM_DISPLAY_DATA mDispData = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC; status = FwpmEngineOpen(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &hEngine); if (!NT_SUCCESS(status)) { return status; }
status = FwpmTransactionBegin(hEngine, 0); if (!NT_SUCCESS(status)) { return status; }
mDispData.name = L"MY WFP LyShark"; mDispData.description = L"WORLD OF DEMON"; mCallout.applicableLayer = *layerKey; mCallout.calloutKey = *calloutKey; mCallout.displayData = mDispData;
status = FwpmCalloutAdd(hEngine, &mCallout, NULL, NULL); if (!NT_SUCCESS(status)) { return status; }
mFilter.action.calloutKey = *calloutKey; mFilter.action.type = FWP_ACTION_CALLOUT_TERMINATING; mFilter.displayData.name = L"MY WFP LyShark"; mFilter.displayData.description = L"WORLD OF DEMON"; mFilter.layerKey = *layerKey; mFilter.subLayerKey = FWPM_SUBLAYER_UNIVERSAL; mFilter.weight.type = FWP_EMPTY;
status = FwpmFilterAdd(hEngine, &mFilter, NULL, filterId); if (!NT_SUCCESS(status)) { return status; }
status = FwpmTransactionCommit(hEngine); if (!NT_SUCCESS(status)) { return status; }
*engine = hEngine; return status; }
VOID NTAPI classifyFn(_In_ const FWPS_INCOMING_VALUES0* inFixedValues, _In_ const FWPS_INCOMING_METADATA_VALUES0* inMetaValues, _Inout_opt_ void* layerData, _In_opt_ const void* classifyContext, _In_ const FWPS_FILTER2* filter, _In_ UINT64 flowContext, _Inout_ FWPS_CLASSIFY_OUT0* classifyOut) { WORD wDirection = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_DIRECTION].value.int8;
ULONG ulLocalIp = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS].value.uint32; UINT16 uLocalPort = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_PORT].value.uint16;
ULONG ulRemoteIp = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32; UINT16 uRemotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;
KIRQL kCurrentIrql = KeGetCurrentIrql();
ULONG64 processId = inMetaValues->processId; UCHAR szProcessPath[256] = { 0 }; CHAR szProtocalName[256] = { 0 }; RtlZeroMemory(szProcessPath, 256);
for (ULONG i = 0; i < inMetaValues->processPath->size; i++) { szProcessPath[i] = inMetaValues->processPath->data[i]; }
ProtocalIdToName(inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL].value.uint16, szProtocalName);
classifyOut->actionType = FWP_ACTION_PERMIT;
if (NULL != wcsstr((PWCHAR)szProcessPath, L"iexplore.exe")) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights = classifyOut->rights & (~FWPS_RIGHT_ACTION_WRITE); classifyOut->flags = classifyOut->flags | FWPS_CLASSIFY_OUT_FLAG_ABSORB; DbgPrint("[LyShark.com] 拦截IE网络链接请求... \n"); }
char szRemoteAddress[256] = { 0 }; char szRemotePort[128] = { 0 };
char szLocalAddress[256] = { 0 }; char szLocalPort[128] = { 0 };
sprintf(szRemoteAddress, "%u.%u.%u.%u", (ulRemoteIp >> 24) & 0xFF, (ulRemoteIp >> 16) & 0xFF, (ulRemoteIp >> 8) & 0xFF, (ulRemoteIp)& 0xFF); sprintf(szRemotePort, "%d", uRemotePort);
sprintf(szLocalAddress, "%u.%u.%u.%u", (ulLocalIp >> 24) & 0xFF, (ulLocalIp >> 16) & 0xFF, (ulLocalIp >> 8) & 0xFF, (ulLocalIp)& 0xFF); sprintf(szLocalPort, "%d", uLocalPort);
if (strcmp(szRemoteAddress, "8.141.58.64") == 0 && strcmp(szRemotePort, "443") == 0) { DbgPrint("[LyShark.com] 拦截网站访问请求 --> %s : %s \n", szRemoteAddress, szRemotePort); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights = classifyOut->rights & (~FWPS_RIGHT_ACTION_WRITE); classifyOut->flags = classifyOut->flags | FWPS_CLASSIFY_OUT_FLAG_ABSORB; } else if (strcmp(szRemotePort, "0") == 0) { DbgPrint("[LyShark.com] 拦截Ping访问请求 --> %s \n", szRemoteAddress);
classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights = classifyOut->rights & (~FWPS_RIGHT_ACTION_WRITE); classifyOut->flags = classifyOut->flags | FWPS_CLASSIFY_OUT_FLAG_ABSORB; }
DbgPrint("[LyShark.com] 方向: %d -> 协议类型: %s -> 本端地址: %u.%u.%u.%u:%d -> 对端地址: %u.%u.%u.%u:%d -> IRQL: %d -> 进程ID: %I64d -> 路径: %S \n", wDirection, szProtocalName, (ulLocalIp >> 24) & 0xFF, (ulLocalIp >> 16) & 0xFF, (ulLocalIp >> 8) & 0xFF, (ulLocalIp)& 0xFF, uLocalPort, (ulRemoteIp >> 24) & 0xFF, (ulRemoteIp >> 16) & 0xFF, (ulRemoteIp >> 8) & 0xFF, (ulRemoteIp)& 0xFF, uRemotePort, kCurrentIrql, processId, (PWCHAR)szProcessPath); }
NTSTATUS NTAPI notifyFn(_In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType, _In_ const GUID* filterKey, _Inout_ FWPS_FILTER2* filter) { NTSTATUS status = STATUS_SUCCESS; return status; }
VOID NTAPI flowDeleteFn(_In_ UINT16 layerId, _In_ UINT32 calloutId, _In_ UINT64 flowContext) { return; }
NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status; }
NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT pDevObj = NULL; UNICODE_STRING ustrDevName, ustrSymName; RtlInitUnicodeString(&ustrDevName, DEV_NAME); RtlInitUnicodeString(&ustrSymName, SYM_NAME);
status = IoCreateDevice(pDriverObject, 0, &ustrDevName, FILE_DEVICE_NETWORK, 0, FALSE, &pDevObj); if (!NT_SUCCESS(status)) { return status; } status = IoCreateSymbolicLink(&ustrSymName, &ustrDevName); if (!NT_SUCCESS(status)) { return status; } return status; }
VOID UnDriver(PDRIVER_OBJECT driver) { WfpUnload();
UNICODE_STRING ustrSymName; RtlInitUnicodeString(&ustrSymName, SYM_NAME); IoDeleteSymbolicLink(&ustrSymName); if (driver->DeviceObject) { IoDeleteDevice(driver->DeviceObject); } }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; Driver->DriverUnload = UnDriver; for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { Driver->MajorFunction[i] = DriverDefaultHandle; }
CreateDevice(Driver);
WfpLoad(Driver->DeviceObject);
Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
|