最近闲来无事,翻看wfp的资料,发现WFP真是好用,就是资料太稀少~好在有WDK的src目录和万能的搜索引擎. 后来发现http://www.cnblogs.com/nevergone/archive/2013/04/05/3001765.html 挺不错的,于是就把那份代码给改了一下,做一个网络日志记录小程序.
#ifndef __MAIN_H__
#define __MAIN_H__
#include <ntifs.h>
#include <ip2string.h>
#pragma warning(push)
#pragma warning(disable: 4201)
#pragma warning(disable: 4324)
#include <fwpsk.h>
#include <fwpmk.h>
#pragma warning(pop)
#define INITGUID
#include <guiddef.h>
//
// Callout and sublayer GUIDs
//
DEFINE_GUID(
SF_ALE_CONNECT_CALLOUT_V4,
0x76b743d4,
0x1249,
0x4610,
0xa6, 0x32, 0x6f, 0x9c, 0x4d, 0x08, 0xd2, 0x5a
);
DEFINE_GUID(
SF_ALE_RECV_ACCEPT_CALLOUT_V4,
0x7ec7f7f5,
0x1249,
0x4614,
0xa6, 0x32, 0x6f, 0x9c, 0x4d, 0x08, 0xd2, 0x5a
);
DEFINE_GUID(
SF_ALE_ESTABLISHED_CALLOUT_V4,
0x7ec7f7f5,
0x1249,
0x4618,
0xa6, 0x32, 0x6f, 0x9c, 0x4d, 0x08, 0xd2, 0x5a
);
DEFINE_GUID(
SF_SUBLAYER,
0x7ec7f7f5,
0x1249,
0x4620,
0xa6, 0x32, 0x6f, 0x9c, 0x4d, 0x08, 0xd2, 0x5a
);
typedef enum _OP_TYPE
{
OP_NONE = 0,
OP_CONNECT = 1,
OP_ACCEPT = 2,
OP_ESTABLISHED = 3,
}OP_TYPE;
typedef struct _CALLOUT_INFO
{
LIST_ENTRY List;
LARGE_INTEGER Time;
OP_TYPE Type;
ULONG ProcessId;
//UINT64 calloutId;
ULONG localAddressV4;
USHORT localPort;
ULONG remoteAddressV4;
USHORT remotePort;
USHORT ipProto;
WCHAR ProcessPath[1];
} CALLOUT_INFO, *PCALLOUT_INFO;
NTSTATUS
DriverEntry(
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
);
VOID
DriverUnload(
__in PDRIVER_OBJECT DriverObject
);
NTSTATUS
DeviceDispatch(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
);
NTSTATUS
SFRegistryCallouts(
__in PDEVICE_OBJECT DeviceObject
);
void
SFDeregistryCallouts(
__in PDEVICE_OBJECT DeviceObject
);
NTSTATUS
SFRegisterALEClassifyCallouts(
__in const GUID* layerKey,
__in const GUID* calloutKey,
__in void* DeviceObject,
__out UINT32* calloutId
);
NTSTATUS
SFAddFilter(
__in const wchar_t* filterName,
__in const wchar_t* filterDesc,
__in const GUID* layerKey,
__in const GUID* calloutKey
);
NTSTATUS
SFALEConnectNotify(
__in FWPS_CALLOUT_NOTIFY_TYPE notifyType,
__in const GUID* filterKey,
__in const FWPS_FILTER0* filter
);
NTSTATUS
SFALERecvAcceptNotify(
__in FWPS_CALLOUT_NOTIFY_TYPE notifyType,
__in const GUID* filterKey,
__in const FWPS_FILTER0* filter
);
NTSTATUS
SFALEEstablishedNotify(
__in FWPS_CALLOUT_NOTIFY_TYPE notifyType,
__in const GUID* filterKey,
__in const FWPS_FILTER0* filter
);
void
SFALEConnectClassify(
__in const FWPS_INCOMING_VALUES0* inFixedValues,
__in const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
__inout void* layerData,
__in const FWPS_FILTER0* filter,
__in UINT64 flowContext,
__in FWPS_CLASSIFY_OUT0* classifyOut
);
void
SFALERecvAcceptClassify(
__in const FWPS_INCOMING_VALUES0* inFixedValues,
__in const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
__inout void* layerData,
__in const FWPS_FILTER0* filter,
__in UINT64 flowContext,
__inout FWPS_CLASSIFY_OUT0* classifyOut
);
void
SFALEEstablishedClassify(
__in const FWPS_INCOMING_VALUES0* inFixedValues,
__in const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
__inout void* layerData,
__in const FWPS_FILTER0* filter,
__in UINT64 flowContext,
__inout FWPS_CLASSIFY_OUT0* classifyOut
);
VOID
ThreadStart(
IN PVOID StartContext
);
#endif//__MAIN_H__
上面的是main.h, 下面则是main.c
#include "main.h"
HANDLE gInjectionHandle;
HANDLE gEngineHandle;
UINT32 gAleConnectCalloutIdV4;
UINT32 gAleRecvAcceptCalloutIdV4;
UINT32 gAleEstablishedCalloutIdV4;
LIST_ENTRY gCalloutInfoList;
KSPIN_LOCK gCalloutInfoLock;
KEVENT gWorkerEvent;
NTSTATUS
DriverEntry(
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT DeviceObject = NULL;
NTSTATUS Status;
HANDLE ThreadHandle;
UNICODE_STRING DeviceName;
//
// Initialize the driver object with this driver's entry points.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceDispatch;
DriverObject->DriverUnload = DriverUnload;
//
// Create control device object
//
RtlInitUnicodeString(&DeviceName, L"\\Device\\NetFlow");
Status = IoCreateDevice(DriverObject,
sizeof(HANDLE) + sizeof(LONG),
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceObject);
if (NT_SUCCESS(Status))
{
InitializeListHead(&gCalloutInfoList);
KeInitializeSpinLock(&gCalloutInfoLock);
KeInitializeEvent(&gWorkerEvent, NotificationEvent, FALSE); //KdBreakPoint();
Status = SFRegistryCallouts(DeviceObject);
if (NT_SUCCESS(Status))
{
*(PLONG)((PCH)DeviceObject->DeviceExtension + sizeof(HANDLE)) = FALSE;
Status = PsCreateSystemThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
ThreadStart,
(PVOID)((PCH)DeviceObject->DeviceExtension + sizeof(HANDLE)));
if (!NT_SUCCESS(Status))
{
SFDeregistryCallouts(DeviceObject);
}
else
{
*(PHANDLE)DeviceObject->DeviceExtension = ThreadHandle;
}
}
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
}
}
return Status;
}
VOID
DriverUnload(
__in PDRIVER_OBJECT DriverObject
)
{
KIRQL OldIrql;
PLIST_ENTRY lpEntry;
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
HANDLE ThreadHandle = *(PHANDLE)DeviceObject->DeviceExtension;
PLONG pbUnloading = (PLONG)((PCH)DeviceObject->DeviceExtension + sizeof(HANDLE));
SFDeregistryCallouts(DeviceObject);
InterlockedExchange (pbUnloading, TRUE);
KeSetEvent(&gWorkerEvent, IO_NO_INCREMENT, FALSE);
ZwWaitForSingleObject(ThreadHandle, FALSE, NULL);
ZwClose(ThreadHandle);
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
while (!IsListEmpty(&gCalloutInfoList))
{
lpEntry = RemoveHeadList(&gCalloutInfoList);
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
ExFreePoolWithTag(lpEntry, ' lT ');
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
}
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
IoDeleteDevice(DeviceObject);
}
NTSTATUS
DeviceDispatch(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
switch (irpsp->MajorFunction)
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
Status = STATUS_SUCCESS;
break;
case IRP_MJ_DEVICE_CONTROL:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
SFRegistryCallouts(
__in PDEVICE_OBJECT DeviceObject
)
{
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN EngineOpened = FALSE;
BOOLEAN InTransaction = FALSE;
FWPM_SESSION0 Session = {0};
FWPM_SUBLAYER0 FirewallSubLayer;
Session.flags = FWPM_SESSION_FLAG_DYNAMIC;
Status = FwpmEngineOpen0(NULL,
RPC_C_AUTHN_WINNT,
NULL,
&Session,
&gEngineHandle);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
EngineOpened = TRUE;
Status = FwpmTransactionBegin0(gEngineHandle, 0);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
InTransaction = TRUE;
RtlZeroMemory(&FirewallSubLayer, sizeof(FWPM_SUBLAYER0));
FirewallSubLayer.subLayerKey = SF_SUBLAYER;
FirewallSubLayer.displayData.name = L"Transport SimpleFirewall Sub-Layer";
FirewallSubLayer.displayData.description = L"Sub-Layer for use by Transport SimpleFirewall callouts";
FirewallSubLayer.flags = 0;
FirewallSubLayer.weight = 0;
Status = FwpmSubLayerAdd0(gEngineHandle, &FirewallSubLayer, NULL);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
Status = SFRegisterALEClassifyCallouts(&FWPM_LAYER_ALE_AUTH_CONNECT_V4,
&SF_ALE_CONNECT_CALLOUT_V4,
DeviceObject,
&gAleConnectCalloutIdV4);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
Status = SFRegisterALEClassifyCallouts(&FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4,
&SF_ALE_RECV_ACCEPT_CALLOUT_V4,
DeviceObject,
&gAleRecvAcceptCalloutIdV4);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
Status = SFRegisterALEClassifyCallouts(&FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4,
&SF_ALE_ESTABLISHED_CALLOUT_V4,
DeviceObject,
&gAleEstablishedCalloutIdV4);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
Status = FwpmTransactionCommit0(gEngineHandle);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
InTransaction = FALSE;
Exit:
if (!NT_SUCCESS(Status))
{
if (InTransaction)
{
FwpmTransactionAbort0(gEngineHandle);
}
if (EngineOpened)
{
FwpmEngineClose0(gEngineHandle);
gEngineHandle = NULL;
}
}
return Status;
}
void
SFDeregistryCallouts(
__in PDEVICE_OBJECT DeviceObject
)
{
UNREFERENCED_PARAMETER(DeviceObject);
FwpmEngineClose0(gEngineHandle);
gEngineHandle = NULL;
FwpsCalloutUnregisterById0(gAleConnectCalloutIdV4);
FwpsCalloutUnregisterById0(gAleRecvAcceptCalloutIdV4);
FwpsCalloutUnregisterById0(gAleEstablishedCalloutIdV4);
}
NTSTATUS
SFRegisterALEClassifyCallouts(
__in const GUID* layerKey,
__in const GUID* calloutKey,
__in void* DeviceObject,
__out UINT32* calloutId
)
{
NTSTATUS Status = STATUS_SUCCESS;
FWPS_CALLOUT0 sCallout = {0};
FWPM_CALLOUT0 mCallout = {0};
FWPM_DISPLAY_DATA0 DisplayData = {0};
BOOLEAN calloutRegistered = FALSE;
sCallout.calloutKey = *calloutKey;
if (IsEqualGUID(layerKey, &FWPM_LAYER_ALE_AUTH_CONNECT_V4))
{
sCallout.classifyFn = SFALEConnectClassify;
sCallout.notifyFn = SFALEConnectNotify;
}
else if (IsEqualGUID(layerKey, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4))
{
sCallout.classifyFn = SFALERecvAcceptClassify;
sCallout.notifyFn = SFALERecvAcceptNotify;
}
else
{
sCallout.classifyFn = SFALEEstablishedClassify;
sCallout.notifyFn = SFALEEstablishedNotify;
}
Status = FwpsCalloutRegister0(DeviceObject,
&sCallout,
calloutId);
if (NT_SUCCESS(Status))
{
DisplayData.name = L"Transport SimpleFirewall ALE Classify Callout";
DisplayData.description = L"Intercepts inbound or outbound connect attempts";
mCallout.calloutKey = *calloutKey;
mCallout.displayData = DisplayData;
mCallout.applicableLayer = *layerKey;
Status = FwpmCalloutAdd0(gEngineHandle,
&mCallout,
NULL,
NULL);
if (NT_SUCCESS(Status))
{
//没有Filter(FwpmFilterAdd0), ClassifyFn/NotifyFn就处于未激活状态
Status = SFAddFilter(L"Transport SimpleFirewall ALE Classify",
L"Intercepts inbound or outbound connect attempts",
layerKey,
calloutKey);
}
if (!NT_SUCCESS(Status))
{
FwpsCalloutUnregisterById0(*calloutId);
*calloutId = 0;
}
}
return Status;
}
NTSTATUS
SFAddFilter(
__in const wchar_t* filterName,
__in const wchar_t* filterDesc,
__in const GUID* layerKey,
__in const GUID* calloutKey
)
{
FWPM_FILTER0 Filter = {0};
Filter.layerKey = *layerKey;
Filter.displayData.name = (wchar_t*)filterName;
Filter.displayData.description = (wchar_t*)filterDesc;
Filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
Filter.action.calloutKey = *calloutKey;
Filter.subLayerKey = SF_SUBLAYER;
Filter.weight.type = FWP_EMPTY;
Filter.rawContext = 0;
return FwpmFilterAdd0(gEngineHandle, &Filter, NULL, NULL);
}
NTSTATUS
SFALERecvAcceptNotify(
__in FWPS_CALLOUT_NOTIFY_TYPE notifyType,
__in const GUID* filterKey,
__in const FWPS_FILTER0* filter
)
{
UNREFERENCED_PARAMETER(notifyType);
UNREFERENCED_PARAMETER(filterKey);
UNREFERENCED_PARAMETER(filter);
return STATUS_SUCCESS;
}
NTSTATUS
SFALEConnectNotify(
__in FWPS_CALLOUT_NOTIFY_TYPE notifyType,
__in const GUID* filterKey,
__in const FWPS_FILTER0* filter
)
{
UNREFERENCED_PARAMETER(notifyType);
UNREFERENCED_PARAMETER(filterKey);
UNREFERENCED_PARAMETER(filter);
return STATUS_SUCCESS;
}
NTSTATUS
SFALEEstablishedNotify(
__in FWPS_CALLOUT_NOTIFY_TYPE notifyType,
__in const GUID* filterKey,
__in const FWPS_FILTER0* filter
)
{
UNREFERENCED_PARAMETER(notifyType);
UNREFERENCED_PARAMETER(filterKey);
UNREFERENCED_PARAMETER(filter);
return STATUS_SUCCESS;
}
void
SFALEConnectClassify(
__in const FWPS_INCOMING_VALUES0* inFixedValues,
__in const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
__inout void* layerData,
__in const FWPS_FILTER0* filter,
__in UINT64 flowContext,
__in FWPS_CLASSIFY_OUT0* classifyOut
)
{
NTSTATUS status = STATUS_SUCCESS;
KIRQL OldIrql;
UINT32 index;
ULONG Length;
PCALLOUT_INFO Info;
//classifyOut->actionType = FWP_ACTION_CONTINUE;
classifyOut->actionType = FWP_ACTION_PERMIT;
//
// We don't have the necessary right to alter the classify, exit.
//
if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
return ;
}
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_ID))
{
return ;
}
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_PATH))
{
return ;
}
Length = sizeof(CALLOUT_INFO) + inMetaValues->processPath->size;
Info = ExAllocatePoolWithTag(NonPagedPool, Length, ' lT ' );
if (Info == NULL)
{
return;
}
RtlZeroMemory(Info, Length);
RtlCopyMemory(Info->ProcessPath, inMetaValues->processPath->data, inMetaValues->processPath->size);
Info->Type = OP_CONNECT;
Info->ProcessId = (ULONG)inMetaValues->processId;
index = FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS;
Info->localAddressV4 = RtlUlongByteSwap(inFixedValues->incomingValue[index].value.uint32);
index = FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_PORT;
Info->localPort = inFixedValues->incomingValue[index].value.uint16;
index = FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS;
Info->remoteAddressV4 = RtlUlongByteSwap(inFixedValues->incomingValue[index].value.uint32);
index = FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT;
Info->remotePort = inFixedValues->incomingValue[index].value.uint16;
index = FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_PROTOCOL;
Info->ipProto = inFixedValues->incomingValue[index].value.uint8;
KeQuerySystemTime(&Info->Time);
InitializeListHead(&Info->List);
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
InsertTailList(&gCalloutInfoList, &Info->List);
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
//if ( KeGetCurrentIrql() <= APC_LEVEL )
{
KeSetEvent(&gWorkerEvent, IO_NO_INCREMENT, FALSE);
}
}
void
SFALERecvAcceptClassify(
__in const FWPS_INCOMING_VALUES0* inFixedValues,
__in const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
__inout void* layerData,
__in const FWPS_FILTER0* filter,
__in UINT64 flowContext,
__inout FWPS_CLASSIFY_OUT0* classifyOut
)
{
NTSTATUS status = STATUS_SUCCESS;
KIRQL OldIrql;
UINT32 index;
ULONG Length;
PCALLOUT_INFO Info;
//classifyOut->actionType = FWP_ACTION_CONTINUE;
classifyOut->actionType = FWP_ACTION_PERMIT;
//
// We don't have the necessary right to alter the classify, exit.
//
if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
return ;
}
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_ID))
{
return ;
}
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_PATH))
{
return ;
}
Length = sizeof(CALLOUT_INFO) + inMetaValues->processPath->size;
Info = ExAllocatePoolWithTag(NonPagedPool, Length, ' lT ' );
if (Info == NULL)
{
return;
}
RtlZeroMemory(Info, Length);
RtlCopyMemory(Info->ProcessPath, inMetaValues->processPath->data, inMetaValues->processPath->size);
Info->Type = OP_ACCEPT;
Info->ProcessId = (ULONG)inMetaValues->processId;
index = FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_ADDRESS;
Info->localAddressV4 = RtlUlongByteSwap(inFixedValues->incomingValue[index].value.uint32);
index = FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_PORT;
Info->localPort = inFixedValues->incomingValue[index].value.uint16;
index = FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_ADDRESS;
Info->remoteAddressV4 = RtlUlongByteSwap(inFixedValues->incomingValue[index].value.uint32);
index = FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_REMOTE_PORT;
Info->remotePort = inFixedValues->incomingValue[index].value.uint16;
index = FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_PROTOCOL;
Info->ipProto = inFixedValues->incomingValue[index].value.uint8;
KeQuerySystemTime(&Info->Time);
InitializeListHead(&Info->List);
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
InsertTailList(&gCalloutInfoList, &Info->List);
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
//if ( KeGetCurrentIrql() <= APC_LEVEL )
{
KeSetEvent(&gWorkerEvent, IO_NO_INCREMENT, FALSE);
}
}
void
SFALEEstablishedClassify(
__in const FWPS_INCOMING_VALUES0* inFixedValues,
__in const FWPS_INCOMING_METADATA_VALUES0* inMetaValues,
__inout void* layerData,
__in const FWPS_FILTER0* filter,
__in UINT64 flowContext,
__inout FWPS_CLASSIFY_OUT0* classifyOut
)
{
NTSTATUS status = STATUS_SUCCESS;
KIRQL OldIrql;
UINT32 index;
ULONG Length;
PCALLOUT_INFO Info;
//classifyOut->actionType = FWP_ACTION_CONTINUE;
classifyOut->actionType = FWP_ACTION_PERMIT;
//
// We don't have the necessary right to alter the classify, exit.
//
if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
return ;
}
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_ID))
{
return ;
}
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_PATH))
{
return ;
}
Length = sizeof(CALLOUT_INFO) + inMetaValues->processPath->size;
Info = ExAllocatePoolWithTag(NonPagedPool, Length, ' lT ' );
if (Info == NULL)
{
return;
}
RtlZeroMemory(Info, Length);
RtlCopyMemory(Info->ProcessPath, inMetaValues->processPath->data, inMetaValues->processPath->size);
Info->Type = OP_ESTABLISHED;
Info->ProcessId = (ULONG)inMetaValues->processId;
index = FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_ADDRESS;
Info->localAddressV4 = RtlUlongByteSwap(inFixedValues->incomingValue[index].value.uint32);
index = FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_PORT;
Info->localPort = inFixedValues->incomingValue[index].value.uint16;
index = FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_ADDRESS;
Info->remoteAddressV4 = RtlUlongByteSwap(inFixedValues->incomingValue[index].value.uint32);
index = FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_PORT;
Info->remotePort = inFixedValues->incomingValue[index].value.uint16;
index = FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL;
Info->ipProto = inFixedValues->incomingValue[index].value.uint8;
KeQuerySystemTime(&Info->Time);
InitializeListHead(&Info->List);
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
InsertTailList(&gCalloutInfoList, &Info->List);
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
//if ( KeGetCurrentIrql() <= APC_LEVEL )
{
KeSetEvent(&gWorkerEvent, IO_NO_INCREMENT, FALSE);
}
}
VOID
HandleCalloutInfo(
IN PVOID Context
)
{
PCWSTR OpType[4] = {L"N/A", L"Connect", L"Accept", L"Established"};
PCALLOUT_INFO Info = Context;
WCHAR szlocalAddressV4[24] = {0};
WCHAR szremoteAddressV4[24]= {0};
RtlIpv4AddressToStringW((PIN_ADDR)&Info->localAddressV4, szlocalAddressV4);
RtlIpv4AddressToStringW((PIN_ADDR)&Info->remoteAddressV4, szremoteAddressV4);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[@] %ws(%d) <-%d-> %ws(%d), %ws : %d, %ws\r\n",
szlocalAddressV4,
Info->localPort,
Info->ipProto,
szremoteAddressV4,
Info->remotePort,
OpType[Info->Type],
Info->ProcessId,
Info->ProcessPath);
}
VOID
ThreadStart(
IN PVOID StartContext
)
{
PLONG pbUnloading = StartContext;
LARGE_INTEGER Interval = {(ULONG)(-5 * 1000 * 1000 * 10), -1};
KIRQL OldIrql;
PLIST_ENTRY lpEntry;
while (TRUE)
{
KeWaitForSingleObject(&gWorkerEvent, Executive, KernelMode, FALSE, &Interval);
if (InterlockedCompareExchange(pbUnloading, TRUE, TRUE))
{
break;
}
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
while (!IsListEmpty(&gCalloutInfoList))
{
lpEntry = RemoveHeadList(&gCalloutInfoList);
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
HandleCalloutInfo(lpEntry);
ExFreePoolWithTag(lpEntry, ' lT ');
KeAcquireSpinLock(&gCalloutInfoLock, &OldIrql);
}
KeReleaseSpinLock (&gCalloutInfoLock, OldIrql);
}
}
最近就是sources文件了,没有它编译就有问题了了^_^
TARGETNAME=netflow
TARGETTYPE=DRIVER
TARGETPATH=..
INCLUDES=\
$(DDK_INC_PATH);
TARGETLIBS=\
$(DDK_LIB_PATH)\ntoskrnl.lib \
$(DDK_LIB_PATH)\ndis.lib \
$(DDK_LIB_PATH)\fwpkclnt.lib \
$(SDK_LIB_PATH)\uuid.lib
C_DEFINES=$(C_DEFINES) -DBINARY_COMPATIBLE=0 -DNT -DUNICODE -D_UNICODE -DNDIS60 -DNDIS_SUPPORT_NDIS6
SOURCES = main.c