应用层的代码如下: /* 名字:minifilter通讯之简单示例.之所以说简单是因为没有列举异步,多线程等全面和安全的用法. 个人感觉FilterSendMessage就像DeviceIoControl,可以发送和接受信息. 但是要自定义格式结构,驱动收到了再解析. FilterGetMessage和FilterReplyMessage可能需要多线程或者异步等措施,这里不列举了,只是简单列举一下调用: //FILTER_MESSAGE_HEADER MessageBuffer; //hResult = FilterGetMessage(port, &MessageBuffer, sizeof (FILTER_MESSAGE_HEADER), 0); //if (IS_ERROR( hResult )) { // OutputDebugString(L"FilterGetMessage fail!\n"); //} else { // OutputDebugString(L"FilterGetMessage ok!\n"); //} //FILTER_REPLY_HEADER ReplyBuffer; //hResult = FilterReplyMessage(port, &ReplyBuffer,sizeof(FILTER_REPLY_HEADER)); //if (IS_ERROR( hResult )) { // OutputDebugString(L"FilterReplyMessage fail!\n"); //} else { // OutputDebugString(L"FilterReplyMessage ok!\n"); //} 不足之处,敬请指出. made by correy made at 2013.11.13 email:kouleguan at hotmail dot com homepage:http://correy.webs.com 效果如下(包括驱动打印的消息): 用户发来的信息是:test [1124] FilterSendMessage ok! [1124] 从内核发来的信息是: [1124] to user client [1124] */ #include <windows.h> //这两个文件在VS中没有,在WDK中有. //如果要用VS编译要拷贝相应的文件到相应的目录或者改变目录的设置等. #include <fltuser.h> #pragma comment(lib, "fltLib.lib") int _tmain(int argc, _TCHAR* argv[]) { MessageBox(0,L"请附加调试器",L"调试专用",0);//如果是远程调试的话,这行特别有用. HANDLE port = INVALID_HANDLE_VALUE; HRESULT hResult = S_OK; hResult = FilterConnectCommunicationPort( L"\\CommunicationPort", 0, NULL, 0, NULL, &port ); if (IS_ERROR( hResult )) { OutputDebugString(L"FilterConnectCommunicationPort fail!\n"); return hResult; } wchar_t InBuffer[] = L"test"; wchar_t OutBuffer[MAX_PATH] = {0}; DWORD bytesReturned = 0; hResult = FilterSendMessage(port, InBuffer, lstrlen(InBuffer), OutBuffer, sizeof(OutBuffer), &bytesReturned); if (IS_ERROR( hResult )) { OutputDebugString(L"FilterSendMessage fail!\n"); CloseHandle( port ); return hResult; } else { OutputDebugString(L"FilterSendMessage ok!\n"); } OutputDebugString(L"从内核发来的信息是:"); OutputDebugString(OutBuffer); OutputDebugString(L"\n"); CloseHandle( port ); return 0; } 驱动的代码如下: /* 内核中没有:FltGetMessage,FltReplyMessage函数. 个人认为:MessageNotifyCallback有FltGetMessage,FltReplyMessage,FltSendMessage这三个函数的功能. 所以在MessageNotifyCallback里面调用这些函数是不对的,得到一些意想不到的效果.建议不要这样做. FltGetMessage除了在MessageNotifyCallback里面,大多的地方都可以调用,但是用户层最好开启线程处理函数. FltGetMessage函数调用示例代码如下: //{ // wchar_t SenderBuffer[] = L"SenderBuffer"; // wchar_t ReplyBuffer[] = L"ReplyBuffer"; // ULONG replyLength = sizeof(ReplyBuffer); // // status = FltSendMessage( gFilterHandle, &g_ClientPort, SenderBuffer, sizeof(SenderBuffer), ReplyBuffer, &replyLength, NULL); // if (STATUS_SUCCESS == status) { // DbgPrint( "send message to user-mode\n"); // } else { // DbgPrint( "couldn't send message to user-mode to scan file, status 0x%X\n", status ); // } //} */ #include <fltKernel.h> PFLT_FILTER gFilterHandle; PFLT_PORT g_ServerPort; PFLT_PORT g_ClientPort; NTSTATUS MessageNotifyCallback ( IN PVOID PortCookie, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength,//用户可以接受的数据的最大长度. OUT PULONG ReturnOutputBufferLength) /* 这里要注意:1.数据地址的对齐. 2.文档建议使用:try/except处理. 3.如果是64位的驱动要考虑32位的EXE发来的请求. */ { NTSTATUS status = 0; wchar_t buffer[] = L"to user client";// PAGED_CODE(); UNREFERENCED_PARAMETER(PortCookie); //打印用户发来的信息 KdPrint(("用户发来的信息是:%ls\n",InputBuffer)); //返回用户一些信息. *ReturnOutputBufferLength = sizeof(buffer); RtlCopyMemory(OutputBuffer,buffer,* ReturnOutputBufferLength); /* minispy在这里用FilterSendMessage获取信息的,对就是FilterSendMessage. 这里某个类型里面获取信息,这些信息是在各种操作时(IRP的MJ_)加入链表的. 注意链表的操作一定要同步,支持多线程. 然后用户的一个线程在不停的获取这些信息. */ return status; } VOID DisconnectNotifyCallback (_In_opt_ PVOID ConnectionCookie) { PAGED_CODE(); UNREFERENCED_PARAMETER(ConnectionCookie); FltCloseClientPort(gFilterHandle, &g_ClientPort);//应该加判断,如果ConnectionCookie == 我们的值就执行这行. } NTSTATUS ConnectNotifyCallback (IN PFLT_PORT ClientPort, IN PVOID ServerPortCookie, IN PVOID ConnectionContext, IN ULONG SizeOfContext, OUT PVOID * ConnectionPortCookie) { PAGED_CODE(); UNREFERENCED_PARAMETER( ServerPortCookie ); UNREFERENCED_PARAMETER( ConnectionContext ); UNREFERENCED_PARAMETER( SizeOfContext); UNREFERENCED_PARAMETER( ConnectionPortCookie); //可以加以判断,禁止非法的连接,从而给予保护. g_ClientPort = ClientPort;//保存以供以后使用. return STATUS_SUCCESS; } #pragma PAGEDCODE NTSTATUS PtInstanceQueryTeardown (__in PCFLT_RELATED_OBJECTS FltObjects,__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags) { return STATUS_SUCCESS; } #pragma PAGEDCODE//#pragma alloc_text(PAGE, PtUnload) NTSTATUS PtUnload (__in FLT_FILTER_UNLOAD_FLAGS Flags) { FltCloseCommunicationPort(g_ServerPort);//没有这一行是停止不了驱动的,查询也是永远等待中. FltUnregisterFilter( gFilterHandle ); return STATUS_SUCCESS; } CONST FLT_REGISTRATION FilterRegistration = { sizeof( FLT_REGISTRATION ), // Size FLT_REGISTRATION_VERSION, // Version 0, // Flags NULL, // Context NULL, // Operation callbacks PtUnload, // MiniFilterUnload NULL, // InstanceSetup PtInstanceQueryTeardown, // InstanceQueryTeardown NULL, // InstanceTeardownStart NULL, // InstanceTeardownComplete NULL, // GenerateFileName NULL, // GenerateDestinationFileName NULL // NormalizeNameComponent }; DRIVER_INITIALIZE DriverEntry; #pragma alloc_text(INIT, DriverEntry)//#pragma INITCODE NTSTATUS DriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { NTSTATUS status; PSECURITY_DESCRIPTOR sd; OBJECT_ATTRIBUTES oa; UNICODE_STRING uniString; UNREFERENCED_PARAMETER(RegistryPath); KdBreakPoint(); __try { status = FltRegisterFilter(DriverObject, &FilterRegistration, &gFilterHandle); if (!NT_SUCCESS(status)) //; { __leave; } status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS); if (!NT_SUCCESS( status )) { __leave; } RtlInitUnicodeString(&uniString, L"\\CommunicationPort"); InitializeObjectAttributes( &oa, &uniString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, sd); status = FltCreateCommunicationPort(gFilterHandle, &g_ServerPort, &oa, NULL, ConnectNotifyCallback, DisconnectNotifyCallback, MessageNotifyCallback, 1); FltFreeSecurityDescriptor( sd ); if (!NT_SUCCESS( status )) { __leave; } status = FltStartFiltering(gFilterHandle);//这个结果在下面判断. } __finally { if (!NT_SUCCESS( status ) ) { if (NULL != g_ServerPort) { FltCloseCommunicationPort(g_ServerPort); } if (NULL != gFilterHandle) { FltUnregisterFilter(gFilterHandle); } } } return status; }
2013年11月13日星期三
minifilter通讯之简单示例
订阅:
博文评论 (Atom)
没有评论:
发表评论