设为首页 收藏本站
查看: 672|回复: 0

[MiniFilter]驱动隐藏文件夹的实现(支持Win7)

[复制链接]

尚未签到

发表于 2015-5-15 09:23:35 | 显示全部楼层 |阅读模式
  刚完成一个利用驱动隐藏文件夹的程序,隐藏文件的类似,现在贴出来共享给大家。
  代码相对比较简单,我是在别人代码的基础上改的。
  因为现在在网上找到的代码都是不支持XP以上版本的,所以我在别人代码的基础上添加了XP以上版本的支持。
  现在该代码同时支持XP以下及XP以上版本(本人仅测试XP和Win7)。
  利用驱动实现文件的隐藏主要是在IRP_MJ_DIRECTORY_CONTROL的后操作回调函数中处理其输入参数FLT_CALLBACK_DATA结构中的缓冲区数据。
  该缓冲地址的获取是重点,Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer(或MdlAddress)
  网上现有代码不支持XP以上版本的原因是Vista或Win7返回的FileInformationClass结构不再是FileBothDirectoryInformation,而是FileIdBothDirectoryInformation
  【注】虽然利用驱动隐藏文件无法利用“显示隐藏文件”查看,但文件实际仍存在,通过路径仍然可以访问。
  实现代码如下:


DSC0000.gif DSC0001.gif C 代码



//[Modify By js2854 2010-10-29 Support Windows 7]

#include
#include
#include
#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")
//
//  This is how FltMgr was released (from oldest to newest) [仅编译时决定,而非运行时]
//  This defines items that only exist in longhorn or later [判断系统版本是否VISTA以上版本]
//

#define FLT_MGR_LONGHORN (NTDDI_VERSION >= NTDDI_VISTA)
PFLT_FILTER filterHandle;
PWCHAR prefixName = L"HideDir";//要隐藏的文件夹名字的前缀

/*************************************************************************
    Prototypes
*************************************************************************/
NTSTATUS DriverEntry ( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath );
NTSTATUS PtUnload ( __in FLT_FILTER_UNLOAD_FLAGS Flags );
FLT_POSTOP_CALLBACK_STATUS
HideFilePostDirCtrl (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, PtUnload)
#endif
CONST FLT_OPERATION_REGISTRATION Callbacks[] =
{
    { IRP_MJ_DIRECTORY_CONTROL,
      0,
      NULL,
      HideFilePostDirCtrl },
    { IRP_MJ_OPERATION_END }
};
CONST FLT_REGISTRATION FilterRegistration =
{
    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags
    NULL,                               //  Context
    Callbacks,                          //  Operation callbacks
    PtUnload,                           //  MiniFilterUnload
    NULL,                               //  InstanceSetup
    NULL,                               //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete
    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent
};
NTSTATUS DriverEntry ( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath )
{
    NTSTATUS status;
    UNREFERENCED_PARAMETER( RegistryPath );
    status = FltRegisterFilter( DriverObject, &FilterRegistration, &filterHandle );
    if (NT_SUCCESS( status ))
    {
        status = FltStartFiltering( filterHandle );
        if (!NT_SUCCESS( status ))
        {
            FltUnregisterFilter( filterHandle );
        }
    }
    return status;
}
NTSTATUS PtUnload ( __in FLT_FILTER_UNLOAD_FLAGS Flags )
{
    UNREFERENCED_PARAMETER( Flags );
    PAGED_CODE();
    FltUnregisterFilter( filterHandle );
    return STATUS_SUCCESS;
}
FLT_POSTOP_CALLBACK_STATUS
HideFilePostDirCtrl (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__in_opt PVOID CompletionContext,
__in FLT_POST_OPERATION_FLAGS Flags )
{
    ULONG nextOffset = 0;
    int modified = 0;
    int removedAllEntries = 1;
    PVOID SafeBuffer;
#if FLT_MGR_LONGHORN
    PFILE_ID_BOTH_DIR_INFORMATION currentFileInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION nextFileInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION previousFileInfo = 0;
#else
    PFILE_BOTH_DIR_INFORMATION currentFileInfo = 0;
    PFILE_BOTH_DIR_INFORMATION nextFileInfo = 0;
    PFILE_BOTH_DIR_INFORMATION previousFileInfo = 0;
#endif   
    UNICODE_STRING fileName;
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );
    if( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) )
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }
    //vista或win7返回的FileInformationClass结构不再是FileBothDirectoryInformation.
    //而是FileidBothDirectoryInformation
    if( Data->Iopb->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
        (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass ==FileIdBothDirectoryInformation ) &&
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length > 0 &&
        NT_SUCCESS(Data->IoStatus.Status))
    {
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {
            SafeBuffer=MmGetSystemAddressForMdlSafe(
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {
             SafeBuffer=Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;            
         }     
        if(SafeBuffer==NULL)
        {
            return FLT_POSTOP_FINISHED_PROCESSING;
        }
        #if FLT_MGR_LONGHORN
               currentFileInfo = (PFILE_ID_BOTH_DIR_INFORMATION)SafeBuffer;
        #else
               currentFileInfo = (PFILE_BOTH_DIR_INFORMATION)SafeBuffer;
        #endif
        previousFileInfo = currentFileInfo;
        do
        {
            //Byte offset of the next FILE_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileInfo->NextEntryOffset;
            #if FLT_MGR_LONGHORN
                nextFileInfo = (PFILE_ID_BOTH_DIR_INFORMATION)((PCHAR)(currentFileInfo) + nextOffset);
            #else
                nextFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)(currentFileInfo) + nextOffset);
            #endif
            //若满足条件,隐藏之
            if(_wcsnicmp(currentFileInfo->FileName,prefixName,wcslen(prefixName))==0)
            {               
                if( nextOffset == 0 )
                {
                    previousFileInfo->NextEntryOffset = 0;
                }
                else
                {
                    previousFileInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileInfo - (PCHAR)previousFileInfo) + nextOffset;
                }
                modified = 1;               
            }
            else
            {
                removedAllEntries = 0;
                //前驱结点指针后移
                previousFileInfo = currentFileInfo;               
            }
            //当前指针后移
            currentFileInfo = nextFileInfo;
        } while( nextOffset != 0 );
        if( modified )
        {
            if( removedAllEntries )
            {
                Data->IoStatus.Status = STATUS_NO_MORE_FILES;
            }
            else
            {
                FltSetCallbackDataDirty( Data );
            }
        }
    }
    return FLT_POSTOP_FINISHED_PROCESSING;
}
  注意以上代码使用的是宏开关,只是在编译时起作用,而非运行时。要想XP和win7都可以正常隐藏文件目录需要分别编译。
  要想XP和win7同时起作用,需要去掉宏开关,然后把HideFilePostDirCtrl 改成一下代码


View Code



//实现目录隐藏,支持XP及以上版本 JiaSong[2010-11-1]
FLT_POSTOP_CALLBACK_STATUS
HideFilePostDirCtrl (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
)
{
    ULONG nextOffset = 0;
    int modified = 0;
    int removedAllEntries = 1;   
    PFILE_BOTH_DIR_INFORMATION currentFileInfo = 0;     
     PFILE_BOTH_DIR_INFORMATION nextFileInfo = 0;   
     PFILE_BOTH_DIR_INFORMATION previousFileInfo = 0;   
     PFILE_ID_BOTH_DIR_INFORMATION currentFileIdInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION nextFileIdInfo = 0;
    PFILE_ID_BOTH_DIR_INFORMATION previousFileIdInfo = 0;
    UNREFERENCED_PARAMETER( FltObjects );
    UNREFERENCED_PARAMETER( CompletionContext );   
    //不满足过滤条件的直接放过
    if( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) ||
        Data->Iopb->MinorFunction != IRP_MN_QUERY_DIRECTORY ||
        Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length IoStatus.Status))
    {
        return FLT_POSTOP_FINISHED_PROCESSING;
    }
    //XP及其以下版本,需要过滤 FileBothDirectoryInformation 类型的信息
    if(Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation)
    {
        //我们可以得到一个缓存区,这个缓存里面就保留着文件夹中所有的文件信息。
        //根据这个缓存的结构遍历处理,过滤掉要隐藏的文件名就能达到隐藏的目的了
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {//缓存地址
            currentFileInfo=(PFILE_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdlSafe(
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {//缓存地址
             currentFileInfo=(PFILE_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;            
         }     
        if(currentFileInfo==NULL)return FLT_POSTOP_FINISHED_PROCESSING;      
        previousFileInfo = currentFileInfo;
        do
        {
            //Byte offset of the next FILE_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileInfo->NextEntryOffset;
            //后继结点指针
            nextFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)(currentFileInfo) + nextOffset);            
            KdPrint(("1.FileName: %S, ShortName: %S\n",currentFileInfo->FileName,currentFileInfo->ShortName));
            if(_wcsnicmp(currentFileInfo->FileName,g_prefixName,wcslen(g_prefixName))==0)
            {
                KdPrint(("1.g_prefixName: %S, currentFileInfo->FileName: %S\n",g_prefixName,currentFileInfo->FileName));
                if( nextOffset == 0 )
                {
                    previousFileInfo->NextEntryOffset = 0;
                }
                else
                {//更改前驱结点中指向下一结点的偏移量,略过要隐藏的文件的文件结点,达到隐藏目的
                    previousFileInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileInfo - (PCHAR)previousFileInfo) + nextOffset;
                }
                modified = 1;
            }
            else
            {
                removedAllEntries = 0;
                //前驱结点指针后移
                previousFileInfo = currentFileInfo;
            }
            //当前指针后移         
            currentFileInfo = nextFileInfo;
        } while( nextOffset != 0 );
    }
    //vista或win7返回的结构不再是FileBothDirectoryInformation.而是FileIdBothDirectoryInformation
    else if(Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass ==FileIdBothDirectoryInformation)
    {
        if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL)
        {
            currentFileIdInfo=(PFILE_ID_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdlSafe(
                         Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress,
                         NormalPagePriority );            
        }
        else
         {
             currentFileIdInfo=(PFILE_ID_BOTH_DIR_INFORMATION)Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;            
         }     
        if(currentFileIdInfo==NULL)return FLT_POSTOP_FINISHED_PROCESSING;
        previousFileIdInfo = currentFileIdInfo;
        do
        {
            //Byte offset of the next FILE_ID_BOTH_DIR_INFORMATION entry
            nextOffset = currentFileIdInfo->NextEntryOffset;            
               nextFileIdInfo = (PFILE_ID_BOTH_DIR_INFORMATION)((PCHAR)(currentFileIdInfo) + nextOffset);            
            KdPrint(("2.FileName: %S, ShortName: %S\n",currentFileIdInfo->FileName,currentFileIdInfo->ShortName));
            if(_wcsnicmp(currentFileIdInfo->FileName,g_prefixName,wcslen(g_prefixName))==0)
            {
                KdPrint(("2.g_prefixName: %S, currentFileInfo->FileName: %S\n",g_prefixName,currentFileIdInfo->FileName));
                if( nextOffset == 0 )
                {
                    previousFileIdInfo->NextEntryOffset = 0;
                }
                else
                {
                    previousFileIdInfo->NextEntryOffset = (ULONG)((PCHAR)currentFileIdInfo - (PCHAR)previousFileIdInfo) + nextOffset;
                }
                modified = 1;
            }
            else
            {
                removedAllEntries = 0;               
                previousFileIdInfo = currentFileIdInfo;               
            }
            currentFileIdInfo = nextFileIdInfo;
        } while( nextOffset != 0 );
    }
    if( modified )
    {
        if( removedAllEntries )
         {
              Data->IoStatus.Status = STATUS_NO_MORE_FILES;
          }
           else
           {
            FltSetCallbackDataDirty( Data );
        }
    }        
    return FLT_POSTOP_FINISHED_PROCESSING;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-67089-1-1.html 上篇帖子: Win7(64位)安装Microsoft SQL Server Management Studio Express[error 29506] 下篇帖子: 最新32位和64位xp,win7,win8,win10系统大全(电脑装机版)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表