#ifndef _HEADER_HEAD_FILE
#define _HEADER_HEAD_FILE
#pragma once
#include <fltKernel.h>
#include <Ntstrsafe.h>
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
#define EVENT_NAMEXP L"\\BaseNamedObjects\\FileMonEvent" //xp下是这个
#define EVENT_NAME L"\\Sessions\\1\\BaseNamedObjects\\FileMonEvent" //win7上要看exe的会话
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;
PKEVENT pEvent = NULL;
HANDLE gEventHandle;
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);
//打印用户发来的信息
KdPrint(("用户发来的信息是:%ls\n", InputBuffer));
//返回用户一些信息.
RtlCopyMemory(OutputBuffer, g_szOutBuf, strlen(g_szOutBuf)+1);
KeClearEvent(pEvent);
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)
{
ZwClose(gEventHandle);
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(pEvent, IO_NO_INCREMENT, FALSE);
KeClearEvent(pEvent);
}
}
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, 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);
}
}
if (NT_SUCCESS(status))
{
UNICODE_STRING uniEventName;
RtlInitUnicodeString(&uniEventName, EVENT_NAME);
pEvent = IoCreateNotificationEvent(&uniEventName, &gEventHandle);
if (pEvent != NULL)
{
KeClearEvent(pEvent);
PKEVENT pDeveObject;
status = ObReferenceObjectByHandle(gEventHandle, GENERIC_ALL, *ExEventObjectType, KernelMode, &pDeveObject, NULL);
if (NT_SUCCESS(status))
{
ObDereferenceObject(pDeveObject);
if (NT_SUCCESS(status))
{
PsSetCreateProcessNotifyRoutine(CreateProcessNotifyFunction, FALSE);
}
}
}
}
return status;
}
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
//这两个文件在VS中没有,在WDK中有.
//如果要用VS编译要拷贝相应的文件到相应的目录或者改变目录的设置等.
#include <fltuser.h>
#pragma comment(lib, "fltLib.lib")
HANDLE g_hPort;
HANDLE g_hEvent;
bool EnableDebugPrivilege();
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
printf("线程开始运行\n");
HRESULT hResult;
while (WaitForSingleObject(g_hEvent, 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("从内核发来的信息是:");
printf("%s\n", OutBuffer);
}
printf("线程结束\n");
return 0;
}
#define NPMINI_PORT_NAME L"\\CommunicationPort"
#define EVENT_NAME L"FileMonEvent"
//"Global\\WriteEvent"
int main(void)
{
EnableDebugPrivilege();
g_hEvent = OpenEvent(SYNCHRONIZE, FALSE, EVENT_NAME);
if (g_hEvent != NULL)
{
CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
}
else
{
printf("打开驱动创建的事件失败%d\n", GetLastError());
getchar();
getchar();
}
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");
//wchar_t InBuffer[] = L"test";
//wchar_t 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");
// CloseHandle(g_hPort);
// getchar();
// getchar();
// return hResult;
//}
//else
//{
// printf("FilterSendMessage ok!\n");
//}
getchar();
getchar();
CloseHandle(g_hPort);
return 0;
}
bool EnableDebugPrivilege()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return false;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
{
CloseHandle(hToken);
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
CloseHandle(hToken);
return false;
}
return true;
}