最近闲来无事,翻看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