VS2013里面有向导可以直接创建一个minifilter驱动,这简化了很多工作,不像以前往往是从一个现有驱动代码里面copy一下,然后修改。VS2013的向导可以生成代码框架和inf文件,这让程序员减少很多繁琐的工作。
使用向导创建一个minifilter工程
太容易了,傻瓜式的一步创建。
点击ok,打开MyMiniFilter.c,更改下面的代码:
/* #define PT_DBG_PRINT( _dbgLevel, _string ) \ (FlagOn(gTraceFlags,(_dbgLevel)) ? \ DbgPrint _string : \ ((int)0))*/ #define PT_DBG_PRINT( _dbgLevel, _string ) \ DbgPrint _string
向导生成的Log有一些条件,我们测试的话,就改成无条件打印好了。
然后弄一个filter,向导已经生成了一些代码,但是用 if 0 禁掉了。我们启用一个Write的过滤,如:
CONST FLT_OPERATION_REGISTRATION Callbacks[] = { { IRP_MJ_WRITE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, #if 0 // TODO - List all of the requests to filter. { IRP_MJ_CREATE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_CREATE_NAMED_PIPE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_CLOSE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_READ, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_WRITE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_QUERY_INFORMATION, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_SET_INFORMATION, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_QUERY_EA, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_SET_EA, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_FLUSH_BUFFERS, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_QUERY_VOLUME_INFORMATION, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_SET_VOLUME_INFORMATION, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_DIRECTORY_CONTROL, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_FILE_SYSTEM_CONTROL, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_DEVICE_CONTROL, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_INTERNAL_DEVICE_CONTROL, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_SHUTDOWN, 0, MyMiniFilterPreOperationNoPostOperation, NULL }, //post operations not supported { IRP_MJ_LOCK_CONTROL, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_CLEANUP, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_CREATE_MAILSLOT, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_QUERY_SECURITY, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_SET_SECURITY, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_QUERY_QUOTA, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_SET_QUOTA, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_PNP, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_ACQUIRE_FOR_MOD_WRITE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_RELEASE_FOR_MOD_WRITE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_ACQUIRE_FOR_CC_FLUSH, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_RELEASE_FOR_CC_FLUSH, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_NETWORK_QUERY_OPEN, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_MDL_READ, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_MDL_READ_COMPLETE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_PREPARE_MDL_WRITE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_MDL_WRITE_COMPLETE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_VOLUME_MOUNT, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, { IRP_MJ_VOLUME_DISMOUNT, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation }, #endif // TODO { IRP_MJ_OPERATION_END } };
好了,直接编译。
然后把MyMinifilter.inf和MyMiniFilter.sys考到虚拟机上。注意VS2013不支持了XP了,所以我们找一个win7 32位虚拟机。因为win7 64位虚拟机需要签名,为了省去签名这一步,先用win7 32位。
右键点击inf文件安装。之后运行cmd,(注意需要用Administrator运行)。输入命令sc start myminifilter
这样就可以把minifilter驱动起来。
用Administrator运行Windbg(注意勾上Enable verbose kernel output)这样我们用start,stop命令的时候就可以看到一下log。
现在有个问题就是,我们挂载了回调函数给IRP: IRP_MJ_WRITE
{ IRP_MJ_WRITE, 0, MyMiniFilterPreOperation, MyMiniFilterPostOperation },
可是实际情况却没有看到log。这个是因为inf文件需要稍微改一下。
修改inf文件
现在暂时只需要修改Altitude,看下图,其实就是把注释掉的代码启用。
把inf文件copy到虚拟机上,然后再右键安装,重启驱动。这个时候就可以看到很多log了,因为IRP_MJ_WRITE到处被调用。
ok,sample 代码就跑起来了。后面再一步步介绍具体的细节。