Minifilter

Minifilter特点

在Minifilter框架中,不在需要自己去写代码生成设备,去绑定卷.这些框架已经做好了.唯一需要我们做的就是在Callback中处理我们感兴趣的回调函数而已.

创建文件
使用FltCreateFile 不能再使用ZwCreateFile

通信方式
在minifilter中改为通过端口通信.

驱动加载
使用inf文件安装 然后使用命令net start +驱动名
或者使用代码的方式加载,与NT驱动不同的是,需要新增两个注册表键值.

Minifilter的注册

CONST FLT_REGISTRATION FilterRegistration = {

sizeof( FLT_REGISTRATION ),         //  Size
FLT_REGISTRATION_VERSION,           //  Version
0,                                  //  Flags

NULL,                               //  上下文相关回调(数组)
Callbacks,                          // 所有IRP的操作都在这个数组里,需要关心的就是这里面的Irp处理回调

MiniUnload,                           //  MiniFilterUnload

MiniInstanceSetup,                    //  每一个卷设备都会生成一个Instance 把Instance绑定到卷设备上
									  //可以从该回调函数获得卷设备的名称,扇区大小 文件系统类别
MiniInstanceQueryTeardown,            //  InstanceQueryTeardown
MiniInstanceTeardownStart,            //  Instance和卷设备分离的时候会调用该回调
MiniInstanceTeardownComplete,         //  InstanceTeardownComplete

NULL,                               //  以下三个回调是关于名字处理的
NULL,                               //  GenerateDestinationFileName
NULL                                //  NormalizeNameComponent

};

回调函数中的数据
IRP数据结构在Minifilter中已经看不到了.框架使用的是CALLBACK_DATA的这样一种数据结构.


typedef struct _FLT_CALLBACK_DATA {

    FLT_CALLBACK_DATA_FLAGS Flags;
    PETHREAD CONST Thread;
    PFLT_IO_PARAMETER_BLOCK CONST Iopb;
    IO_STATUS_BLOCK IoStatus;


    struct _FLT_TAG_DATA_BUFFER *TagData;

    union {
        struct {

     
            LIST_ENTRY QueueLinks;

            PVOID QueueContext[2];
        };
        PVOID FilterContext[4];
    };

    KPROCESSOR_MODE RequestorMode;

} FLT_CALLBACK_DATA, *PFLT_CALLBACK_DATA;

IRP相关信息在结构FLT_IO_PARAMETER_BLOCK里面

typedef struct _FLT_IO_PARAMETER_BLOCK {


    //
    //  Fields from IRP
    //  Flags

    ULONG IrpFlags;

    //
    //  Major/minor functions from IRP
    //

    UCHAR MajorFunction;
    UCHAR MinorFunction;

    //
    //  The flags associated with operations.
    //  The IO_STACK_LOCATION.Flags field in the old model (SL_* flags)
    //

    UCHAR OperationFlags;

    //
    //  For alignment
    //

    UCHAR Reserved;


    //
    //  The FileObject that is the target for this
    //  IO operation.
    //

    PFILE_OBJECT TargetFileObject;

    //
    //  Instance that i/o is directed to
    //

    PFLT_INSTANCE TargetInstance;

    //
    //  Normalized parameters for the operation
    //

    FLT_PARAMETERS Parameters; //写入位置 写入长度 缓冲区等相关参数

} FLT_IO_PARAMETER_BLOCK, *PFLT_IO_PARAMETER_BLOCK;

Altitude值:20000-429999
在这里插入图片描述

IRP_PAGING_IO

IRP_PAGING_IO是由系统发起的,自己不需要监控.设置FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO标志.
例如:

{ IRP_MJ_CREATE,
      FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
      MiniPreOperation,
      MiniPostOperation }

在这里插入图片描述

预操作的返回值

typedef enum _FLT_PREOP_CALLBACK_STATUS {

    FLT_PREOP_SUCCESS_WITH_CALLBACK, //调用POST操作(相当于完成函数)	
    FLT_PREOP_SUCCESS_NO_CALLBACK,	 //不会调用POST操作
    FLT_PREOP_PENDING,
    FLT_PREOP_DISALLOW_FASTIO,	     //禁用FAST_IO
    FLT_PREOP_COMPLETE,				 //完成DATA,不会再往下传递.
    FLT_PREOP_SYNCHRONIZE			 //POST操作的IRQL等级小于DPC


} FLT_PREOP_CALLBACK_STATUS, *PFLT_PREOP_CALLBACK_STATUS;

POST操作的IRQL

一般情况下是DPC,相等于是完成函数
如果拦截的是IRP_MJ_CREATE IRQL=PASSIVE_LEVEL
如果是基于FASTIO的, IRQL=PASSIVE_LEVEL
如果预处理操作的返回值是FLT_PREOP_SYNCHRONIZE POST操作的IRQL<DPC

POST操作的返回值


typedef enum _FLT_POSTOP_CALLBACK_STATUS {

    FLT_POSTOP_FINISHED_PROCESSING,
    FLT_POSTOP_MORE_PROCESSING_REQUIRED

} FLT_POSTOP_CALLBACK_STATUS, *PFLT_POSTOP_CALLBACK_STATUS;

判断Data是什么操作的宏

#define FLT_IS_IRP_OPERATION(Data)          (FlagOn( (Data)->Flags, FLTFL_CALLBACK_DATA_IRP_OPERATION ))
#define FLT_IS_FASTIO_OPERATION(Data)       (FlagOn( (Data)->Flags, FLTFL_CALLBACK_DATA_FAST_IO_OPERATION ))
#define FLT_IS_FS_FILTER_OPERATION(Data)    (FlagOn( (Data)->Flags, FLTFL_CALLBACK_DATA_FS_FILTER_OPERATION ))

DATA中参数的获取

IRP 中的buffer和length 都变得在data中获取
在这里插入图片描述

获取创建文件全路径

在这里插入图片描述

FLT_PREOP_CALLBACK_STATUS
MyPreCreate(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID *CompletionContext
)
{
	//需要调用POST
	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

FLT_POSTOP_CALLBACK_STATUS
MyPostCreate(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
{
	NTSTATUS status = STATUS_SUCCESS;
	PFLT_FILE_NAME_INFORMATION pNameInfo = NULL;
	status = FltGetFileNameInformation(Data, 
									  FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
										&pNameInfo);
	if(!NT_SUCCESS(status))
	{
		KdPrint(("获取文件信息失败,status=%x\n",status)); //文件信息有获取失败的时候 
		return status;
	}
	status=FltParseFileNameInformation(pNameInfo);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("解析文件信息失败\n"));
		FltReleaseFileNameInformation(pNameInfo); 
		return status;
	}
	KdPrint(("卷名:%wZ\n", &pNameInfo->Volume));
	KdPrint(("文件名:%wZ\n", &pNameInfo->Name));
	FltReleaseFileNameInformation(pNameInfo);
	return FLT_POSTOP_FINISHED_PROCESSING;
}

在这里插入图片描述

拦截进程创建

在这里插入图片描述

Minifilter中的文件操作

在这里插入图片描述

Minifilter上下文

在这里插入图片描述

创建 删除 重命名的判断

FLT_PREOP_CALLBACK_STATUS
NPPreCreate (
			 __inout PFLT_CALLBACK_DATA Data,
			 __in PCFLT_RELATED_OBJECTS FltObjects,
			 __deref_out_opt PVOID *CompletionContext
			 )
{

	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameInfo;

	UNREFERENCED_PARAMETER( FltObjects );
	UNREFERENCED_PARAMETER( CompletionContext );

	PAGED_CODE();        
	if (gCommand == ENUM_PASS)
	{
		return FLT_PREOP_SUCCESS_WITH_CALLBACK;
	}
	else if (gCommand == ENUM_BLOCK && gPath[0] != 0)
	{
		__try 
		{
			status = FltGetFileNameInformation( Data,
				FLT_FILE_NAME_NORMALIZED |
				FLT_FILE_NAME_QUERY_DEFAULT,
				&nameInfo );


			if (NT_SUCCESS( status ))
			{
				char fileName[500] = "";
				FltParseFileNameInformation(nameInfo);
				if (NPUnicodeStringToChar(&nameInfo->Name, fileName))
				{
					if (strstr(fileName, gPath))
					{

						//IRP_MJ_CREATE
						if (Data->Iopb->MajorFunction == IRP_MJ_CREATE)
						{
							//create file
							if (   ((Data->Iopb->Parameters.Create.Options>>24) & 0x000000ff) == FILE_CREATE || 
								((Data->Iopb->Parameters.Create.Options>>24) & 0x000000ff) == FILE_OPEN_IF||
								((Data->Iopb->Parameters.Create.Options>>24) & 0x000000ff) == FILE_OVERWRITE_IF)
							{

								Data->IoStatus.Status = STATUS_ACCESS_DENIED;
								Data->IoStatus.Information = 0;
								FltReleaseFileNameInformation( nameInfo );
								return FLT_PREOP_COMPLETE;
							}
							//move into folder
							if (Data->Iopb->OperationFlags == '\x05')
							{
								Data->IoStatus.Status = STATUS_ACCESS_DENIED;
								Data->IoStatus.Information = 0;
								FltReleaseFileNameInformation( nameInfo );
								return FLT_PREOP_COMPLETE;
							}
						}
						//IRP_MJ_WRITE
						if (Data->Iopb->MajorFunction == IRP_MJ_WRITE)
						{
							Data->IoStatus.Status = STATUS_ACCESS_DENIED;
							Data->IoStatus.Information = 0;
							FltReleaseFileNameInformation( nameInfo );
							return FLT_PREOP_COMPLETE;
						}

						//IRP_MJ_SET_INFORMATION
						if (Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION)	
						{
							//delete file
							if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileDispositionInformation)
							{
								DbgPrint("delete file\n");
								Data->IoStatus.Status = STATUS_ACCESS_DENIED;
								Data->IoStatus.Information = 0;
								FltReleaseFileNameInformation( nameInfo );
								return FLT_PREOP_COMPLETE;
							}

							//rename file
							if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformation)		
							{
								DbgPrint("rename file\n");
								Data->IoStatus.Status = STATUS_ACCESS_DENIED;
								Data->IoStatus.Information = 0;
								FltReleaseFileNameInformation( nameInfo );
								return FLT_PREOP_COMPLETE;
							}
						}
					}

				}  
				FltReleaseFileNameInformation( nameInfo );

			}
		}
		__except( EXCEPTION_EXECUTE_HANDLER ) 
		{

			return FLT_PREOP_SUCCESS_WITH_CALLBACK;
		}

	}
		
	
	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
	

文件的重定向

FLT_PREOP_CALLBACK_STATUS
MyMinifiterPreOperation (
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
    )
{
    NTSTATUS status;
    PFLT_FILE_NAME_INFORMATION nameInfo;
 
    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext);
 
    UNICODE_STRING desFilename;
    RtlCreateUnicodeString(&desFilename, L"\\DEVICE\\HARDDISKVOLUME3\\USERS\\User\\DESKTOP\\2.TXT");//为了方便测试路径我写死了,实际操作也很简单仅仅只是字符串的拼接
    PFILE_OBJECT FileObject;
    PAGED_CODE();
    __try {
 
        status = FltGetFileNameInformation(Data,
            FLT_FILE_NAME_NORMALIZED |
            FLT_FILE_NAME_QUERY_DEFAULT,
            &nameInfo);
        if (NT_SUCCESS(status)) {
            FltParseFileNameInformation(nameInfo);
            if (wcsstr(nameInfo->Name.Buffer, L"1.txt")) {
                FileObject = Data->Iopb->TargetFileObject;
                FileObject->FileName = desFilename;//替换成目标文件的路径。
                Data->IoStatus.Information = IO_REPARSE;
                Data->IoStatus.Status = STATUS_REPARSE;
                Data->Iopb->TargetFileObject->RelatedFileObject = NULL;
                FltSetCallbackDataDirty(Data)FltReleaseFileNameInformation(nameInfo);
                return FLT_PREOP_COMPLETE;
            }
            //release resource
            FltReleaseFileNameInformation(nameInfo);
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        DbgPrint("EXCEPTION_EXECUTE_HANDLER\n");
    }
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Minifilter是Windows操作系统中的一个内核模块,它可以对文件系统I/O操作进行监控和过滤,提供一定程度的文件系统访问控制和文件操作的修改能力。minifilter可以在文件系统级别实现对文件的读写访问控制、文件内容加密、文件过滤等功能。 minifilter的下载通常分为两个步骤:首先需要下载Windows Driver Kit(WDK)或Windows SDK,以获取minifilter开发所需的工具和库文件;其次,可以根据自己的具体需求编写或下载现有的minifilter源代码。 WDK或Windows SDK是微软提供的一套开发工具,它包含了开发Windows驱动程序所需的一系列工具、示例代码、库文件和文档等,可以用于minifilter开发及其他相关驱动程序的开发。 一般来说,在微软官网上可以找到WDK或Windows SDK的下载链接,用户可以根据自己的操作系统版本和开发环境选择合适的版本进行下载安装。安装完成后,用户可以在Windows开发环境中配置相应的环境变量,然后就可以使用WDK或Windows SDK提供的工具和库文件进行minifilter开发。 另外,也可以通过搜索引擎或开源社区等途径,找到已经编写好的minifilter源代码,并根据需要进行下载和修改。这种方式适用于一些常见的minifilter功能,如文件加密、病毒扫描等,可以节省开发时间和工作量。 总之,minifilter的下载需要获取Windows Driver Kit或Windows SDK,然后可以通过官方渠道或开源社区获取minifilter的源代码,以进行开发和定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值