#include "stdafx.h"
#ifdef __cplusplus
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
#endif
LIST_ENTRY logListHeader;
//minifilter 句柄
PFLT_FILTER gFilterHandle;
KEVENT s_Event;
BOOLEAN FLAG = TRUE;
//进程名的偏移
ULONG ProcessNameOffset = 0;
#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
KdPrint(("DriverEntry \n"));
InitializeListHead(&logListHeader);
//注册
status=FltRegisterFilter(DriverObject,
&FilterRegistration,
&gFilterHandle);
if (NT_SUCCESS(status))
{
//启动过滤器
status=FltStartFiltering(gFilterHandle);
if(!NT_SUCCESS(status))
{
FltUnregisterFilter(gFilterHandle);
}
}
KeInitializeEvent(&s_Event,SynchronizationEvent,FALSE);
StartThread();
return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif
NTSTATUS FilterUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags)
{
FLAG = FALSE;
FltUnregisterFilter(gFilterHandle);
KdPrint(("卸载成功\n"));
return STATUS_SUCCESS;
}
FLT_PREOP_CALLBACK_STATUS
preRead(
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
NTSTATUS status;
PFLT_FILE_NAME_INFORMATION nameInfo;
UNICODE_STRING Directory_Of_Bait_files;
UNICODE_STRING log_msg;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
PAGED_CODE();
//检查中断级
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
__try {
//判断是否文件夹
BOOLEAN isDir;
status = FltIsDirectory(FltObjects->FileObject,FltObjects->Instance,&isDir);
if (NT_SUCCESS(status))
{
//文件夹直接跳过
if (isDir)
{
return FLT_PREOP_SUCCESS_NO_CALLBACK; //是文件夹直接返回失败
}
else
{
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo );
if (NT_SUCCESS( status ))
{
FltParseFileNameInformation( nameInfo );
RtlInitUnicodeString( &Directory_Of_Bait_files, L"\\Device\\HarddiskVolume3\\");
if (RtlPrefixUnicodeString(&Directory_Of_Bait_files,&nameInfo->Name,TRUE))
{
//进入了我想要监控的目录
PEPROCESS obProcess = NULL;
HANDLE hProcess;
UNICODE_STRING fullPath;
obProcess = IoThreadToProcess(Data->Thread);
hProcess = PsGetProcessId(obProcess);
fullPath.Length = 0;
fullPath.MaximumLength = 520;
fullPath.Buffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool,520,PROCESS_FULLPATH);
if (fullPath.Buffer == NULL)
{
FltReleaseFileNameInformation( nameInfo );
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
status = GetProcessImageName(hProcess,&fullPath);
if (!NT_SUCCESS(status))
{
FltReleaseFileNameInformation( nameInfo );
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
UNICODE_STRING tmpTail;
RtlInitUnicodeString( &tmpTail, L";\r\n"); //用来结尾
ULONG len = fullPath.MaximumLength + nameInfo->Name.MaximumLength + tmpTail.MaximumLength;
PLOG_LIST logListNode;
logListNode = (PLOG_LIST)ExAllocatePool(NonPagedPool,sizeof(LOG_LIST));
if (logListNode == NULL)
{
KdPrint(("队列申请失败 \n"));
}
logListNode->msg.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, len, LOG_MSG);
logListNode->msg.Length = 0;
logListNode->msg.MaximumLength = len;
RtlAppendUnicodeStringToString(&logListNode->msg,&fullPath);
ExFreePoolWithTag(fullPath.Buffer,PROCESS_FULLPATH); //在将进程全路径赋值给要保存的消息后将内存释放
RtlAppendUnicodeToString(&logListNode->msg,L";");
RtlAppendUnicodeStringToString(&logListNode->msg,&nameInfo->Name);
RtlAppendUnicodeStringToString(&logListNode->msg,&tmpTail);
//KdPrint(("&logListNode->msg = %wZ\n",&logListNode->msg));
InsertTailList(&logListHeader,&logListNode->listNode);//插入队尾
KeSetEvent(&s_Event,IO_NO_INCREMENT,FALSE);
}
FltReleaseFileNameInformation( nameInfo );
}
}//else
}//判断是否是文件夹
}//__try
__except(EXCEPTION_EXECUTE_HANDLER) {
DbgPrint("NPPreCreate EXCEPTION_EXECUTE_HANDLER\n");
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
FLT_PREOP_CALLBACK_STATUS
preWrite(
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
NTSTATUS status;
PFLT_FILE_NAME_INFORMATION nameInfo;
UNICODE_STRING Directory_Of_Bait_files;
UNICODE_STRING log_msg;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
PAGED_CODE();
//检查中断级
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
__try {
//判断是否文件夹
BOOLEAN isDir;
status = FltIsDirectory(FltObjects->FileObject,FltObjects->Instance,&isDir);
if (NT_SUCCESS(status))
{
//文件夹直接跳过
if (isDir)
{
return FLT_PREOP_SUCCESS_NO_CALLBACK; //是文件夹直接返回失败
}
else
{
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo );
if (NT_SUCCESS( status ))
{
FltParseFileNameInformation( nameInfo );
RtlInitUnicodeString( &Directory_Of_Bait_files, L"\\Device\\HarddiskVolume3\\");
if (RtlPrefixUnicodeString(&Directory_Of_Bait_files,&nameInfo->Name,TRUE))
{
//进入了我想要监控的目录
PEPROCESS obProcess = NULL;
HANDLE hProcess;
UNICODE_STRING fullPath;
obProcess = IoThreadToProcess(Data->Thread);
hProcess = PsGetProcessId(obProcess);
fullPath.Length = 0;
fullPath.MaximumLength = 520;
fullPath.Buffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool,520,PROCESS_FULLPATH);
if (fullPath.Buffer == NULL)
{
FltReleaseFileNameInformation( nameInfo );
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
status = GetProcessImageName(hProcess,&fullPath);
if (!NT_SUCCESS(status))
{
FltReleaseFileNameInformation( nameInfo );
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
UNICODE_STRING tmpTail;
RtlInitUnicodeString( &tmpTail, L";\r\n"); //用来结尾
ULONG len = fullPath.MaximumLength + nameInfo->Name.MaximumLength + tmpTail.MaximumLength;
PLOG_LIST logListNode;
logListNode = (PLOG_LIST)ExAllocatePool(NonPagedPool,sizeof(LOG_LIST));
if (logListNode == NULL)
{
KdPrint(("队列申请失败 \n"));
}
logListNode->msg.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, len, LOG_MSG);
logListNode->msg.Length = 0;
logListNode->msg.MaximumLength = len;
RtlAppendUnicodeStringToString(&logListNode->msg,&fullPath);
ExFreePoolWithTag(fullPath.Buffer,PROCESS_FULLPATH); //在将进程全路径赋值给要保存的消息后将内存释放
RtlAppendUnicodeToString(&logListNode