微过滤驱动主要用于安全隔离盒累产品,通过收集资料,和各位高手的文章,具有参考意义的的文章主要输入下
看雪论套:https://bbs.pediy.com/thread-226174.htm
是一篇很有质量的文章,基本逻辑已经实现,入门级的如何新建工程,编译,签名与安装,可以参考其他教程,这里只把实践重遇到的问题进行总结与给出解决方案。现在先总结问题:
问题1:设置为保护,仍然可以删除文件和目录;
问题2、保护状态仍然可以通过鼠标右键新建文件夹与其他文件,只是内容为空,0字节大小;
问题3、发现目录重第一个文件无法隐藏;
解决方法:
问题1、对IRP_MJ_SET_INFORMATION与IRP_MJ_CREATE 的pre过程监听,参考了如下文章
https://www.cnblogs.com/lsh123/archive/2004/01/13/10405002.html
但需要坐下改进代码如:
FLT_PREOP_CALLBACK_STATUS SafeUsbFilterPreDelete(_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID *CompletionContext)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();//PreCallback的IRQL应当<= APC_LEVEL
FILE_DISPOSITION_INFORMATION fdi;
FLT_PREOP_CALLBACK_STATUS Status = FLT_PREOP_SUCCESS_NO_CALLBACK;//不再调用postoperation callback routine,
ULONG ulDisposition = 0;
BOOLEAN IsDirectory = FALSE;//目录操作跳过,不管
NTSTATUS status = FltIsDirectory(FltObjects->FileObject, FltObjects->Instance, &IsDirectory);
if (NT_SUCCESS(status)) {
if (IsDirectory == TRUE) {
//return Status;
}
}
if (Data->Iopb->MajorFunction == IRP_MJ_CREATE) {
if (!FlagOn(Data->Iopb->Parameters.Create.Options, FILE_DELETE_ON_CLOSE)) {
ulDisposition = (Data->Iopb->Parameters.Create.Options >> 24) & 0xFF;
if (ulDisposition == FILE_CREATE || ulDisposition == FILE_OVERWRITE || ulDisposition == FILE_OVERWRITE_IF)
{
fdi.DeleteFile = TRUE;
//FltSetInformationFile(FltObjects->Instance, FltObjects->FileObject, &fdi, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation);
//FltCancelFileOpen(FltObjects->Instance, FltObjects->FileObject);
if (gReadOnly == TRUE)
{
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
Status = FLT_PREOP_COMPLETE;
}
}
return Status;
}
}
if (Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) {
switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass) {
case FileRenameInformation:
case FileRenameInformationEx:
case FileDispositionInformation:
case FileDispositionInformationEx:
case FileRenameInformationBypassAccessCheck:
case FileRenameInformationExBypassAccessCheck:
case FileShortNameInformation:
break;
default:
return Status;
}
}
PFLT_FILE_NAME_INFORMATION FileNameInfo = NULL;
if (FltObjects->FileObject != NULL) {
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);
if (NT_SUCCESS(status)) {
FltParseFileNameInformation(FileNameInfo);
//if (RtlCompareUnicodeString(&FileNameInfo->Name, &Protected, TRUE) == 0) {
//if (RtlCompareUnicodeString(&FileNameInfo->Extension, &Protected, TRUE) == 0)
if (gReadOnly == TRUE)
{
DbgPrint("===========Protecting file deletion/rename! filenamelength ==========");
DbgPrint("%wZ\n", &(FileNameInfo->Name));
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
Status = FLT_PREOP_COMPLETE;
}
// Clean up file name information.
FltReleaseFileNameInformation(FileNameInfo);
}
}
return Status;
问题2
参考http://bbs3.driverdevelop.com/read.php?tid=90996
但是需要改进,不是处理Post,仍然是Pre代码已经在问题1重,对if (ulDisposition == FILE_CREATE || ulDisposition == FILE_OVERWRITE || ulDisposition == FILE_OVERWRITE_IF)进行拦截;
问题3:参考https://www.oschina.net/code/piece_full?code=43729
改问题比较特殊,网上只找对对目录隐藏的处理方式,但不足以满足需求,且在时间过程中发现 IRP_MJ_CREATE 的Post函数始终未执行,还是IRP_MJ_DIRECTORY_CONTROL中隐藏逻辑代码中做特殊处理,根据看雪轮胎网友代码中previousFileInfo = currentFileInfo;//保存下来是有问题的,始终无法处理第一个文件隐藏问题,最后参考了该链接方式,把该因此的文件类型强制改为系统不显示的类型,问题解决。
解决以上三个问题后,一个完整的存储过滤器安全防护类产品通过微软的微滤器完美实现。