[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

时间:2022-09-25 11:06:48

转载:http://blog.csdn.net/C0ldstudy/article/details/51585708

转载:http://blog.csdn.net/zj510/article/details/39344889

转载:http://blog.csdn.net/zj510/article/details/39345479

转载:http://www.cnblogs.com/js2854/archive/2010/11/03/HideDir.html

转载:http://blog.csdn.net/Z18_28_19/article/details/12979743

转载:https://bbs.pediy.com/thread-192118.htm

转载:http://blog.csdn.net/u013761036/article/details/63254697

转载:http://www.cnblogs.com/js2854/archive/2011/04/03/sysload.html

转载:http://www.cnblogs.com/huangyong9527/archive/2012/09/07/2674720.html

转载:http://blog.csdn.net/xum2008/article/details/5634903

一.环境配置

VS2012 + WDK 8.0

WDK下载地址:https://developer.microsoft.com/zh-cn/windows/hardware/windows-driver-kit

二.安装WDK

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

这样WDK就集成到VS里面

三.创建文件过滤驱动工程

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

建立工程后,首先会有两个工程,一个就是驱动工程,另外一个是package工程(这个是测试驱动安装的一个工程,对于我们来说其实没有什么用处,反正本人是没有使用过得,可以直接删除)。

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

NTSTATUS DriverEntry (_In_ PDRIVER_OBJECT DriverObject,_In_ PUNICODE_STRING RegistryPath),这个类似C语言里面的main函数,这是驱动内核的入口函数

DriverEntry函数中,通过FltRegisterFilter注册一个微过滤器;另一个是用FltStartFiltering开始过滤。FltRegisterFilter函数通过输入驱动对象和注册信息的结构返回微过滤器句柄,而FltStartFiltering函数实现开启过滤功能

NTSTATUS
DriverEntry (
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
PSECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
UNREFERENCED_PARAMETER( RegistryPath ); //向过滤管理器注册一个过滤器
status = FltRegisterFilter( DriverObject,
&FilterRegistration,
&gFilterHandle ); ASSERT( NT_SUCCESS( status ) );
//开启过滤行为
if (NT_SUCCESS( status )) {
status = FltStartFiltering( gFilterHandle );
//如果开启失败,取消注册
if (!NT_SUCCESS( status )) {
FltUnregisterFilter( gFilterHandle );
}
}
status=FltBuildDefaultSecurityDescriptor(&sd,FLT_PORT_ALL_ACCESS);
RtlInitUnicodeString( &uniString, MINISPY_PORT_NAME ); InitializeObjectAttributes( &oa,
&uniString,
OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
NULL,
sd );
FltFreeSecurityDescriptor( sd );
return status;
}

在注册过滤器时,使用了微过滤器注册结构,也就是FLT_REGISTRATION。

CONST FLT_REGISTRATION FilterRegistration = {

    sizeof( FLT_REGISTRATION ),         //  Size
FLT_REGISTRATION_VERSION, // Version
, // Flags NULL, // Context
Callbacks, // Operation callbacks MyMiniFilterUnload, // MiniFilterUnload MyMiniFilterInstanceSetup, // InstanceSetup
MyMiniFilterInstanceQueryTeardown, // InstanceQueryTeardown
MyMiniFilterInstanceTeardownStart, // InstanceTeardownStart
MyMiniFilterInstanceTeardownComplete, // InstanceTeardownComplete NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent };

CallBacks最为重要,这是一个回调函数组,其中可以处理各种请求。请求过滤分为2种:请求完成之前操作和等待请求完成之后操作,分别在预操作回调和后操作回调函数中。CallBacks回调函数数组如下:

当系统接收到标识为IRP_MJ_CREATE的IPR也就是试图生成或者打开文件时,自然就会调用到预操作函数与后操作函数。

我们启用一个Write的过滤,如:

CONST FLT_OPERATION_REGISTRATION Callbacks[] = {

    { IRP_MJ_WRITE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation },
#if 0 // TODO - List all of the requests to filter.
{ IRP_MJ_CREATE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_CREATE_NAMED_PIPE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_CLOSE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_READ,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_WRITE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_QUERY_INFORMATION,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_SET_INFORMATION,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_QUERY_EA,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_SET_EA,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_FLUSH_BUFFERS,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_QUERY_VOLUME_INFORMATION,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_SET_VOLUME_INFORMATION,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_DIRECTORY_CONTROL,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_FILE_SYSTEM_CONTROL,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_DEVICE_CONTROL,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_INTERNAL_DEVICE_CONTROL,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_SHUTDOWN,
,
MyMiniFilterPreOperationNoPostOperation,
NULL }, //post operations not supported { IRP_MJ_LOCK_CONTROL,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_CLEANUP,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_CREATE_MAILSLOT,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_QUERY_SECURITY,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_SET_SECURITY,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_QUERY_QUOTA,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_SET_QUOTA,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_PNP,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_ACQUIRE_FOR_MOD_WRITE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_RELEASE_FOR_MOD_WRITE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_ACQUIRE_FOR_CC_FLUSH,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_RELEASE_FOR_CC_FLUSH,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_NETWORK_QUERY_OPEN,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_MDL_READ,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_MDL_READ_COMPLETE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_PREPARE_MDL_WRITE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_MDL_WRITE_COMPLETE,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_VOLUME_MOUNT,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, { IRP_MJ_VOLUME_DISMOUNT,
,
MyMiniFilterPreOperation,
MyMiniFilterPostOperation }, #endif // TODO { IRP_MJ_OPERATION_END }
};

预操作回调函数:MyMiniFilterPreOperation函数第一个参数是回调数据包的指针,其中包含这个请求相关的全部信息。

FLT_PREOP_CALLBACK_STATUS
MyMiniFilterPreOperation (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID *CompletionContext
)
{
char FileName[] = "X:";//记录文件名
char FilePath[] = "Y:";//记录相对路径(ParentDir)
char Ext[] = "Z:";//记录扩展名
NTSTATUS status;
UNICODE_STRING uniString;
PEPROCESS pEprocess = ;
PUNICODE_STRING uSProcessPath = NULL; PFLT_FILE_NAME_INFORMATION nameInfo;
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
PAGED_CODE();
__try {
status = FltGetFileNameInformation( Data,FLT_FILE_NAME_NORMALIZED|FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo );
if (NT_SUCCESS( status )) {
//DbgPrint("进入了\r\n");
FltParseFileNameInformation( nameInfo );
if (NPUnicodeStringToChar(&nameInfo->Name, FileName)) {
if (NPUnicodeStringToChar(&nameInfo->ParentDir, FilePath)){
//输出文件名及相对路径
DbgPrint("文件名:%s\r\n",FileName);
DbgPrint("文件路径:%s\r\n",FilePath);
//输出扩展名
NPUnicodeStringToChar(&nameInfo->Extension,Ext);
DbgPrint("文件扩展名:%s\r\n",Ext); //
pEprocess = Data->Thread ? IoThreadToProcess(Data->Thread) : PsGetCurrentProcess();
//uSProcessPath = PsGetProcessFullName(pEprocess);//这里需要释放UNICODESTRING 的内存 GetSeLocateProcessImageName(pEprocess,&uSProcessPath);
DbgPrint("ProcFullName : %wZ\n", uSProcessPath); //判断文件路径或名字是否符合要求,若是满足要求则拒绝访问
if (strstr(FileName, "txt") > ) {
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = ;
FltReleaseFileNameInformation( nameInfo );
return FLT_PREOP_COMPLETE;
}
} FltReleaseFileNameInformation( nameInfo );
}
}}
__except(EXCEPTION_EXECUTE_HANDLER) {
DbgPrint("NPPreCreate EXCEPTION_EXECUTE_HANDLER\n");
}
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

在预操作函数里,我用到NPUnicodeStringToChar函数和GetSeLocateProcessImageName,在此一并贴出来

BOOLEAN NPUnicodeStringToChar(PUNICODE_STRING UniName, char Name[])
{
ANSI_STRING AnsiName;
NTSTATUS ntstatus;
char* nameptr; __try {
ntstatus = RtlUnicodeStringToAnsiString(&AnsiName, UniName, TRUE); if (AnsiName.Length < ) {
nameptr = (PCHAR)AnsiName.Buffer;
//Convert into upper case and copy to buffer
//strcpy(Name, _strupr(nameptr)); //将字符串转换成大写形式
strcpy(Name,_strlwr(nameptr));//讲字符串转换成小写形式
DbgPrint("NPUnicodeStringToChar : %s\n", Name);
}
RtlFreeAnsiString(&AnsiName);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DbgPrint("NPUnicodeStringToChar EXCEPTION_EXECUTE_HANDLER\n");
return FALSE;
}
return TRUE;
} //获取进程全路径
PUNICODE_STRING GetSeLocateProcessImageName(PEPROCESS Process,PUNICODE_STRING *pImageFileName)
{
POBJECT_NAME_INFORMATION pProcessImageName = NULL;
PUNICODE_STRING pTempUS = NULL;
ULONG NameLength = ;
//Process->SeAuditProcessCreationInfo.ImageFileName->Name
//win7 x86 offset = 0x1ec
//if (NULL == Process->SeAuditProcessCreationInfo.ImageFileName)
pProcessImageName = (POBJECT_NAME_INFORMATION)(*(ULONG*)((ULONG)Process + 0x1ec));
if(pProcessImageName == NULL)
{
DbgPrint("Process->SeAuditProcessCreationInfo.ImageFileName == NULL \n");
return NULL;
}
else
{
NameLength = sizeof(UNICODE_STRING) + pProcessImageName->Name.MaximumLength;
pTempUS = ExAllocatePoolWithTag( NonPagedPool, NameLength, 'aPeS' );
if (NULL != pTempUS) { RtlCopyMemory(
pTempUS,
&pProcessImageName->Name,
NameLength
); pTempUS->Buffer = (PWSTR)(((PUCHAR) pTempUS) + sizeof(UNICODE_STRING));
*pImageFileName = pTempUS;
DbgPrint("Path:%wZ\n",&pProcessImageName->Name);
return *pImageFileName;
}
return NULL;
} }

后操作回调函数:在一般的情况下,后操作回调函数在文件新建不成功的时候取消之前的操作,本次项目中没有相关实践,就没有做过多的修改和研究。

FLT_POSTOP_CALLBACK_STATUS
MiniFilterPostOperation (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
{
UNREFERENCED_PARAMETER( Data );
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( CompletionContext );
UNREFERENCED_PARAMETER( Flags ); PT_DBG_PRINT( PTDBG_TRACE_ROUTINES,
("MiniFilter!MiniFilterPostOperation: Entered\n") ); return FLT_POSTOP_FINISHED_PROCESSING;
}

好了,选择Win 7 Debug直接编译。

然后。。。。  报错了,没有关系,查看出错原因,无外乎一些警告被当做错误,或者一些函数参数没有被使用,导致编译不过,这些都是因为安全警告等级太高了,我们的解决方法:

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

然后把MyMinifilter.inf和MyMiniFilter.sys考到虚拟机上。注意VS2012不支持了XP了,所以我们找一个win7 32位虚拟机。因为win7 64位虚拟机需要签名,为了省去签名这一步,先用win7 32位

右键点击inf文件安装。之后运行cmd,(注意需要用Administrator运行)。输入命令sc start myminifilter

这样就可以把minifilter驱动起来。

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

我们需要查看驱动运行过程的打印信息,用DebugView这个软件。

用Administrator运行DebugView(注意勾上Enable verbose kernel output)这样我们用start,stop命令的时候就可以看到一下log

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

可是实际情况却没有看到log。这个是因为inf文件需要稍微改一下。

修改inf文件

现在暂时只需要修改Altitude,看下图,其实就是把注释掉的代码启用。

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

再次安装驱动运行驱动服务,用记事本打开一个txt文本

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

可见阻止txt格式的文件打开了。

后记:当下次打开虚拟机时,发现驱动不拦截了,原来是我驱动开始类型默认是SERVICE_DEMAND_START,这种是按需启动的驱动程序

SERVICE_SYSTEM_START 是随着操作系统启动而启动,如果想要驱动下次系统启动还生效,可以选择这种类型。

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问

[内核驱动] VS2012+WDK 8.0 Minifilter实现指定扩展名文件拒绝访问的更多相关文章

  1. ASP&period;NET MVC 4&period;0中选择Windows 验证默认出错拒绝访问的原因和解决方案

    在VS 2012或者2013 中,根据模板创建一个ASP.NET MVC 4.0的应用程序,选择下面的模板 然后选择Intranet Application 不对源代码做任何修改,直接按下F5调试,会 ...

  2. 编译器错误消息&colon; CS0016&colon; 未能写入输出文件&OpenCurlyDoubleQuote;c&colon;&sol;Windows&sol;Microsoft&period;NET&sol;Framework&sol;v4&period;0&period;50727&sol;Temporary ASP&period;NET Files&sol;root &period;&period;&period;&period; 拒绝访问。

    此问题困扰良久,得终极解决方案 环境:windows 2008 server r2 + iis7 + .net framework4.5 解决:1. 错误信息中包含的目录“c:/Windows/Mic ...

  3. 【转载】错误 CS0016&colon; 未能写入输出文件&OpenCurlyDoubleQuote;c&colon;&sol;WINDOWS&sol;Microsoft&period;NET&sol;Framework&sol;v2&period;0&period;50727&sol;Temporary ASP&period;NET Files&sol;&period;&period;&period;&period;&period;&period;&period;&period;&period;dll”--&OpenCurlyDoubleQuote;拒绝访问。 ”

    win7中安装asp.net的问题 编译器错误信息: CS0016: 未能写入输出文件问题解决办法 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地 ...

  4. Windows内核驱动中操作文件

    本页主题:如何在windows内核驱动中对文件操作,实现对文件的拷贝.粘贴.删除.查询信息等,这是很常用也是很简单的方法. 部分内容参考:http://www.cppblog.com/aurain/a ...

  5. Windows内核驱动开发:HelloWorld

    测试信息 Dev Machine: Windows Version: 2004 (19041.264) WDK Version: 10.0.19041.1 SDK Version: 10.0.1904 ...

  6. 驱动开发学习笔记&period; 0&period;06 嵌入式linux视频开发之预备知识

    驱动开发读书笔记. 0.06  嵌入式linux视频开发之预备知识 由于毕业设计选择了嵌入式linux视频开发相关的项目,于是找了相关的资料,下面是一下预备知识 UVC : UVC,全称为:USB v ...

  7. 驱动开发学习笔记&period; 0&period;05 linux 2&period;6 platform device register 平台设备注册 2&sol;2 共2篇

    驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇 下面这段摘自 linux源码里面的文档 : 内核版本2.6.22Doc ...

  8. 驱动开发学习笔记&period; 0&period;04 linux 2&period;6 platform device register 平台设备注册 1&sol;2 共2篇

    驱动开发读书笔记. 0.04  linux 2.6 platform device register 平台设备注册  1/2 共2篇下面这段摘自 linux源码里面的文档 : Documentatio ...

  9. 驱动开发学习笔记&period; 0&period;02 基于EASYARM-IMX283 烧写uboot和linux系统

    驱动开发读书笔记. 0.02 基于EASYARM-IMX283 怎么烧写自己裁剪的linux内核?(非所有arm9通用) 手上有一块tq2440,但是不知道什么原因,没有办法烧boot进norflas ...

随机推荐

  1. tp框架实现ajax

    不墨迹,直接进主题. tp框架实现ajax 首先,我们先做一个testajax.html用来显示页面(只是一个简单的下拉列表^_^) <!DOCTYPE html PUBLIC "-/ ...

  2. JS调用中文乱码怎么办

    网络上有很多的实用的小插件,这些小插件可以直接拿过来实用即可,但是在使用的时候会出现很多的问题,就比如与说今天要讲的乱码中文乱码的问题,这个主要是因为我们调用的js和我们写的程序使用的编码不同,那么如 ...

  3. excel 作图中次横坐标及次纵坐标的调试,以及excel自定义轴标签的步骤方法

    在工作中除了要做一些常用的图表之外,不时还会有一切奇怪图表的制作需求. 今天的内容主要记录的是如何对excle图表的次横坐标及次纵坐标进行调试,以及如何自定义调整轴标签 首先看下如何做次纵坐标,工作中 ...

  4. 在vs中跑动ransac

    期间遇到很多问题. 记一个最主要的是: LINK2019 无法识别的外部符号,然后某一个函数的函数名 然后是 @@函数名 (@) 大概长成这样.或者还就根本就是 无法识别的外部符号. 解决方案: 我这 ...

  5. 【转】C&plus;&plus;及java在内存分配上的区别

    转自:http://blog.csdn.net/qinghezhen/article/details/9116053 C++内存分配由五个部分组成:栈.堆.全局代码区.常量区.程序代码区.如下图所示: ...

  6. ICSharpCode&period;SharpZipLib&period;Zip

    //压缩整个目录下载 var projectFolder = Request.Params["folder"] != null ? Request.Params["fol ...

  7. C&num; 语言规范&lowbar;版本5&period;0 &lpar;第2章 词法结构&rpar;

    1. 词法结构 1.1 程序 C# 程序 (program) 由一个或多个源文件 (source file) 组成,源文件的正式名称是编译单元 (compilation unit)(第 9.1 节). ...

  8. 应对WannaCry勒索危机之关闭445端口等危险端口——以本人Windows7系统为例

    应对WannaCry勒索危机之关闭445端口等危险端口--以本人Windows7系统为例 近日,全球范围内爆发WannaCry勒索病毒危机 我国很多大学纷纷中招.受灾严重,甚至连刘老师的电脑也-- 拿 ...

  9. Linux登录失败:Too many logins for &&num;39&semi;username&&num;39&semi;&period;

    cat /etc/security/limits.conf #<domain> <type> <item> <value> * - maxlogins ...

  10. 通过Hive将数据写入到ElasticSearch

    我在<使用Hive读取ElasticSearch中的数据>文章中介绍了如何使用Hive读取ElasticSearch中的数据,本文将接着上文继续介绍如何使用Hive将数据写入到Elasti ...