MiniFilter实现硬链接和软链接监控
对于MiniFilter监控软链接和硬链接这块的资料还是挺少的。
这里整理并实现了以下功能:
#include <fltKernel.h>
PFLT_FILTER gFilterHandle = NULL;
FLT_POSTOP_CALLBACK_STATUS FsFilterPostSetInformation(
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
FILE_INFORMATION_CLASS Class =
Data->Iopb->Parameters.SetFileInformation.FileInformationClass;
PFILE_RENAME_INFORMATION pRenameInfo = (PFILE_RENAME_INFORMATION)
Data->Iopb->Parameters.SetFileInformation.InfoBuffer;
PFLT_FILE_NAME_INFORMATION pSrcNameInfo = NULL;
PFLT_FILE_NAME_INFORMATION pLinkNameInfo = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
if (Class == FileLinkInformation)
{
Status = FltGetFileNameInformation(
Data,
FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
&pSrcNameInfo
);
if (!NT_SUCCESS(Status))
{
goto END;
}
Status = FltParseFileNameInformation(pSrcNameInfo);
if (!NT_SUCCESS(Status))
{
goto END;
}
Status = FltGetDestinationFileNameInformation(
FltObjects->Instance,
Data->Iopb->TargetFileObject,
pRenameInfo->RootDirectory,
pRenameInfo->FileName,
pRenameInfo->FileNameLength,
FLT_FILE_NAME_NORMALIZED,
&pLinkNameInfo
);
if (!NT_SUCCESS(Status))
{
goto END;
}
KdPrint(("[HardLink] FilePath:%S, HardLink:%S\n",
pSrcNameInfo->Name.Buffer, pLinkNameInfo->Name.Buffer));
}
END:
if (pSrcNameInfo != NULL)
{
FltReleaseFileNameInformation(pSrcNameInfo);
}
if (pLinkNameInfo != NULL)
{
FltReleaseFileNameInformation(pLinkNameInfo);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}
FLT_POSTOP_CALLBACK_STATUS FsFilterPostFileSystemControl(
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags
)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PWCHAR pwzFilePath = NULL;
PFLT_FILE_NAME_INFORMATION NameInfo = NULL;
ULONG FsControlCode = Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode;
if (FsControlCode == FSCTL_SET_REPARSE_POINT)
{
ULONG InputBufferLength = Data->Iopb->Parameters.FileSystemControl.Neither.InputBufferLength;
if (InputBufferLength == sizeof(REPARSE_GUID_DATA_BUFFER) ||
InputBufferLength > MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
{
goto END;
}
PREPARSE_DATA_BUFFER DataBuffer = Data->Iopb->Parameters.FileSystemControl.Neither.InputBuffer;
if (DataBuffer == NULL)
{
goto END;
}
PUCHAR pPathBuffer = NULL;
USHORT uNameOffset = 0;
USHORT uNameLength = 0;
if (DataBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
pPathBuffer = (PUCHAR)DataBuffer->SymbolicLinkReparseBuffer.PathBuffer;
uNameOffset = DataBuffer->SymbolicLinkReparseBuffer.PrintNameOffset;
uNameLength = DataBuffer->SymbolicLinkReparseBuffer.PrintNameLength;
}
else if (DataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
pPathBuffer = (PUCHAR)DataBuffer->MountPointReparseBuffer.PathBuffer;
uNameOffset = 0;
uNameLength = DataBuffer->MountPointReparseBuffer.SubstituteNameLength;
}
else
{
goto END;
}
pwzFilePath = ExAllocatePoolWithTag(NonPagedPool, uNameLength + sizeof(WCHAR), 'TAG_');
if (pwzFilePath == NULL)
{
goto END;
}
RtlCopyMemory(pwzFilePath, pPathBuffer + uNameOffset, uNameLength);
pwzFilePath[uNameLength / 2] = L'\0';
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = FltGetFileNameInformation(
Data,
FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
&NameInfo
);
if (!NT_SUCCESS(Status))
{
goto END;
}
Status = FltParseFileNameInformation(NameInfo);
if (!NT_SUCCESS(Status))
{
goto END;
}
KdPrint(("[SymboLink] FilePath:%S, SymbolicPath:%S\n", pwzFilePath, NameInfo->Name.Buffer));
}
END:
if (pwzFilePath != NULL)
{
ExFreePool(pwzFilePath);
}
if (NameInfo != NULL)
{
FltReleaseFileNameInformation(NameInfo);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}
CONST FLT_OPERATION_REGISTRATION Callbacks[] =
{
{
IRP_MJ_SET_INFORMATION,
0,
NULL,
FsFilterPostSetInformation
},
{
IRP_MJ_FILE_SYSTEM_CONTROL,
0,
NULL,
FsFilterPostFileSystemControl
},
{
IRP_MJ_OPERATION_END
}
};
NTSTATUS
FsFilterUnload(
_In_ FLT_FILTER_UNLOAD_FLAGS Flags
)
{
FltUnregisterFilter(gFilterHandle);
return STATUS_SUCCESS;
}
CONST FLT_REGISTRATION FilterRegistration =
{
sizeof(FLT_REGISTRATION),
FLT_REGISTRATION_VERSION,
0,
NULL,
Callbacks,
FsFilterUnload,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
KdPrint(("DriverEntry\n"));
NTSTATUS Status = STATUS_SUCCESS;
Status = FltRegisterFilter(
DriverObject,
&FilterRegistration,
&gFilterHandle);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = FltStartFiltering(gFilterHandle);
if (!NT_SUCCESS(Status))
{
FltUnregisterFilter(gFilterHandle);
}
return Status;
}
测试:
// 创建硬链接
mklink /h xxHardLink xxx.txt
// 创建软链接
mklink /d xxSymbolLink xxx.txt
发表回复
要发表评论,您必须先登录。