- #ifndef _HEADER_HEAD_FILE
- #define _HEADER_HEAD_FILE
- #pragma once
- #include <ntifs.h>
- #include <ntddk.h>
- #include <fltKernel.h>
- #include <Ntstrsafe.h>
- #ifndef MAX_PATH
- #define MAX_PATH 260
- #endif
- NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
- //驱动控制代码
- #define IOCTL_START CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810,METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_STOP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811,METHOD_BUFFERED, FILE_ANY_ACCESS)
- 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;
- //同步事件对象
- PRKEVENT g_pEventObject = NULL;
- //句柄信息
- OBJECT_HANDLE_INFORMATION g_ObjectHandleInfo;
- char g_szOutBuf[MAX_PATH] = { 0 };
- /*
- 这里要注意:1.数据地址的对齐.
- 2.文档建议使用:try/except处理.
- 3.如果是64位的驱动要考虑32位的EXE发来的请求.
- */
- NTSTATUS MessageNotifyCallback(IN PVOID PortCookie, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, OUT PULONG ReturnOutputBufferLength)
- {
- NTSTATUS status = 0;
- PAGED_CODE();
- UNREFERENCED_PARAMETER(PortCookie);
- //返回用户一些信息.
- RtlCopyMemory(OutputBuffer, g_szOutBuf, strlen(g_szOutBuf) + 1);
- return status;
- }
- VOID DisconnectNotifyCallback(_In_opt_ PVOID ConnectionCookie)
- {
- PAGED_CODE();
- UNREFERENCED_PARAMETER(ConnectionCookie);
- FltCloseClientPort(gFilterHandle, &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;
- }
- 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)
- {
- if (Create)
- {
- char* pName=GetProcessName16ByProcessId(ProcessId);
- if (pName)
- {
- RtlZeroMemory(g_szOutBuf, sizeof(g_szOutBuf));
- RtlCopyMemory(g_szOutBuf, pName, strlen(pName)+1);
- //设置事件为有信号,通知应用层
- KeSetEvent(g_pEventObject, 0, FALSE);
- }
- }
- return;
- }
- VOID DriverUnload(DRIVER_OBJECT *DriverObject)
- {
- PsSetCreateProcessNotifyRoutine(CreateProcessNotifyFunction, TRUE);
- UNICODE_STRING Win32Device;
- RtlInitUnicodeString(&Win32Device, L"\\DosDevices\\KernelHandle");
- IoDeleteSymbolicLink(&Win32Device);
- IoDeleteDevice(DriverObject->DeviceObject);
- return;
- }
- NTSTATUS KernelHandleCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
- {
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS KernelHandleClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
- {
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Irp->IoStatus.Status;
- }
- NTSTATUS KernelHandleDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
- {
- NTSTATUS status = STATUS_SUCCESS;
- ULONG ulReturn = 0;
- PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
- ULONG ulCtrlCode = stack->Parameters.DeviceIoControl.IoControlCode;
- PVOID InputBuffer = (PVOID)Irp->AssociatedIrp.SystemBuffer;
- PVOID OutputBuffer = (PVOID)Irp->AssociatedIrp.SystemBuffer;
- ULONG ulInputBufferSize = stack->Parameters.DeviceIoControl.InputBufferLength;
- ULONG ulOutputBufferSize = stack->Parameters.DeviceIoControl.OutputBufferLength;
- switch (ulCtrlCode)
- {
- case IOCTL_START:
- {
- //设置同步事件
- if (InputBuffer == NULL || ulInputBufferSize < sizeof(HANDLE))
- {
- KdPrint(("Set Event Error~!\n"));
- break;
- }
- //取得句柄对象
- HANDLE hEvent = *(HANDLE*)InputBuffer;
- status = ObReferenceObjectByHandle(hEvent, GENERIC_ALL, NULL, KernelMode, (PVOID*)&g_pEventObject, &g_ObjectHandleInfo);
- PsSetCreateProcessNotifyRoutine(CreateProcessNotifyFunction, FALSE);
- break;
- }
- case IOCTL_STOP:
- {
- //移除进程创建通知函数
- PsSetCreateProcessNotifyRoutine(CreateProcessNotifyFunction, TRUE);
- //释放对象引用
- if (g_pEventObject != NULL)
- {
- ObDereferenceObject(g_pEventObject);
- g_pEventObject = NULL;
- }
- break;
- }
- default:
- break;
- }
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = ulOutputBufferSize;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Irp->IoStatus.Status;
- }
- NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
- {
- NTSTATUS status;
- PDEVICE_OBJECT DeviceObject = NULL;
- UNICODE_STRING DeviceName;
- UNICODE_STRING Win32Device;
- KdBreakPoint();
- DriverObject->DriverUnload = DriverUnload;
- RtlInitUnicodeString(&DeviceName, L"\\Device\\KernelHandle");
- RtlInitUnicodeString(&Win32Device, L"\\DosDevices\\KernelHandle");
- DriverObject->MajorFunction[IRP_MJ_CREATE] = KernelHandleCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = KernelHandleClose;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KernelHandleDefaultHandler;
- status = IoCreateDevice(DriverObject,0,&DeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
- if (!NT_SUCCESS(status))
- return status;
- if (!DeviceObject)
- return STATUS_UNEXPECTED_IO_ERROR;
- DeviceObject->Flags |= DO_DIRECT_IO;
- DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
- status = IoCreateSymbolicLink(&Win32Device, &DeviceName);
- DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- do
- {
- PSECURITY_DESCRIPTOR sd;
- OBJECT_ATTRIBUTES oa;
- UNICODE_STRING uniString;
- 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, MessageNotifyCallback, 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);
- }
- }
- return STATUS_SUCCESS;
- }
- #include <windows.h>
- #include <tchar.h>
- #include <stdio.h>
- //这两个文件在VS中没有,在WDK中有.
- //如果要用VS编译要拷贝相应的文件到相应的目录或者改变目录的设置等.
- #include <fltuser.h>
- #pragma comment(lib, "fltLib.lib")
- HANDLE hDevice;
- HANDLE g_hKernelEvent = NULL;
- HANDLE g_hPort;
- #define NPMINI_PORT_NAME L"\\CommunicationPort"
- //驱动控制代码
- #define IOCTL_START CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810,METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_STOP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811,METHOD_BUFFERED, FILE_ANY_ACCESS)
- DWORD WINAPI ThreadProc(LPVOID lpParameter)
- {
- printf("线程开始运行\n");
- HRESULT hResult;
- while (WaitForSingleObject(g_hKernelEvent, INFINITE) == WAIT_OBJECT_0)
- {
- printf("收到状态\n");
- wchar_t InBuffer[] = L"test";
- char OutBuffer[MAX_PATH] = { 0 };
- DWORD bytesReturned = 0;
- hResult = FilterSendMessage(g_hPort, InBuffer, lstrlen(InBuffer), OutBuffer, sizeof(OutBuffer), &bytesReturned);
- if (IS_ERROR(hResult))
- {
- printf("FilterSendMessage fail!\n");
- }
- else
- {
- printf("FilterSendMessage ok!\n");
- }
- printf("从内核发来的信息是:%s\n", OutBuffer);
- //设置同步事件为无信号,等待下一次通知
- ResetEvent(g_hKernelEvent);
- }
- printf("线程结束\n");
- return 0;
- }
- int main(void)
- {
- //创建手动重置的事件
- g_hKernelEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- //打开驱动的符号链接
- hDevice = CreateFile(L"\\\\.\\KernelHandle", GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE == hDevice)
- {
- printf("CreateFile fail!\n");
- getchar();
- getchar();
- return FALSE;
- }
- DWORD dwRet;
- DeviceIoControl(hDevice, IOCTL_START, &g_hKernelEvent, sizeof(g_hKernelEvent), NULL, NULL, &dwRet, NULL);
- HRESULT hResult = S_OK;
- hResult = FilterConnectCommunicationPort(NPMINI_PORT_NAME, 0, NULL, 0, NULL, &g_hPort);
- if (IS_ERROR(hResult))
- {
- printf("FilterConnectCommunicationPort fail!\n");
- getchar();
- getchar();
- return hResult;
- }
- printf("FilterConnectCommunicationPort\n");
- HANDLE hThread =CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
- CloseHandle(hThread);
- getchar();
- getchar();
- CloseHandle(g_hPort);
- DeviceIoControl(hDevice, IOCTL_STOP, NULL, 0, NULL, NULL, &dwRet, NULL);
- CloseHandle(hDevice);
- return 0;
- }