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 }
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 }
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 }