最近一直在做操作系统的大作业,作业的要求是开发一个Windows文件过滤驱动,对某一个文本文件xxxx.txt进行保护。首先,驱动要读取权限记录文件user.txt,文件内记录有read_false/read_true,write_false/write_true,delete_false/delete_true,每个文件记录有三个操作的其中一个,true或者false,
然后驱动在根据相应的权限进行下一步操作。
我们现在遇到的问题是,可以对文本文件xxxx.txt进行相应的保护,即防止删除,防止写,防止读,但是问题在于读取不了权限记录文件.我们使用的是FLTxxxFile()系列函数。但是每次驱动运行后,电脑马上就蓝屏了。。。
具体代码如下:(环境:Visual Studio2017)
1.先放出一个IRP_MJ_WRITE,pre函数为WritePreOperation()
2.读取权限文件的相关函数ReadFileTest(PVOID buffer)
打开权限文件,然后读取内容到buffer.
NTSTATUS ReadFileTest(PVOID buffer)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
//PVOID buffer = NULL;
ULONG total_len = 0;
ULONG readbytes = 0;
ULONG byteswritten = 0;
HANDLE FileHandle = NULL;
PFILE_OBJECT FileObject = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
PFLT_VOLUME Volume = NULL;
PFLT_INSTANCE Instance = NULL;
PUNICODE_STRING FullFileName = NULL;
RtlInitUnicodeString(FullFileName, L"\C:\user.txt");
InitializeObjectAttributes(
&ObjectAttributes,
FullFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = FltCreateFileEx(
gFilterHandle,
Instance,
&FileHandle,
&FileObject,
GENERIC_READ,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY | FILE_COMPLETE_IF_OPLOCKED,
NULL,
0,
IO_NO_PARAMETER_CHECKING
);
if (FileObject)
{
//read the file
//get the volume
status = FltGetVolumeFromFileObject(gFilterHandle, FileObject, &Volume);
if (NT_SUCCESS(status))
{
status = FltGetVolumeInstanceFromName(
gFilterHandle,
Volume,
NULL,
&Instance
);
// if (NT_SUCCESS(status))
// {
// while (STATUS_END_OF_FILE != FltReadFile(Instance, FileObject, NULL, 4096,
// buffer, FLTFL_IO_OPERATION_NON_CACHED, &readbytes, NULL, NULL))
// {
// total_len += readbytes;
// PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF:Read length is %u,total len is %u\n", readbytes, total_len));
// FltWriteFile(Instance, FileObject2, NULL, readbytes, buffer, FLTFL_IO_OPERATION_NON_CACHED, &byteswritten, NULL, NULL);
// }
// }
FltReadFile(Instance, FileObject, NULL, 4096,
buffer, FLTFL_IO_OPERATION_NON_CACHED, &readbytes, NULL, NULL);
if (Volume)
{
FltObjectDereference(Volume);
}
if (Instance)
{
FltObjectDereference(Instance);
}
}
if (FileObject)
{
FltClose(FileHandle);
ObDereferenceObject(FileObject);
}
return status;
}
}
3.WritePreOperation()
我们是这样想的,得到在函数ReadFileTest中读取到了内容的buffer,然后再调用wcsstr(buffer,L"WRITE_FALSE") 看看buffer 里面有没有相应的权限子串,再进行相应的操作。
FLT_PREOP_CALLBACK_STATUS
WritePreOperation(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID *CompletionContext
)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();
{
PFLT_FILE_NAME_INFORMATION nameInfo;
WCHAR buffer[64] = { 0 };
ReadFileTest(buffer);
//直接获得文件名并检查
if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)))
{
if (NT_SUCCESS(FltParseFileNameInformation(nameInfo)))
{
WCHAR pTempBuf[512] = { 0 };
WCHAR *pNonPageBuf = NULL, *pTemp = pTempBuf;
if (nameInfo->Name.MaximumLength > 512)
{
pNonPageBuf = ExAllocatePool(NonPagedPool, nameInfo->Name.MaximumLength);
pTemp = pNonPageBuf;
}
RtlCopyMemory(pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength);
DbgPrint("[MiniFilter][IRP_MJ_WRITE]%wZ", &nameInfo->Name);
_wcsupr(pTemp);
_wcsupr(buffer);
if (NULL != wcsstr(pTemp, L"XXXX.TXT")&& NULL != wcsstr(buffer,L"WRITE_FALSE"))
{
if (NULL != pNonPageBuf)
ExFreePool(pNonPageBuf);
if (buffer != NULL)
{
ExFreePool(buffer);
}
FltReleaseFileNameInformation(nameInfo);
return FLT_PREOP_DISALLOW_FASTIO;
}
if (NULL != pNonPageBuf)
ExFreePool(pNonPageBuf);
if (buffer != NULL)
{
ExFreePool(buffer);
}
}
FltReleaseFileNameInformation(nameInfo);
}
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
工程全景:
代码都是在cFilter.c里面写的,然后测试环境是虚拟机Windows7,没有读取权限文件操作时,可以进行相应的保护,加上后,一运行就蓝屏了。还望有高人指导~