您的位置:首页 > Web前端 > JavaScript

青松卓然 js2854的博客 [MiniFilter]驱动隐藏文件夹的实现(支持Win7)

2012-07-18 08:56 375 查看
青松卓然
js2854的博客

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

/article/5459351.html

刚完成一个利用驱动隐藏文件夹的程序,隐藏文件的类似,现在贴出来共享给大家。

代码相对比较简单,我是在别人代码的基础上改的。

因为现在在网上找到的代码都是不支持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

【注】虽然[b]利用驱动隐藏文件无法利用“显示隐藏文件”查看,但文件实际仍存在,通过路径仍然可以访问。[/b]

实现代码如下:

C 代码

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

#include <fltKernel.h>

#include <dontuse.h>

#include <suppress.h>

#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,

,

NULL,

HideFilePostDirCtrl },

{ IRP_MJ_OPERATION_END }

};

CONST FLT_REGISTRATION FilterRegistration =

{

sizeof( FLT_REGISTRATION ), // Size

FLT_REGISTRATION_VERSION, // Version

, // 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 <= 0 ||

!NT_SUCCESS(Data->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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: