在一个Minifilter驱动中,我想在PreCreate函数中打开C盘下的目录文件,现在可以使用FltCreateFle获取文件句柄,但是使用FltReadFile时候会导致蓝屏:DUMP分析之后是PAGE_FAULT_IN_NONPAGED_AREA错误。
我也尝试了直接发送IRP给底层设备 ,但是不知道底层设备的DEVICE_OBJECT怎么获取,陷入了文件的重入。
代码如下:
NTSTATUS status;
NTSTATUS ntStatus;
HANDLE hFile;
PIO_STATUS_BLOCK iostatus;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING fileName;
ULONG length;
char FileName[260] = "X:";
char str_temp[260] = {'\0'};
FILE_STANDARD_INFORMATION fsi;
PFLT_FILE_NAME_INFORMATION nameInfo;
PFILE_OBJECT FileObject;
PVOID pBuffer;
ULONG bytesRead;
LARGE_INTEGER offset;
UNREFERENCED_PARAMETER( CompletionContext );
PAGED_CODE();
__try {
status = FltGetFileNameInformation( Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo );
if (NT_SUCCESS( status )) {
//开始文件截获
if (gCommand == ENUM_BLOCK) {
FltParseFileNameInformation( nameInfo );
if (NPUnicodeStringToChar(&nameInfo->Name, FileName)) {
//下面开始打开文件并且读入需要过滤的文件信息
_asm int 3;
RtlInitUnicodeString( &fileName,LoadFilePath);
InitializeObjectAttributes( &objectAttributes,
&fileName,
OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
NULL,
NULL );
//下面使用FltCreateFile开始非重入打开文件
status = FltCreateFile( gFilterHandle,
FltObjects->Instance,
&hFile,
FILE_READ_DATA,
&objectAttributes,
&ioStatus,
(PLARGE_INTEGER) NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_ALERT,
NULL,
0,
IO_IGNORE_SHARE_ACCESS_CHECK
);
if(!NT_SUCCESS(status))
{
__leave;
FltClose(hFile);
}
//读取文件长度
ntStatus = ZwQueryInformationFile(hFile,
&iostatus,
&fsi,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
KdPrint(("The program want to read %d bytes\n",fsi.EndOfFile.QuadPart));
//为读取的文件分配缓冲区
length = (ULONG)fsi.EndOfFile.QuadPart;
pBuffer = FltAllocatePoolAlignedWithTag( FltObjects->Instance,
PagedPool,
length,
'nacS' );
FileObject = (PFILE_OBJECT)ExAllocatePool(PagedPool,sizeof(FILE_OBJECT));
//读取文件
status = ObReferenceObjectByHandle(hFile,FILE_READ_DATA,*IoFileObjectType,
KernelMode,(PVOID*)FileObject,NULL);
/*status = ZwReadFile(hFile,NULL,
NULL,NULL,
iostatus,
pBuffer,
(LONG)fsi.EndOfFile.QuadPart,
NULL,NULL);*/
if(!NT_SUCCESS(status))
{
__leave;
FltClose(hFile);
}
//下面使用直接封装IRP发送到设备栈的底层的方式
offset.QuadPart = 0;
//status = FltFileReadWrite(FltObjects->FileObject->DeviceObject->AttachedDevice,FileObject,&offset,&length,pBuffer,TRUE);
//status = FltFileReadWrite(Data->Iopb->TargetFileObject->DeviceObject,FileObject,&offset,&length,pBuffer,TRUE);
bytesRead = 0;
_asm int 3;
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
{
DbgPrint("Over Level");
__leave;
}
PAGED_CODE();
status = FltReadFile(
FltObjects->Instance,
FileObject,
&offset,
1,
pBuffer,
FLTFL_IO_OPERATION_NON_CACHED|FLTFL_IO_OPERATION_PAGING,
&bytesRead,
NULL,
NULL
);
if(!NT_SUCCESS(status))
{
__leave;
FltClose(hFile);
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)