EXE和SYS通信(FltSendMessage+FilterReplyMessage)

#ifndef _HEADER_HEAD_FILE
#define _HEADER_HEAD_FILE
#pragma once
#include <fltKernel.h>
#include <Ntstrsafe.h>

#ifndef MAX_PATH
#define MAX_PATH	260
#endif

typedef struct _SCANNER_NOTIFICATION {

	BOOLEAN bCreate;
	ULONG Reserved;            
	UCHAR ProcessName[MAX_PATH];
} SCANNER_NOTIFICATION, *PSCANNER_NOTIFICATION;

typedef struct _SCANNER_REPLY {

	BOOLEAN SafeToOpen;
	UCHAR	ReplyMsg[MAX_PATH];
} SCANNER_REPLY, *PSCANNER_REPLY;


NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);

NTSTATUS PtUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags);

NTSTATUS PtInstanceQueryTeardown(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags);

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



#endif


#include "Header.h"

PFLT_FILTER gFilterHandle;
PFLT_PORT g_ServerPort;
PFLT_PORT g_ClientPort;


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


VOID DisconnectNotifyCallback(_In_opt_ PVOID ConnectionCookie)
{
	PAGED_CODE();
	UNREFERENCED_PARAMETER(ConnectionCookie);
	FltCloseClientPort(gFilterHandle, &g_ClientPort);
}



NTSTATUS PtInstanceQueryTeardown(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
{
	return STATUS_SUCCESS;
}


NTSTATUS PtUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags)
{

	FltCloseCommunicationPort(g_ServerPort);
	FltUnregisterFilter(gFilterHandle);
	return STATUS_SUCCESS;
}




//设置注册表键值  
NTSTATUS SetValueKey(PUNICODE_STRING pRegPath, PUNICODE_STRING pValueName, ULONG Type, wchar_t ValueData[MAX_PATH])
{


	//定义变量  
	size_t pcch = 0;
	OBJECT_ATTRIBUTES objectAttribues;
	HANDLE hRegister = NULL;
	NTSTATUS ntstatus;
	USHORT cbszSize = 0;

	//参数效验  
	if (pRegPath == NULL || pValueName == 0 || ValueData == NULL)return FALSE;


	switch (Type)
	{
	case REG_SZ:
	{
		//获取长度  
		RtlStringCchLengthW(ValueData, MAX_PATH, &pcch);
		if (pcch <= 0)return FALSE;
		cbszSize = (USHORT)(pcch * sizeof(wchar_t)) + sizeof(wchar_t);
	}
	break;
	case REG_DWORD:
	{
		cbszSize = sizeof(ULONG);
	}
	break;
	default:
		return STATUS_UNSUCCESSFUL;
	}


	//设置变量  
	InitializeObjectAttributes(&objectAttribues, pRegPath, OBJ_CASE_INSENSITIVE, NULL, NULL);

	//打开注册表  
	ntstatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttribues);
	if (!NT_SUCCESS(ntstatus) || hRegister == NULL)return FALSE;


	//设置REG_SZ子健  
	ntstatus = ZwSetValueKey(hRegister, pValueName, 0, Type, ValueData, cbszSize);
	ZwClose(hRegister);
	return ntstatus;
}

//注册MiniFilter
NTSTATUS RegisterMiniFilter(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryPath)
{


	UNICODE_STRING UnicodeDriverServerName;
	UNICODE_STRING UnicodeValue;
	UNICODE_STRING UnicodeSzText;
	UNICODE_STRING UnicodeSzServerNameInstances;
	ULONG ulValue;
	HANDLE hRegister;
	ULONG ulResult;
	NTSTATUS ntStatus;
	static wchar_t szInstances[MAX_PATH] = { 0 };
	static wchar_t szServerNameInstances[MAX_PATH] = { 0 };
	//初始化objectAttributes    
	OBJECT_ATTRIBUTES objectAttributes;
	wchar_t* pFind = NULL;
	ULONG  nAltitude = 399998;
	int i = 0;

	//参数效验  
	if (DriverObject == NULL)return STATUS_UNSUCCESSFUL;


	if (pRegistryPath == NULL || pRegistryPath->Length <= 0)return STATUS_UNSUCCESSFUL;
	InitializeObjectAttributes(&objectAttributes, pRegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
	//创建或打开注册表项目    
	ntStatus = ZwCreateKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes, 0, NULL, (ULONG)REG_OPTION_NON_VOLATILE, &ulResult);
	if (hRegister == NULL || ntStatus != STATUS_SUCCESS) return STATUS_UNSUCCESSFUL;
	ZwClose(hRegister);

	//DependOnService  
	RtlInitUnicodeString(&UnicodeValue, L"DependOnService");
	SetValueKey(pRegistryPath, &UnicodeValue, REG_SZ, L"FltMgr");

	//Instances  
	RtlStringCbPrintfExW(szServerNameInstances, sizeof(szServerNameInstances), NULL, NULL, STRSAFE_FILL_BEHIND_NULL, L"%wZ\\Instances", pRegistryPath);
	RtlInitUnicodeString(&UnicodeSzServerNameInstances, szServerNameInstances);
	InitializeObjectAttributes(&objectAttributes, &UnicodeSzServerNameInstances, OBJ_CASE_INSENSITIVE, NULL, NULL);
	ntStatus = ZwCreateKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &ulResult);
	if (hRegister == NULL || ntStatus != STATUS_SUCCESS) return STATUS_UNSUCCESSFUL;
	ZwClose(hRegister);



	//获取服务名  
	pFind = wcsrchr(pRegistryPath->Buffer, '\\');
	if (pFind)
		RtlInitUnicodeString(&UnicodeDriverServerName, pFind + sizeof(char));
	else
		return STATUS_UNSUCCESSFUL;

	//DefaultInstance  
	RtlInitUnicodeString(&UnicodeValue, L"DefaultInstance");
	RtlStringCbPrintfExW(szInstances, sizeof(szInstances), NULL, NULL, STRSAFE_FILL_BEHIND_NULL, L"%wZ Instance", &UnicodeDriverServerName);
	SetValueKey(&UnicodeSzServerNameInstances, &UnicodeValue, REG_SZ, szInstances);


	//ProtectFile Instance  
	RtlStringCbPrintfExW(szInstances, sizeof(szInstances), NULL, NULL, STRSAFE_FILL_BEHIND_NULL, L"%wZ\\%wZ Instance", &UnicodeSzServerNameInstances, &UnicodeDriverServerName);
	RtlInitUnicodeString(&UnicodeSzText, szInstances);
	InitializeObjectAttributes(&objectAttributes, &UnicodeSzText, OBJ_CASE_INSENSITIVE, NULL, NULL);
	ntStatus = ZwCreateKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &ulResult);
	if (hRegister == NULL || ntStatus != STATUS_SUCCESS) return STATUS_UNSUCCESSFUL;
	ZwClose(hRegister);

	//Altitude  
	RtlInitUnicodeString(&UnicodeValue, L"Altitude");
	SetValueKey(&UnicodeSzText, &UnicodeValue, REG_SZ, L"399999");


	//Flags  
	RtlInitUnicodeString(&UnicodeValue, L"Flags");
	ulValue = 0;
	SetValueKey(&UnicodeSzText, &UnicodeValue, REG_DWORD, (wchar_t*)&ulValue);


	return ntStatus;
}

//获取进程名
PCHAR GetProcessName16ByProcessId(HANDLE ProcessId)
{
	//定义变量
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PEPROCESS ProcessObj = NULL;
	PUCHAR ProcessName = NULL;

	//进程ID和返回一个引用指针的过程EPROCESS结构
	status = PsLookupProcessByProcessId(ProcessId, &ProcessObj);
	if (NT_SUCCESS(status))
	{
		// ImageFileName    : [16]  "SogouExplorer.e"
		//使用这个函数,只能获取进程名称是16的长度,后面的被截取了。。。
		ProcessName = PsGetProcessImageFileName(ProcessObj);
		ObfDereferenceObject(ProcessObj);
	}

	return ProcessName;
}



VOID CreateProcessNotifyFunction(IN HANDLE  ParentId, IN HANDLE  ProcessId, IN BOOLEAN  Create)
{
	NTSTATUS status;
	ULONG replyLength;

	if (Create == FALSE)return;
	if (gFilterHandle == NULL || g_ClientPort == NULL)return;
	char* pName = GetProcessName16ByProcessId(ProcessId);
	if (pName == NULL)return;
	
	KdPrint(("%s\n", pName));
	PSCANNER_NOTIFICATION notification = ExAllocatePool(NonPagedPool,sizeof(SCANNER_NOTIFICATION));
	if (notification == NULL)return;
	RtlZeroMemory(notification, sizeof(SCANNER_NOTIFICATION));
	notification->bCreate = Create;
	RtlCopyMemory(¬ification->ProcessName, pName,strlen(pName)+1);

	SCANNER_REPLY	Reply = {0};
	replyLength = sizeof(SCANNER_REPLY);
	status = FltSendMessage(gFilterHandle,&g_ClientPort,notification,sizeof(SCANNER_NOTIFICATION),&Reply,&replyLength,NULL);
	if (NT_SUCCESS(status))
	{
		KdPrint(("发送成功	%d\n", replyLength));
	}
	else
	{
		KdPrint(("发送失败\n"));
	}
	return;
}


VOID DriverUnload(DRIVER_OBJECT *DriverObject)
{
	PsSetCreateProcessNotifyRoutine(CreateProcessNotifyFunction, TRUE);
	return;
}


NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
	NTSTATUS status;
	PSECURITY_DESCRIPTOR sd;
	OBJECT_ATTRIBUTES oa;
	UNICODE_STRING uniString;

	KdBreakPoint();
	DriverObject->DriverUnload = DriverUnload;

	do
	{
		status = RegisterMiniFilter(DriverObject, RegistryPath);
		if (!NT_SUCCESS(status))break;

		status = FltRegisterFilter(DriverObject, &FilterRegistration, &gFilterHandle);
		if (!NT_SUCCESS(status))break;

		status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);
		if (!NT_SUCCESS(status))break;

		RtlInitUnicodeString(&uniString, L"\\CommunicationPort");
		InitializeObjectAttributes(&oa, &uniString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, sd);
		status = FltCreateCommunicationPort(gFilterHandle, &g_ServerPort, &oa, NULL, ConnectNotifyCallback, DisconnectNotifyCallback, NULL, 1);
		FltFreeSecurityDescriptor(sd);
		if (!NT_SUCCESS(status))break;

		status = FltStartFiltering(gFilterHandle);
		if (!NT_SUCCESS(status))break;

	} while (FALSE);


	if (!NT_SUCCESS(status))
	{
		if (NULL != g_ServerPort) {
			FltCloseCommunicationPort(g_ServerPort);
		}

		if (NULL != gFilterHandle) {
			FltUnregisterFilter(gFilterHandle);
		}
	}

	if (NT_SUCCESS(status))
	{
		PsSetCreateProcessNotifyRoutine(CreateProcessNotifyFunction, FALSE);
	}
	


	return status;
}





#pragma pack(1)


typedef struct _SCANNER_NOTIFICATION {

	BOOL bCreate;
	ULONG Reserved;             // for quad-word alignement of the Contents structure
	UCHAR ProcessName[MAX_PATH];

} SCANNER_NOTIFICATION, *PSCANNER_NOTIFICATION;

typedef struct _SCANNER_REPLY {

	BOOLEAN SafeToOpen;
	UCHAR	ReplyMsg[MAX_PATH];

} SCANNER_REPLY, *PSCANNER_REPLY;

typedef struct _SCANNER_MESSAGE 
{

	//
	//  Required structure header.
	//

	FILTER_MESSAGE_HEADER MessageHeader;


	//
	//  Private scanner-specific fields begin here.
	//

	SCANNER_NOTIFICATION Notification;

	//
	//  Overlapped structure: this is not really part of the message
	//  However we embed it instead of using a separately allocated overlap structure
	//

	OVERLAPPED Ovlp;

} SCANNER_MESSAGE, *PSCANNER_MESSAGE;

typedef struct _SCANNER_REPLY_MESSAGE {

	//
	//  Required structure header.
	//

	FILTER_REPLY_HEADER ReplyHeader;

	//
	//  Private scanner-specific fields begin here.
	//

	SCANNER_REPLY Reply;

} SCANNER_REPLY_MESSAGE, *PSCANNER_REPLY_MESSAGE;

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winioctl.h>
#include <string.h>
#include <crtdbg.h>
#include <assert.h>
#include <fltuser.h>
#include <dontuse.h>
#include "header.h"

#define SCANNER_DEFAULT_REQUEST_COUNT       5
#define SCANNER_DEFAULT_THREAD_COUNT        2
#define SCANNER_MAX_THREAD_COUNT            64

typedef struct _SCANNER_THREAD_CONTEXT {

	HANDLE Port;
	HANDLE Completion;

} SCANNER_THREAD_CONTEXT, *PSCANNER_THREAD_CONTEXT;

DWORD ScannerWorker(PSCANNER_THREAD_CONTEXT Context);

int main(void)
{
	DWORD requestCount = SCANNER_DEFAULT_REQUEST_COUNT;
	DWORD threadCount = SCANNER_DEFAULT_THREAD_COUNT;
	HANDLE port, completion;
	HRESULT hr;
	DWORD threadId;
	PSCANNER_MESSAGE msg;
	HANDLE threads[SCANNER_MAX_THREAD_COUNT];
	SCANNER_THREAD_CONTEXT context;
	int i = 0;

	hr = FilterConnectCommunicationPort(L"\\CommunicationPort", 0, NULL, 0, NULL, &port);
	if (IS_ERROR(hr))
	{

		printf("ERROR: Connecting to filter port: 0x%08x\n", hr);
		getchar();
		getchar();
		return 2;
	}

	completion = CreateIoCompletionPort(port,NULL,0,threadCount);
	if (completion == NULL) 
	{

		printf("ERROR: Creating completion port: %d\n", GetLastError());
		CloseHandle(port);
		getchar();
		getchar();
		return 3;
	}

	context.Port = port;
	context.Completion = completion;



	for (i = 0; i < threadCount; i++) 
	{

		threads[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ScannerWorker,&context,0,&threadId);
		if (threads[i] == NULL) 
		{
			hr = GetLastError();
			printf("ERROR: Couldn't create thread: %d\n", hr);
			goto main_cleanup;
		}

		for (int j = 0; j < requestCount; j++) 
		{


			msg = new SCANNER_MESSAGE[sizeof(SCANNER_MESSAGE)];
			if (msg == NULL) 
			{

				hr = ERROR_NOT_ENOUGH_MEMORY;
				goto main_cleanup;
			}

			memset(&msg->Ovlp, 0, sizeof(OVERLAPPED));
		
			hr = FilterGetMessage(port,&msg->MessageHeader,FIELD_OFFSET(SCANNER_MESSAGE, Ovlp),&msg->Ovlp);
			if (hr != HRESULT_FROM_WIN32(ERROR_IO_PENDING)) 
			{

				delete msg;
				goto main_cleanup;
			}
		}
	}

	hr = S_OK;
	WaitForMultipleObjectsEx(i, threads, TRUE, INFINITE, FALSE);

main_cleanup:

	printf("Scanner:  All done. Result = 0x%08x\n", hr);

	CloseHandle(port);
	CloseHandle(completion);

	getchar();
	getchar();
	return 0;
}


DWORD ScannerWorker(PSCANNER_THREAD_CONTEXT Context)
{
	BOOL result;
	DWORD outSize;
	LPOVERLAPPED pOvlp;
	ULONG_PTR key;
	HRESULT hr;
	PSCANNER_MESSAGE message;
	PSCANNER_NOTIFICATION notification;
	SCANNER_REPLY_MESSAGE replyMessage;

	while (TRUE)
	{
		result = GetQueuedCompletionStatus(Context->Completion, &outSize, &key, &pOvlp, INFINITE);
		message = CONTAINING_RECORD(pOvlp, SCANNER_MESSAGE, Ovlp);
		if (!result) 
		{
			printf("GetQueuedCompletionStatus error \n");
			break;
		}

		notification = &message->Notification;
		printf("%d	%s	%d\n", notification->bCreate, notification->ProcessName, pOvlp->InternalHigh);

		ZeroMemory(&replyMessage, sizeof(SCANNER_REPLY_MESSAGE));
		replyMessage.ReplyHeader.Status = 0;
		replyMessage.ReplyHeader.MessageId = message->MessageHeader.MessageId;
		replyMessage.Reply.SafeToOpen = 6;
		CopyMemory(replyMessage.Reply.ReplyMsg, "12345678ab", 10);
		hr = FilterReplyMessage(Context->Port, (PFILTER_REPLY_HEADER)&replyMessage, sizeof(replyMessage));
		if (SUCCEEDED(hr))
		{
			printf("Replied message\n");
		}
		else
		{
			printf("Scanner: Error replying message. Error = 0x%X\n", hr);
			break;
		}

		memset(&message->Ovlp, 0, sizeof(OVERLAPPED));
		hr = FilterGetMessage(Context->Port, &message->MessageHeader, FIELD_OFFSET(SCANNER_MESSAGE, Ovlp), &message->Ovlp);
		if (hr != HRESULT_FROM_WIN32(ERROR_IO_PENDING))
		{
			printf("线程		FilterGetMessage error\n");
			break;
		}


	}

	printf("线程结束\n");

	delete message;
	return 0;
}


  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值