⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfilter.c

📁 网程络过滤驱动,可以截获网络封包!对其进行分析拦截!
💻 C
📖 第 1 页 / 共 5 页
字号:
	FastIoDispatch->MdlRead = SfFastIoMdlRead;
	FastIoDispatch->MdlReadComplete = SfFastIoMdlReadComplete;
	FastIoDispatch->PrepareMdlWrite = SfFastIoPrepareMdlWrite;
	FastIoDispatch->MdlWriteComplete = SfFastIoMdlWriteComplete;
	FastIoDispatch->FastIoReadCompressed = SfFastIoReadCompressed;
	FastIoDispatch->FastIoWriteCompressed = SfFastIoWriteCompressed;
	FastIoDispatch->MdlReadCompleteCompressed = SfFastIoMdlReadCompleteCompressed;
	FastIoDispatch->MdlWriteCompleteCompressed = SfFastIoMdlWriteCompleteCompressed;
	FastIoDispatch->FastIoQueryOpen = SfFastIoQueryOpen;

	DriverObject->FastIoDispatch = FastIoDispatch;

// 
// VERSION NOTE:
// 
// There are 6 FastIO routines for which file system filters are bypassed as
// the requests are passed directly to the base file system.  These 6 routines
// are AcquireFileForNtCreateSection, ReleaseFileForNtCreateSection,
// AcquireForModWrite, ReleaseForModWrite, AcquireForCcFlush, and 
// ReleaseForCcFlush.
// 
// In Windows XP and later, the FsFilter callbacks were introduced to allow
// filters to safely hook these operations.  See the IFS Kit documentation for
// more details on how these new interfaces work.
// 
// MULTIVERSION NOTE:
// 
// If built for Windows XP or later, this driver is built to run on 
// multiple versions.  When this is the case, we will test
// for the presence of FsFilter callbacks registration API.  If we have it,
// then we will register for those callbacks, otherwise, we will not.
// 

#if WINVER >= 0x0501

	{
		FS_FILTER_CALLBACKS FsFilterCallbacks;

		if (NULL != gSfDynamicFunctions.RegisterFileSystemFilterCallbacks)
		{
			// 
			// Setup the callbacks for the operations we receive through
			// the FsFilter interface.
			// 
			// NOTE:  You only need to register for those routines you really need
			//		to handle.  SFilter is registering for all routines simply to
			//		give an example of how it is done.
			// 
			FsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS);
			FsFilterCallbacks.PreAcquireForSectionSynchronization = SfPreFsFilterPassThrough;
			FsFilterCallbacks.PostAcquireForSectionSynchronization = SfPostFsFilterPassThrough;
			FsFilterCallbacks.PreReleaseForSectionSynchronization = SfPreFsFilterPassThrough;
			FsFilterCallbacks.PostReleaseForSectionSynchronization = SfPostFsFilterPassThrough;
			FsFilterCallbacks.PreAcquireForCcFlush = SfPreFsFilterPassThrough;
			FsFilterCallbacks.PostAcquireForCcFlush = SfPostFsFilterPassThrough;
			FsFilterCallbacks.PreReleaseForCcFlush = SfPreFsFilterPassThrough;
			FsFilterCallbacks.PostReleaseForCcFlush = SfPostFsFilterPassThrough;
			FsFilterCallbacks.PreAcquireForModifiedPageWriter = SfPreFsFilterPassThrough;
			FsFilterCallbacks.PostAcquireForModifiedPageWriter = SfPostFsFilterPassThrough;
			FsFilterCallbacks.PreReleaseForModifiedPageWriter = SfPreFsFilterPassThrough;
			FsFilterCallbacks.PostReleaseForModifiedPageWriter = SfPostFsFilterPassThrough;

			Status = (gSfDynamicFunctions.RegisterFileSystemFilterCallbacks)(DriverObject, &FsFilterCallbacks);
			if (!NT_SUCCESS(Status))
			{
				DriverObject->FastIoDispatch = NULL;
				ExFreePool(FastIoDispatch);
				IoDeleteDevice(gSFilterControlDeviceObject);
				ZwClose(&gRuleFileHandle);
				ExDeleteResourceLite(&gRulesResource);
				return Status;
			}
		}
	}
#endif

	// 
	// The registered callback routine "SfFsNotification" will be called
	// whenever a new file systems is loaded or when any file system is
	// unloaded.
	// 
	// VERSION NOTE:
	// 
	// On Windows XP and later this will also enumerate all existing file
	// systems (except the RAW file systems).  On Windows 2000 this does not
	// enumerate the file systems that were loaded before this filter was
	// loaded.
	// 
	Status = IoRegisterFsRegistrationChange(DriverObject, SfFsNotification);
	if (!NT_SUCCESS(Status))
	{
		KdPrint(("SFilter!DriverEntry: Error registering FS change notification, Status=%08x\n", Status));

		DriverObject->FastIoDispatch = NULL;
		ExFreePool(FastIoDispatch);
		IoDeleteDevice(gSFilterControlDeviceObject);
		ZwClose(&gRuleFileHandle);
		ExDeleteResourceLite(&gRulesResource);
		return Status;
	}

	// 
	// Attempt to attach to the appropriate RAW file system device objects
	// since they are not enumerated by IoRegisterFsRegistrationChange.
	// 
	{
		PDEVICE_OBJECT RawDeviceObject;
		PFILE_OBJECT FileObject;

		// 
		// Attach to RawDisk device
		// 
		RtlInitUnicodeString(&NameString, L"\\Device\\RawDisk");
		Status = IoGetDeviceObjectPointer(
			&NameString,
			FILE_READ_ATTRIBUTES,
			&FileObject,
			&RawDeviceObject
			);
		if (NT_SUCCESS(Status))
		{
			SfFsNotification(RawDeviceObject, TRUE);
			ObDereferenceObject(FileObject);
		}

		// 
		// Attach to the RawCdRom device
		// 
		RtlInitUnicodeString(&NameString, L"\\Device\\RawCdRom");
		Status = IoGetDeviceObjectPointer(
			&NameString,
			FILE_READ_ATTRIBUTES,
			&FileObject,
			&RawDeviceObject
			);
		if (NT_SUCCESS(Status))
		{
			SfFsNotification(RawDeviceObject, TRUE);
			ObDereferenceObject(FileObject);
		}
	}

	// 
	// Clear the initializing flag on the control device object since we
	// have now successfully initialized everything.
	// 
	ClearFlag(gSFilterControlDeviceObject->Flags, DO_DEVICE_INITIALIZING);

	return STATUS_SUCCESS;
}

#if DBG && WINVER >= 0x0501
VOID
DriverUnload(
	IN PDRIVER_OBJECT DriverObject
	)
/*++

Routine Description:

	This routine is called when a driver can be unloaded.  This performs all of
	the necessary cleanup for unloading the driver from memory.  Note that an
	error can NOT be returned from this routine.
	
	When a request is made to unload a driver the IO System will cache that
	information and not actually call this routine until the following states
	have occurred:
	- All device objects which belong to this filter are at the top of their
	  respective attachment chains.
	- All handle counts for all device objects which belong to this filter have
	  gone to zero.

	WARNING: Microsoft does not officially support the unloading of File
			 System Filter Drivers.  This is an example of how to unload
			 your driver if you would like to use it during development.
			 This should not be made available in production code.

Arguments:

	DriverObject - Driver object for this module

Return Value:

	None.

--*/
{
	PSFILTER_DEVICE_EXTENSION DevExt;
	PFAST_IO_DISPATCH FastIoDispatch;
	NTSTATUS Status;
	ULONG NumDevices;
	ULONG i;
	LARGE_INTEGER Interval;
#	define DEVOBJ_LIST_SIZE 64
	PDEVICE_OBJECT DevList[DEVOBJ_LIST_SIZE];

	ASSERT(DriverObject == gSFilterDriverObject);

	// 
	// Log we are unloading
	// 
	SF_LOG_PRINT(SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
				  ("SFilter!DriverUnload:						Unloading driver (%p)\n",
					DriverObject));

	// 
	// Don't get anymore file system change notifications
	// 
	IoUnregisterFsRegistrationChange(DriverObject, SfFsNotification);

	// 
	// This is the loop that will go through all of the devices we are attached
	// to and detach from them.  Since we don't know how many there are and
	// we don't want to allocate memory (because we can't return an error)
	// we will free them in chunks using a local array on the stack.
	// 
	for (;;)
	{
		// 
		// Get what device objects we can for this driver.  Quit if there
		// are not any more.  Note that this routine should always be
		// defined since this routine is only compiled for Windows XP and
		// later.
		// 

		ASSERT(NULL != gSfDynamicFunctions.EnumerateDeviceObjectList);
		Status = (gSfDynamicFunctions.EnumerateDeviceObjectList)(
			DriverObject,
			DevList,
			sizeof(DevList),
			&NumDevices
			);

		if (NumDevices <= 0)
			break;

		NumDevices = min(NumDevices, DEVOBJ_LIST_SIZE);

		// 
		// First go through the list and detach each of the devices.
		// Our control device object does not have a DeviceExtension and
		// is not attached to anything so don't detach it.
		// 
		for (i=0; i < NumDevices; i++)
		{
			DevExt = DevList[i]->DeviceExtension;
			if (NULL != DevExt)
				IoDetachDevice(DevExt->AttachedToDeviceObject);
		}

		// 
		// The IO Manager does not currently add a reference count to a device
		// object for each outstanding IRP.  This means there is no way to
		// know if there are any outstanding IRPs on the given device.
		// We are going to wait for a reasonable amount of time for pending
		// irps to complete.  
		// 
		// WARNING: This does not work 100% of the time and the driver may be
		//		 unloaded before all IRPs are completed.  This can easily
		//		 occur under stress situations and if a long lived IRP is
		//		 pending (like oplocks and directory change notifications).
		//		 The system will fault when this Irp actually completes.
		//		 This is a sample of how to do this during testing.  This
		//		 is not recommended for production code.
		// 
		Interval.QuadPart = (5 * DELAY_ONE_SECOND);	  // delay 5 seconds
		KeDelayExecutionThread(KernelMode, FALSE, &Interval);

		// 
		// Now go back through the list and delete the device objects.
		// 
		for (i=0; i < NumDevices; i++)
		{
			// 
			// See if this is our control device object.  If not then cleanup
			// the device extension.  If so then clear the global pointer
			// that references it.
			// 
			if (NULL != DevList[i]->DeviceExtension)
				SfCleanupMountedDevice(DevList[i]);
			else
			{
				ASSERT(DevList[i] == gSFilterControlDeviceObject);
				gSFilterControlDeviceObject = NULL;
			}

			// 
			// Delete the device object, remove reference counts added by
			// IoEnumerateDeviceObjectList.  Note that the delete does
			// not actually occur until the reference count goes to zero.
			// 
			IoDeleteDevice(DevList[i]);
			ObDereferenceObject(DevList[i]);
		}
	}

	// 
	// Free our FastIO table
	// 
	FastIoDispatch = DriverObject->FastIoDispatch;
	DriverObject->FastIoDispatch = NULL;
	ExFreePool(FastIoDispatch);

	ExDeletePagedLookasideList(&gFsCtxLookAsideList);
	ExDeletePagedLookasideList(&gFileNameLookAsideList);
	ExDeleteNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList);

	ZwClose(gRuleFileHandle);
	ExDeleteResourceLite(&gRulesResource);
	if (gRules)
		ExFreePoolWithTag(gRules, SFLT_POOL_TAG);
}
#endif

#if WINVER >= 0x0501
VOID
SfLoadDynamicFunctions (
	)
/*++

Routine Description:

	This routine tries to load the function pointers for the routines that
	are not supported on all versions of the OS.  These function pointers are
	then stored in the global structure SpyDynamicFunctions.

	This support allows for one driver to be built that will run on all 
	versions of the OS Windows 2000 and greater.  Note that on Windows 2000, 
	the functionality may be limited.
	
Arguments:

	None.
	
Return Value:

	None.

--*/
{
	UNICODE_STRING FunctionName;

	RtlZeroMemory(&gSfDynamicFunctions, sizeof(gSfDynamicFunctions));

	// 
	// For each routine that we would want to use, lookup its address in the
	// kernel or hal.  If it is not present, that field in our global
	// SpyDynamicFunctions structure will be set to NULL.
	// 

	RtlInitUnicodeString(&FunctionName, L"FsRtlRegisterFileSystemFilterCallbacks");
	gSfDynamicFunctions.RegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoAttachDeviceToDeviceStackSafe");
	gSfDynamicFunctions.AttachDeviceToDeviceStackSafe = MmGetSystemRoutineAddress(&FunctionName);
	
	RtlInitUnicodeString(&FunctionName, L"IoEnumerateDeviceObjectList");
	gSfDynamicFunctions.EnumerateDeviceObjectList = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetLowerDeviceObject");
	gSfDynamicFunctions.GetLowerDeviceObject = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetDeviceAttachmentBaseRef");
	gSfDynamicFunctions.GetDeviceAttachmentBaseRef = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetDiskDeviceObject");
	gSfDynamicFunctions.GetDiskDeviceObject = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetAttachedDeviceReference");
	gSfDynamicFunctions.GetAttachedDeviceReference = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"RtlGetVersion");
	gSfDynamicFunctions.GetVersion = MmGetSystemRoutineAddress(&FunctionName);
}

VOID
SfGetCurrentVersion (
	)
/*++

Routine Description:

	This routine reads the current OS version using the correct routine based
	on what routine is available.

Arguments:

	None.
	
Return Value:

	None.

--*/
{
	if (NULL != gSfDynamicFunctions.GetVersion)
	{
		RTL_OSVERSIONINFOW VersionInfo;
		NTSTATUS Status;

		// 
		// VERSION NOTE: RtlGetVersion does a bit more than we need, but
		// we are using it if it is available to show how to use it.  It
		// is available on Windows XP and later.  RtlGetVersion and
		// RtlVerifyVersionInfo (both documented in the IFS Kit docs) allow
		// you to make correct choices when you need to change logic based
		// on the current OS executing your code.
		// 
		VersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);

		Status = (gSfDynamicFunctions.GetVersion)(&VersionInfo);

		ASSERT(NT_SUCCESS(Status));

		gSfOsMajorVersion = VersionInfo.dwMajorVersion;
		gSfOsMinorVersion = VersionInfo.dwMinorVersion;
		
	}
	else
	{
		PsGetVersion(&gSfOsMajorVersion,
			&gSfOsMinorVersion,
			NULL,
			NULL
			);
	}
}
#endif

VOID
SfFsNotification(
	IN PDEVICE_OBJECT DeviceObject,
	IN BOOLEAN FsActive
	)
/*++

Routine Description:

	This routine is invoked whenever a file system has either registered or
	unregistered itself as an active file system.

	For the former case, this routine creates a device object and attaches it
	to the specified file system's device object.  This allows this driver
	to filter all requests to that file system.  Specifically we are looking
	for MOUNT requests so we can attach to newly mounted volumes.

	For the latter case, this file system's device object is located,
	detached, and deleted.  This removes this file system as a filter for
	the specified file system.

Arguments:

	DeviceObject - Pointer to the file system's device object.

	FsActive - Boolean indicating whether the file system has registered
		(TRUE) or unregistered (FALSE) itself as an active file system.

Return Value:

	None.

--*/
{
	UNICODE_STRING Name;
	WCHAR NameBuffer[MAX_DEVNAME_LENGTH];

	PAGED_CODE();

	// 
	// Init local Name buffer
	// 
	RtlInitEmptyUnicodeString(&Name, NameBuffer, sizeof(NameBuffer));

	SfGetObjectName(DeviceObject, &Name);

	// 
	// Display the names of all the file system we are notified of
	// 
	SF_LOG_PRINT(SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
		("SFilter!SfFsNotification:					%s	%p \"%wZ\" (%s)\n",
		(FsActive) ? "Activating file system  " : "Deactivating file system",
		DeviceObject,
		&Name,
		GET_DEVICE_TYPE_NAME(DeviceObject->DeviceType))
		);

	// 
	// Handle attaching/detaching from the given file system.
	// 
	if (FsActive)
		SfAttachToFileSystemDevice(DeviceObject, &Name);
	else
		SfDetachFromFileSystemDevice(DeviceObject);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -