minifilter


  暑假剛開始的時候,參照《寒江獨釣》這本書,用VS2015寫過的一個minifilter的框架,今天在博客上分享出來。

  VS2015已經有了minifilter的框架模板,直接生成了minifilter的基本結構,使用非常方便:

  

 

  另外需要一提的是,直接生成的inf文件中,需要把inf文件中的 Instance1.Altitude = "370030"  注釋去掉——否則的話驅動起不了作用,就這一點可是參悟了幾天吶~

  好了,進入正題。

 

0x01  minifilter簡單認識

 

1.需求:要求得到文件操作消息。

 

2.傳統的文件過濾驅動(過濾管理器)提供接口,來接受注冊過的內核模塊

 

3.優點:

1.minifilter不再參與IRP的處理工作,而是交由過濾管理器處理

2.過濾管理器統一管理,提高軟件兼容性

缺點:

只通過接口編程的話,一些數據結構的域無法訪問,部分功能難以實現

 

4.注冊微過濾器,就是向微過濾器注冊它的回調函數,不必再花精力綁定各種設備

 

 

0x02  關鍵代碼

 

一。向過濾管理器注冊微過濾器

NTSTATUS
DriverEntry (
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS Status;
	UNICODE_STRING  MiniFilterPortName;
	PSECURITY_DESCRIPTOR SecurityDescriptor;
	OBJECT_ATTRIBUTES    ObjectAttributes;
    UNREFERENCED_PARAMETER( RegistryPath );  //不用該參數


	//向過濾管理器注冊微過濾器
    Status = FltRegisterFilter( DriverObject,        //DriverEntry參數DriverObject
                                &FilterRegistration, //微過濾器注冊結構
                                &__FilterHandle);    //微過濾器句柄,全局保存

 
    if (NT_SUCCESS(Status)) 
	{
		//開啟過濾
        Status = FltStartFiltering(__FilterHandle);

        if (!NT_SUCCESS(Status)) 
		{
		    //開啟失敗注銷微過濾器
			goto Exit;
        }
    }
	else
	{
		goto Exit;
	}
	Status = FltBuildDefaultSecurityDescriptor(&SecurityDescriptor, FLT_PORT_ALL_ACCESS);

	if (!NT_SUCCESS(Status)) 
	{
		goto Exit;
	}

	RtlInitUnicodeString(&MiniFilterPortName, MINI_FILTER_PORT_NAME);
	//初始化ObjectAttributes,包含端口名MiniFilterPortName,方便Ring3應用層使用
	InitializeObjectAttributes(&ObjectAttributes,
		&MiniFilterPortName,
		OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,  //OBJ_KERNEL_HANDLE 必需???
		NULL,
		SecurityDescriptor);
	//創建通信端口
	Status = FltCreateCommunicationPort(__FilterHandle,
		&__FilterServerPort,   //監聽連接請求的端口
		&ObjectAttributes,     //
		NULL,
		MiniFilterConnect,     //用戶態連接后的回調函數
		MiniFilterDisconnect,
		MiniFilterDeviceIoControl,  //MessageNotifyCallback   接受消息的回調函數
		1);

	FltFreeSecurityDescriptor(SecurityDescriptor);

	if (!NT_SUCCESS(Status)) {
		goto Exit;
	}

Exit :
	if (!NT_SUCCESS(Status)) {

		if (NULL != __FilterServerPort) {
			FltCloseCommunicationPort(__FilterServerPort);
		}

		if (NULL != __FilterHandle) {
			FltUnregisterFilter(__FilterHandle);
		}
	}
    return Status;
}


//注冊微過濾器時的結構填充:

//微過濾器注冊結構
CONST FLT_REGISTRATION FilterRegistration = {

    sizeof( FLT_REGISTRATION ),         //  Size    大小
    FLT_REGISTRATION_VERSION,           //  Version 版本
    0,                                  //  Flags   標志位傳0

    NULL,                               //  Context
    Callbacks,    //回調函數數組        //  Operation callbacks  操作回調函數集注冊,最重點!!!

    MiniFilterUnload,                           //  MiniFilterUnload 卸載回調函數
	//安裝 回調函數
    MiniFilterInstanceSetup,                    //  InstanceSetup
    MiniFilterInstanceQueryTeardown,            //  InstanceQueryTeardown
    MiniFilterInstanceTeardownStart,            //  InstanceTeardownStart
    MiniFilterInstanceTeardownComplete,         //  InstanceTeardownComplete

    NULL,                               //  GenerateFileName  生成文件名回調
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent

};


結構中的回調函數數組:

//過濾函數數組
//聲明過后,通過注冊,IRP包就會順利地通過這里指定的函數被處理
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {

    { IRP_MJ_CREATE,              //主功能號   系統接收到標志為IRP_MJ_CREATE的IRP包,自動調用預處理函數和后處理函數
      0,                          //標志位,傳0表示操作讀寫回調
      MiniFilterPreOperation,     //生成(設置)預操作回調函數
      MiniFilterPostOperation },  //生成后操作回調函數
    { IRP_MJ_OPERATION_END }     //最后一個元素IRP_MJ_OPERATION_END,告訴過濾管理元素個數
};


數組中的預操作回調函數
系統接收到標志為IRP_MJ_CREATE的IRP包,自動調用預處理函數和后處理函數

FLT_PREOP_CALLBACK_STATUS
MiniFilterPreOperation (
    _Inout_ PFLT_CALLBACK_DATA Data,                       //回調數據包,代表一個IO操作
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
    )

{
    NTSTATUS Status;
	//存放文件名的緩沖區
	char FileNameData[MAX_PATH] = {0};
	PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
	//用宏掩蓋不使用的參數,編譯不警告
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );

    DbgPrint("MiniFilterPreOperation\r\n");


	__try
	{
		Status = FltGetFileNameInformation(Data,
			FLT_FILE_NAME_NORMALIZED |
			FLT_FILE_NAME_QUERY_DEFAULT,
			&FileNameInfo);


		if (NT_SUCCESS(Status))
		{
			//客戶端命令:阻塞還是放行
			if (__UserCommand==USER_BLOCK)
			{
				 FltParseFileNameInformation(FileNameInfo);  
				 if (UnicodeStringToChar(FileNameData,&FileNameInfo->Name)) //字符串轉化為char大寫,便於比較
				 {

					 if (strstr(FileNameData, "NOTEPAD.EXE") > 0) {

						 Data->IoStatus.Status = STATUS_ACCESS_DENIED;
						 Data->IoStatus.Information = 0;
						 FltReleaseFileNameInformation(FileNameInfo);
						 return FLT_PREOP_COMPLETE;  
					 }
				 }


			}
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{

	}
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}





二.minifilter與應用程序通信(從端口這一點來看,minifilter應該是封裝的LPC或者ALPC)


1.創建通信端口

	PSECURITY_DESCRIPTOR SecurityDescriptor;
	OBJECT_ATTRIBUTES    ObjectAttributes;
	Status = FltBuildDefaultSecurityDescriptor(&SecurityDescriptor, FLT_PORT_ALL_ACCESS);

	if (!NT_SUCCESS(Status)) 
	{
		goto Exit;
	}

	RtlInitUnicodeString(&MiniFilterPortName, MINI_FILTER_PORT_NAME);
	//初始化ObjectAttributes,包含端口名MiniFilterPortName,方便Ring3應用層使用
	InitializeObjectAttributes(&ObjectAttributes,
		&MiniFilterPortName,
		OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,  //OBJ_KERNEL_HANDLE 必需???
		NULL,
		SecurityDescriptor);
	//創建通信端口
	Status = FltCreateCommunicationPort(__FilterHandle,
		&__FilterServerPort,   //監聽連接請求的端口
		&ObjectAttributes,     //
		NULL,
		MiniFilterConnect,     //用戶態連接后的回調函數
		MiniFilterDisconnect,
		MiniFilterDeviceIoControl,  //MessageNotifyCallback   接受消息的回調函數
		1);


2.用戶層連接通信端口,返回句柄

int InitialCommunicationPort(void)
{
	//MiniFilter 的通信機制  封裝的LPC和ALPC????
	//端口連接
	DWORD Status = FilterConnectCommunicationPort(
		MINI_FILTER_PORT_NAME, //(通信端口名稱)用於連接
		0,
		NULL,
		0,
		NULL,
		&__PortHandle);      //通過Ring3應用層返回的端口句柄__PortHandle與驅動通信

	if (Status != S_OK) {
		return Status;
	}
	return 0;
}

3.觸發minifilter連接回調函數

NTSTATUS
MiniFilterConnect(
	__in PFLT_PORT ClientPort,
	__in PVOID ServerPortCookie,
	__in_bcount(SizeOfContext) PVOID ConnectionContext,
	__in ULONG SizeOfContext,
	__deref_out_opt PVOID *ConnectionCookie
)
{
	DbgPrint("MiniFilterConnect()\r\n");
	PAGED_CODE();

	UNREFERENCED_PARAMETER(ServerPortCookie);
	UNREFERENCED_PARAMETER(ConnectionContext);
	UNREFERENCED_PARAMETER(SizeOfContext);
	UNREFERENCED_PARAMETER(ConnectionCookie);

	
	__FilterClientPort = ClientPort;      //通信端口句柄
	return STATUS_SUCCESS;
}


4.應用層向minifilter發送消息
int MiniFilterDeviceIoControl(USER_COMMAND UserCommand)
{
	DWORD ReturnLength = 0;
	DWORD Status = 0;
	//同步還是異步 ??  ---> 同步機制
	//同步操作,直到消息被傳遞並受到驅動的reply
	//發送消息到內核層
	Status = FilterSendMessage(
		__PortHandle,     //通信端口句柄
		&UserCommand,
		sizeof(USER_COMMAND),
		NULL,            //驅動的reply,傳的NULL
		NULL,
		&ReturnLength);

	if (Status != S_OK)
	{
		return Status;
	}
	return 0;
}


5.minifilter注冊的MessageNotifyCallback   接受消息的回調函數

NTSTATUS
MiniFilterDeviceIoControl(
	__in PVOID ConnectionCookie,
	__in_bcount_opt(InputBufferSize) PVOID InputBuffer,
	__in ULONG InputBufferSize,
	__out_bcount_part_opt(OutputBufferSize, *ReturnOutputBufferLength) PVOID OutputBuffer,
	__in ULONG OutputBufferSize,
	__out PULONG ReturnOutputBufferLength
)
{

	enum _USER_COMMAND_ UserCommand;
	NTSTATUS Status;

	PAGED_CODE();

	UNREFERENCED_PARAMETER(ConnectionCookie);
	UNREFERENCED_PARAMETER(OutputBufferSize);
	UNREFERENCED_PARAMETER(OutputBuffer);

	DbgPrint("MiniFilterDeviceIoControl()\r\n");

	if ((InputBuffer != NULL) &&
		(InputBufferSize  == sizeof(USER_COMMAND)))
	{

		try {
	
			UserCommand = *((USER_COMMAND*)InputBuffer);

		} except(EXCEPTION_EXECUTE_HANDLER)
		{

			return GetExceptionCode();
		}

		switch (UserCommand) 
		{
		case USER_PASS:
		{

			__UserCommand = USER_PASS;
			Status = STATUS_SUCCESS;
			break;
		}
		case USER_BLOCK:
		{
	
			__UserCommand = USER_BLOCK;    //__UserCommand  傳給預操作函數或者后操作函數的值
			Status = STATUS_SUCCESS;
			break;
		}

		default:
			Status = STATUS_INVALID_PARAMETER;
			break;
		}
	}
	else {

		Status = STATUS_INVALID_PARAMETER;
	}

	return Status;
}

  

  

0x03   功能實現

   程序實現的功能是攔截關於Notepad.exe的一切主功能碼為IRP_MJ_CREATE的IRP包,使得Notepad.exe無法創建,存在的Notepad文件無法打開。

   如圖所示,雙擊一個txt文檔將無法打開:

  

 

源代碼:

 

  1 #include "MiniFilter.h"
  2 #include "__String.h"
  3 
  4 //注意把inf文件中的 Instance1.Altitude = "370030"  注釋去掉
  5 
  6  
  7 PFLT_FILTER  __FilterHandle = NULL;
  8 USER_COMMAND __UserCommand  = USER_BLOCK;
  9 PFLT_PORT    __FilterServerPort   = NULL;   //監聽
 10 PFLT_PORT    __FilterClientPort   = NULL;   //通信
 11 
 12 
 13 //過濾函數數組
 14 //聲明過后,通過注冊,IRP包就會順利地通過這里指定的函數被處理
 15 CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
 16 
 17     { IRP_MJ_CREATE,              //主功能號   系統接收到標志為IRP_MJ_CREATE的IRP包,自動調用預處理函數和后處理函數
 18       0,                          //標志位,傳0表示操作讀寫回調
 19       MiniFilterPreOperation,     //生成(設置)預操作回調函數
 20       MiniFilterPostOperation },  //生成后操作回調函數
 21 
 22     { IRP_MJ_OPERATION_END }     //最后一個元素IRP_MJ_OPERATION_END,告訴過濾管理元素個數
 23 };
 24 
 25 
 26 //微過濾器注冊結構
 27 CONST FLT_REGISTRATION FilterRegistration = {
 28 
 29     sizeof( FLT_REGISTRATION ),         //  Size    大小
 30     FLT_REGISTRATION_VERSION,           //  Version 版本
 31     0,                                  //  Flags   標志位傳0
 32 
 33     NULL,                               //  Context
 34     Callbacks,    //回調函數數組        //  Operation callbacks  操作回調函數集注冊,最重點!!!
 35 
 36     MiniFilterUnload,                           //  MiniFilterUnload 卸載回調函數
 37     //安裝 回調函數
 38     MiniFilterInstanceSetup,                    //  InstanceSetup
 39     MiniFilterInstanceQueryTeardown,            //  InstanceQueryTeardown
 40     MiniFilterInstanceTeardownStart,            //  InstanceTeardownStart
 41     MiniFilterInstanceTeardownComplete,         //  InstanceTeardownComplete
 42 
 43     NULL,                               //  GenerateFileName  生成文件名回調
 44     NULL,                               //  GenerateDestinationFileName
 45     NULL                                //  NormalizeNameComponent
 46 
 47 };
 48 
 49 
 50 
 51 
 52 
 53 
 54 NTSTATUS
 55 DriverEntry (
 56     _In_ PDRIVER_OBJECT DriverObject,
 57     _In_ PUNICODE_STRING RegistryPath
 58     )
 59 {
 60     NTSTATUS Status;
 61     UNICODE_STRING  MiniFilterPortName;
 62     PSECURITY_DESCRIPTOR SecurityDescriptor;
 63     OBJECT_ATTRIBUTES    ObjectAttributes;
 64     UNREFERENCED_PARAMETER( RegistryPath );  //不用該參數
 65 
 66 
 67     //向過濾管理器注冊微過濾器
 68     Status = FltRegisterFilter( DriverObject,        //DriverEntry參數DriverObject
 69                                 &FilterRegistration, //微過濾器注冊結構
 70                                 &__FilterHandle);    //微過濾器句柄,全局保存
 71 
 72  
 73     if (NT_SUCCESS(Status)) 
 74     {
 75         //開啟過濾
 76         Status = FltStartFiltering(__FilterHandle);
 77 
 78         if (!NT_SUCCESS(Status)) 
 79         {
 80             //開啟失敗注銷微過濾器
 81             goto Exit;
 82         }
 83     }
 84     else
 85     {
 86         goto Exit;
 87     }
 88     Status = FltBuildDefaultSecurityDescriptor(&SecurityDescriptor, FLT_PORT_ALL_ACCESS);
 89 
 90     if (!NT_SUCCESS(Status)) 
 91     {
 92         goto Exit;
 93     }
 94 
 95     RtlInitUnicodeString(&MiniFilterPortName, MINI_FILTER_PORT_NAME);
 96     //初始化ObjectAttributes,包含端口名MiniFilterPortName,方便Ring3應用層使用
 97     InitializeObjectAttributes(&ObjectAttributes,
 98         &MiniFilterPortName,
 99         OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,  //OBJ_KERNEL_HANDLE 必需???
100         NULL,
101         SecurityDescriptor);
102     //創建通信端口
103     Status = FltCreateCommunicationPort(__FilterHandle,
104         &__FilterServerPort,   //監聽連接請求的端口
105         &ObjectAttributes,     //
106         NULL,
107         MiniFilterConnect,     //用戶態連接后的回調函數
108         MiniFilterDisconnect,
109         MiniFilterDeviceIoControl,  //MessageNotifyCallback   接受消息的回調函數
110         1);
111 
112     FltFreeSecurityDescriptor(SecurityDescriptor);
113 
114     if (!NT_SUCCESS(Status)) {
115         goto Exit;
116     }
117 
118 Exit :
119     if (!NT_SUCCESS(Status)) {
120 
121         if (NULL != __FilterServerPort) {
122             FltCloseCommunicationPort(__FilterServerPort);
123         }
124 
125         if (NULL != __FilterHandle) {
126             FltUnregisterFilter(__FilterHandle);
127         }
128     }
129     return Status;
130 }
131 
132 
133 
134 NTSTATUS
135 MiniFilterConnect(
136     __in PFLT_PORT ClientPort,
137     __in PVOID ServerPortCookie,
138     __in_bcount(SizeOfContext) PVOID ConnectionContext,
139     __in ULONG SizeOfContext,
140     __deref_out_opt PVOID *ConnectionCookie
141 )
142 {
143     DbgPrint("MiniFilterConnect()\r\n");
144     PAGED_CODE();
145 
146     UNREFERENCED_PARAMETER(ServerPortCookie);
147     UNREFERENCED_PARAMETER(ConnectionContext);
148     UNREFERENCED_PARAMETER(SizeOfContext);
149     UNREFERENCED_PARAMETER(ConnectionCookie);
150 
151     
152     __FilterClientPort = ClientPort;
153     return STATUS_SUCCESS;
154 }
155 
156 VOID
157 MiniFilterDisconnect(
158     __in_opt PVOID ConnectionCookie
159 )
160 {
161     PAGED_CODE();
162     UNREFERENCED_PARAMETER(ConnectionCookie);
163     DbgPrint("MiniFilterDisconnect()\r\n");
164 
165     //  Close our handle
166     FltCloseClientPort(__FilterHandle, &__FilterClientPort);
167 }
168 
169 NTSTATUS
170 MiniFilterDeviceIoControl(
171     __in PVOID ConnectionCookie,
172     __in_bcount_opt(InputBufferSize) PVOID InputBuffer,
173     __in ULONG InputBufferSize,
174     __out_bcount_part_opt(OutputBufferSize, *ReturnOutputBufferLength) PVOID OutputBuffer,
175     __in ULONG OutputBufferSize,
176     __out PULONG ReturnOutputBufferLength
177 )
178 {
179 
180     enum _USER_COMMAND_ UserCommand;
181     NTSTATUS Status;
182 
183     PAGED_CODE();
184 
185     UNREFERENCED_PARAMETER(ConnectionCookie);
186     UNREFERENCED_PARAMETER(OutputBufferSize);
187     UNREFERENCED_PARAMETER(OutputBuffer);
188 
189     DbgPrint("MiniFilterDeviceIoControl()\r\n");
190 
191     if ((InputBuffer != NULL) &&
192         (InputBufferSize  == sizeof(USER_COMMAND)))
193     {
194 
195         try {
196     
197             UserCommand = *((USER_COMMAND*)InputBuffer);
198 
199         } except(EXCEPTION_EXECUTE_HANDLER)
200         {
201 
202             return GetExceptionCode();
203         }
204 
205         switch (UserCommand) 
206         {
207         case USER_PASS:
208         {
209 
210             __UserCommand = USER_PASS;
211             Status = STATUS_SUCCESS;
212             break;
213         }
214         case USER_BLOCK:
215         {
216     
217             __UserCommand = USER_BLOCK;
218             Status = STATUS_SUCCESS;
219             break;
220         }
221 
222         default:
223             Status = STATUS_INVALID_PARAMETER;
224             break;
225         }
226     }
227     else {
228 
229         Status = STATUS_INVALID_PARAMETER;
230     }
231 
232     return Status;
233 }
234 NTSTATUS
235 MiniFilterUnload (
236     _In_ FLT_FILTER_UNLOAD_FLAGS Flags)
237 {
238     UNREFERENCED_PARAMETER(Flags);
239     PAGED_CODE();
240 
241     DbgPrint("MiniFilter!MiniFilterUnload: Entered\n");
242 
243     //用來釋放已注冊的微過濾器在Windows內核內部所使用的資源
244     //關閉通信端口
245     FltCloseCommunicationPort(__FilterServerPort);
246     
247     FltUnregisterFilter(__FilterHandle);
248 
249 
250 
251     return STATUS_SUCCESS;
252 }
253 
254 
255 
256 FLT_PREOP_CALLBACK_STATUS
257 MiniFilterPreOperation (
258     _Inout_ PFLT_CALLBACK_DATA Data,                       //回調數據包,代表一個IO操作
259     _In_ PCFLT_RELATED_OBJECTS FltObjects,
260     _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
261     )
262 
263 {
264     NTSTATUS Status;
265     //存放文件名的緩沖區
266     char FileNameData[MAX_PATH] = {0};
267     PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
268     //用宏掩蓋不使用的參數,編譯不警告
269     UNREFERENCED_PARAMETER( FltObjects );
270     UNREFERENCED_PARAMETER( CompletionContext );
271 
272     DbgPrint("MiniFilterPreOperation\r\n");
273 
274 
275     __try
276     {
277         Status = FltGetFileNameInformation(Data,
278             FLT_FILE_NAME_NORMALIZED |
279             FLT_FILE_NAME_QUERY_DEFAULT,
280             &FileNameInfo);
281 
282         if (NT_SUCCESS(Status))
283         {
284             //客戶端命令:阻塞還是放行
285             if (__UserCommand==USER_BLOCK)
286             {
287                  FltParseFileNameInformation(FileNameInfo);  
288                  if (UnicodeStringToChar(FileNameData,&FileNameInfo->Name)) //字符串轉化為char大寫,便於比較
289                  {
290 
291                      if (strstr(FileNameData, "NOTEPAD.EXE") > 0) {
292 
293                          Data->IoStatus.Status = STATUS_ACCESS_DENIED;
294                          Data->IoStatus.Information = 0;
295                          FltReleaseFileNameInformation(FileNameInfo);
296                          return FLT_PREOP_COMPLETE;  
297                      }
298                  }
299 
300 
301             }
302         }
303     }
304     __except(EXCEPTION_EXECUTE_HANDLER)
305     {
306 
307     }
308     return FLT_PREOP_SUCCESS_WITH_CALLBACK;
309 }
310 
311 
312 
313 FLT_POSTOP_CALLBACK_STATUS
314 MiniFilterPostOperation (
315     _Inout_ PFLT_CALLBACK_DATA Data,
316     _In_ PCFLT_RELATED_OBJECTS FltObjects,
317     _In_opt_ PVOID CompletionContext,
318     _In_ FLT_POST_OPERATION_FLAGS Flags
319     )
320 {
321     UNREFERENCED_PARAMETER( Data );
322     UNREFERENCED_PARAMETER( FltObjects );
323     UNREFERENCED_PARAMETER( CompletionContext );
324     UNREFERENCED_PARAMETER( Flags );
325 
326   
327 
328     return FLT_POSTOP_FINISHED_PROCESSING;
329 }
330 
331 
332 NTSTATUS
333 MiniFilterInstanceSetup(
334     _In_ PCFLT_RELATED_OBJECTS FltObjects,
335     _In_ FLT_INSTANCE_SETUP_FLAGS Flags,
336     _In_ DEVICE_TYPE VolumeDeviceType,
337     _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType
338 )
339 
340 {
341     UNREFERENCED_PARAMETER(FltObjects);
342     UNREFERENCED_PARAMETER(Flags);
343     UNREFERENCED_PARAMETER(VolumeDeviceType);
344     UNREFERENCED_PARAMETER(VolumeFilesystemType);
345 
346     PAGED_CODE();
347 
348 
349 
350     return STATUS_SUCCESS;
351 }
352 
353 
354 NTSTATUS
355 MiniFilterInstanceQueryTeardown(
356     _In_ PCFLT_RELATED_OBJECTS FltObjects,
357     _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
358 )
359 
360 {
361     UNREFERENCED_PARAMETER(FltObjects);
362     UNREFERENCED_PARAMETER(Flags);
363 
364     PAGED_CODE();
365 
366 
367 
368     return STATUS_SUCCESS;
369 }
370 
371 
372 VOID
373 MiniFilterInstanceTeardownStart(
374     _In_ PCFLT_RELATED_OBJECTS FltObjects,
375     _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
376 )
377 
378 {
379     UNREFERENCED_PARAMETER(FltObjects);
380     UNREFERENCED_PARAMETER(Flags);
381     PAGED_CODE();
382 
383 }
384 
385 
386 VOID
387 MiniFilterInstanceTeardownComplete(
388     _In_ PCFLT_RELATED_OBJECTS FltObjects,
389     _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags
390 )
391 
392 {
393     UNREFERENCED_PARAMETER(FltObjects);
394     UNREFERENCED_PARAMETER(Flags);
395 
396     PAGED_CODE();
397 }
MiniFilter.c
 1 // MiniFilter(User).cpp : 定義控制台應用程序的入口點。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <windows.h>
 6 
 7 typedef enum _USER_COMMAND_
 8 {
 9     USER_PASS = 0,
10     USER_BLOCK
11 }USER_COMMAND;
12 
13 typedef
14 int(*LPFN_MINIFILTERDEVICEIOCONTROL)(USER_COMMAND UserCommand);
15 
16 int main()
17 {
18 
19     HMODULE ModuleBase = LoadLibrary(L"MiniFilter-Dll.dll");
20     if (ModuleBase==NULL)
21     {
22         return 0;
23     }
24     //向驅動發送消息
25     LPFN_MINIFILTERDEVICEIOCONTROL MiniFilterDeviceIoControl =
26         (LPFN_MINIFILTERDEVICEIOCONTROL)GetProcAddress(ModuleBase, "MiniFilterDeviceIoControl");
27 
28     if (MiniFilterDeviceIoControl==NULL)
29     {
30 
31         goto Exit;
32     }
33 
34     printf("0..放行\r\n");
35     printf("1..攔截\r\n");
36     
37 
38     ULONG  i;
39     scanf("%d", &i);
40     switch (i)
41     {
42     case 0:
43     {
44         MiniFilterDeviceIoControl(USER_PASS);
45         break;
46     }
47     case 1:
48     {
49         MiniFilterDeviceIoControl(USER_BLOCK);
50         break;
51     }
52     default:
53         break;
54     }
55 Exit:
56     FreeLibrary(ModuleBase);
57     ModuleBase = NULL;
58     return 0;
59 }
MiniFilter(User).cpp
 1 // dllmain.cpp : 定義 DLL 應用程序的入口點。
 2 #include "stdafx.h"
 3 #include <FltUser.h>
 4 #pragma comment(lib, "fltLib.lib")
 5 typedef enum _USER_COMMAND_
 6 {
 7     USER_PASS = 0,
 8     USER_BLOCK
 9 }USER_COMMAND;
10 
11 #define MINI_FILTER_PORT_NAME                                L"\\MiniFilterPort"
12 HANDLE __PortHandle = INVALID_HANDLE_VALUE;
13 
14 
15 int InitialCommunicationPort(void);
16 BOOL APIENTRY DllMain( HMODULE hModule,
17                        DWORD  ul_reason_for_call,
18                        LPVOID lpReserved
19                      )
20 {
21     switch (ul_reason_for_call)
22     {
23     case DLL_PROCESS_ATTACH:          //載入Dll成功時呼叫此功能碼
24     {
25 
26         InitialCommunicationPort();
27         break;
28     }
29     case DLL_THREAD_ATTACH:
30     case DLL_THREAD_DETACH:
31     case DLL_PROCESS_DETACH:           //卸載Dll成功時呼叫此功能碼
32     {
33 
34         if (__PortHandle!=NULL)
35         {
36             CloseHandle(__PortHandle);
37             __PortHandle = NULL;
38         }
39     }
40         break;
41     }
42     return TRUE;
43 }
44 int InitialCommunicationPort(void)
45 {
46     //MiniFilter 的通信機制  封裝的LPC和ALPC????
47     //端口連接
48     DWORD Status = FilterConnectCommunicationPort(
49         MINI_FILTER_PORT_NAME, //(通信端口名稱)用於連接
50         0,
51         NULL,
52         0,
53         NULL,
54         &__PortHandle);      //通過Ring3應用層返回的端口句柄__PortHandle與驅動通信
55 
56     if (Status != S_OK) {
57         return Status;
58     }
59     return 0;
60 }
61 
62 
63 int MiniFilterDeviceIoControl(USER_COMMAND UserCommand)
64 {
65     DWORD ReturnLength = 0;
66     DWORD Status = 0;
67     //同步還是異步 ??  ---> 同步機制
68     //同步操作,直到消息被傳遞並受到驅動的reply
69     //發送消息到內核層
70     Status = FilterSendMessage(
71         __PortHandle,
72         &UserCommand,
73         sizeof(USER_COMMAND),
74         NULL,            //驅動的reply,傳的NULL
75         NULL,
76         &ReturnLength);
77 
78     if (Status != S_OK)
79     {
80         return Status;
81     }
82     return 0;
83 }
dllmain.cpp

 

   

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM