0x01 思路(原理)

  驱动层文件保护的思路是通过minifilter过滤文件删除相关的IRP,并将目标文件与被保护文件相比较,命中保护规则的话返回STATUS_ACCESS_DENIED拒绝访问;也可以进一步利用回调函数获取的FLT_CALLBACK_DATA结构体解析文件删除操作对应的发起者进程,与白名单进程(允许执行删除操作的进程)相比较。

  需要过滤的IRP类型:IRP_MJ_SET_INFORMATION与IRP_MJ_CREATE(或还有其他类型IRP需要过滤,尚未知)

IRP_MJ_SET_INFORMATION的产生原因一般是请求设置文件属性等等,比如ZwSetInformationFile函数可以发起此IRP.这里顺带说一句的是,许多驱动都用ZwSetInformationFile函数来实现强删文件的,比如腾讯电脑管家中的TSSysKit.sys驱动中文件穿透操作的删除文件就是调用ZwSetInformationFile函数将FileInformationClass设为FileDispositionInformation且((PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->DeleteFile设为TRUE来达到删除文件的目的(如果是强删正在运行的文件,那么还需将文件对象的SectionObjectPointer->ImageSectionObject和 SectionObjectPointer->DataSectionObject 两个字段置零)。因此,对于IRP_MJ_SET_INFORMATION,应当检查FileInformationClass是否是FileRenameInformation和FileShortNameInformation标志。

  IRP_MJ_CREATE的产生原因一般是请求打开文件句柄,文件对象以及其他内核对象等等,比如ZwCreateFile函数可以发起此IRP.如果ZwCreateFile函数指定了FILE_DELETE_ON_CLOSE标志,那么当最后一个文件句柄被NtClose关闭时,文件会被删除,这也就是过滤IRP_MJ_CREATE的原因。因此,对于IRP_MJ_CREATE,应当检查是否有FILE_DELETE_ON_CLOSE 标志指定。

0x01 源码及注释如下

 #include <fltKernel.h>
//#include "FileDeleteProtect.h" #define DEBUG
#ifdef DEBUG
#define DBG_PRINTF(_fmt, ...) DbgPrint(_fmt, __VA_ARGS__)
#else
#define DBG_PRINTF(_fmt, ...) { NOTHING; }
#endif DRIVER_INITIALIZE DriverEntry; NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath);
NTSTATUS Unload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags);
FLT_PREOP_CALLBACK_STATUS PreAntiDelete(_Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext); //过滤IRP的回调数组
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
{ IRP_MJ_CREATE, , PreAntiDelete, NULL }, // DELETE_ON_CLOSE 标志.
{ IRP_MJ_SET_INFORMATION, , PreAntiDelete, NULL }, // FileDispositionInformation(Ex).
{ IRP_MJ_OPERATION_END }
}; CONST FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION), // Size
FLT_REGISTRATION_VERSION, // Version
, // Flags
NULL, // ContextRegistration
Callbacks, // OperationRegistration
Unload, // FilterUnloadCallback
NULL, // InstanceSetupCallback
NULL, // InstanceQueryTeardownCallback
NULL, // InstanceTeardownStartCallback
NULL, // InstanceTeardownCompleteCallback
NULL, // GenerateFileNameCallback
NULL, // NormalizeNameComponentCallback
NULL // NormalizeContextCleanupCallback
}; PFLT_FILTER Filter;
static UNICODE_STRING Protected = RTL_CONSTANT_STRING(L"EXE"); NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER(RegistryPath); NTSTATUS Status = FltRegisterFilter(DriverObject, &FilterRegistration, &Filter);
if (!NT_SUCCESS(Status)) {
DBG_PRINTF("Failed to register filter: <0x%08x>.\n", Status);
return Status;
} Status = FltStartFiltering(Filter);
if (!NT_SUCCESS(Status)) {
DBG_PRINTF("Failed to start filter: <0x%08x>.\n", Status);
FltUnregisterFilter(Filter);
} return Status;
} NTSTATUS Unload(_In_ FLT_FILTER_UNLOAD_FLAGS Flags) {
UNREFERENCED_PARAMETER(Flags);
DBG_PRINTF("Unload called.\n");
FltUnregisterFilter(Filter); return STATUS_SUCCESS;
} /*
* PreCallback的调用时机
* IRP_MJ_CREATE——ZwCreateFile
* IRP_MJ_SET_INFORMATION——ZwSetInformation.
*/
FLT_PREOP_CALLBACK_STATUS PreAntiDelete(_Inout_ PFLT_CALLBACK_DATA Data, _In_ PCFLT_RELATED_OBJECTS FltObjects, _Flt_CompletionContext_Outptr_ PVOID *CompletionContext) {
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();//PreCallback的IRQL应当<= APC_LEVEL FLT_PREOP_CALLBACK_STATUS Status = FLT_PREOP_SUCCESS_NO_CALLBACK;//不再调用postoperation callback routine, BOOLEAN IsDirectory;//目录操作跳过,不管
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)) {
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;
}
} /*
ZwCreateFile和ZwSetInformation函数都是运行在PASSIVE_LEVEL的,所以当前的线程上下文
应当就是ZwCreateFile或ZwSetInformation函数的调用者进程对应的线程的上下文Context,
所以这里可以判断调用者进程是否在白名单中(如果存在白名单进程的话)
if (IoThreadToProcess(Data->Thread) == WhiteListProcess) {
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
*/ 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) == ) {
DBG_PRINTF("Protecting file deletion/rename!");
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = ;
Status = FLT_PREOP_COMPLETE;
}
// Clean up file name information.
FltReleaseFileNameInformation(FileNameInfo);
}
} return Status;
}

文件防删除保护(miniifiter)的更多相关文章

  1. 简单HOOK SSDT实现文件防删除

    http://www.rosoo.net/a/201001/8347.html

  2. Git学习笔记(3)——撤销修改和文件的删除

    本文主要记录了git中,错误的撤销和文件的删除. 撤销修改 这里有3中情况 改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file. 不但改乱了工作区某个 ...

  3. LINUX运维实战案例之文件已删除但空间不释放问题的分析与解决办法

    1.错误现象 运维的监控系统发来通知,报告一台服务器空间满了,登陆服务器查看,根分区确实没有空间了,如下图所示: 这里首先说明一下服务器的一些删除策略,由于Linux没有回收站功能,我们的线上服务器所 ...

  4. [WinAPI] API 9 [文件的删除、复制和移动功能]

    Windows系统为文件的删除.复制.重命名或移动文件提供了相应的API函数.删除文件使用DeleteFile函数:复制文件使用CopyFile函数:重命名文件和移动文件实际是一个操作,使用MoveF ...

  5. Linux大文件已删除,但df查看已使用的空间并未减少解决

    在我的生活当中遇到磁盘快满了,这时候准备去删除一些大文件 于是我使用ncdu 查看了一下当前系统占用资源比较多的是那些文件,结果一看是elasticsearch的日志文件,好吧,竟然找到源头了,那就把 ...

  6. Mac下关于——你不能拷贝项目“”,因为它的名称太长或包括的字符在目的宗卷上无效。文件的删除

    内容是google的,测试有效,因为用revel打包的东西删除以后有这个循环bug Mac下关于——你不能拷贝项目“”,因为它的名称太长或包括的字符在目的宗卷上无效.文件的删除 关于这个问题我找到的一 ...

  7. DLL文件无法删除怎么解决

    dll文件你听说过吗?那怎样把那些删不掉的东西删掉呢?请看.... 老听网友说某某文件删不掉啊.之类的.而且有很多都是dll文件.删除的时候总是提示,"正在使用"或者是" ...

  8. C#结合js 上传文件和删除文件(技术点有:asp.net mvc ,nhibernate,ajax等)

    之前做项目的时候要用到上传文件的功能,现在我总结一下,上传文件和删除文件的代码,在以后的使用的过程中也更方便查找. [HttpPost] public ActionResult EditUser() ...

  9. ASP FSO操作文件(复制文件、重命名文件、删除文件、替换字符串)

    ASP FSO操作文件(复制文件.重命名文件.删除文件.替换字符串)FSO的意思是FileSystemObject,即文件系统对象.FSO对象模型包含在Scripting 类型库 (Scrrun.Dl ...

随机推荐

  1. java四则运算 界面化

    本次作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2232 项目的地址:https://github.com/kdays ...

  2. jQuery初识、函数、对象

    初识jQuery 官方地址:http://jquery.com/ what:一个优秀的JS函数库(封装了BOM.DOM(主要)) why: HTML元素选取(选择器) HTML元素操作 CSS操作 H ...

  3. 工具类封装之--CommonUtils

    /** * @file_name : CommonUtils.java * @author : * @date : 2018年3月15日 * Description: */ package cn.xx ...

  4. Vue-admin工作整理(十六):Ajax-axios进行请求封装+拦截器

    典型的工具类封装,增加拦截起来做相应的处理 user.js: import axios from './index' export const getUserInfo = ({ userId }) = ...

  5. Valotile关键字详解

    在了解valotile关键字之前.我们先来了解其他相关概念. 1.1  java内存模型: 不同的平台,内存模型是不一样的,我们可以把内存模型理解为在特定操作协议下,对特定的内存或高速缓存进行读写访问 ...

  6. _spellmod_aura_pct

    属性光环 为玩家增加光环或降低属性 `aura`光环ID `auraType1` 配置属性('空','生命值','全属性','近战攻击强度','远程攻击强度','法术强度','治疗效果','施法速度' ...

  7. php日志

    // 全局通用日志工具 function setlog($param = [],$result = [],$name='',$filename = 'm.log',$path = '/tmp/bear ...

  8. JS-NaN的数据类型

    NaN 的数据类型:not a number .是数字类型但是不是数字 例: var x = Number('abcd'); //结果是NaN alert( typeof (x) ); //结果是nu ...

  9. sysbench工具安装使用

    一.sysbench简介 Sysbench是一款开源的.跨平台的.模块化的.多线程的性能测试工具,通过高负载地运行在数据库上,可以执行CPU.内存.线程.IO.数据库等方面的性能测试.用于评估操作系统 ...

  10. vs.net2015发布web网站时,提示JsonIgnoreAttribute无法找到的解决办法

    产生该问题的原因是因为项目中引用了两个版本的newtonsoft.json.dll,具体解决办法参见: 用记事本打开项目文件(*.csproj) 可以找到在这个文件中,有两处Newtonsoft.Js ...