Example #1
0
NTSTATUS 
File_GetFileStandardInfo(
	__in  PFLT_CALLBACK_DATA Data,
	__in  PFLT_RELATED_OBJECTS FltObjects,
	__in PLARGE_INTEGER FileAllocationSize,
	__in PLARGE_INTEGER FileSize,
	__in PBOOLEAN bDirectory
	)
{
	NTSTATUS status = STATUS_SUCCESS ;
	FILE_STANDARD_INFORMATION sFileStandardInfo ;

	//修改为向下层Call
	status = FltQueryInformationFile(FltObjects->Instance,
									 FltObjects->FileObject,
									 &sFileStandardInfo,
									 sizeof(FILE_STANDARD_INFORMATION),
									 FileStandardInformation,
									 NULL
									 ) ;
	if (NT_SUCCESS(status))
	{
		if (NULL != FileSize)
			*FileSize = sFileStandardInfo.EndOfFile ;
		if (NULL != FileAllocationSize)
			*FileAllocationSize = sFileStandardInfo.AllocationSize ;
		if (NULL != bDirectory)
			*bDirectory = sFileStandardInfo.Directory ;
	}

	return status ;
}
Example #2
0
NTSTATUS 
File_GetFileSize(
	__in  PFLT_CALLBACK_DATA Data,
	__in  PFLT_RELATED_OBJECTS FltObjects,
	__in PLARGE_INTEGER FileSize
	)
{
	NTSTATUS status;
	FILE_STANDARD_INFORMATION fileInfo ;

	//修改为向下层Call
	status = FltQueryInformationFile(FltObjects->Instance,
									 FltObjects->FileObject,
									 &fileInfo,
									 sizeof(FILE_STANDARD_INFORMATION),
									 FileStandardInformation,
									 NULL
									 ) ;
	if (NT_SUCCESS(status))
	{
		FileSize->QuadPart = fileInfo.EndOfFile.QuadPart ;
	}
	else
	{
		FileSize->QuadPart = 0 ;
	}

	return status;
}
Example #3
0
NTSTATUS 
File_GetFileOffset(
	__in  PFLT_CALLBACK_DATA Data,
	__in  PFLT_RELATED_OBJECTS FltObjects,
	__out PLARGE_INTEGER FileOffset
	)
{
	NTSTATUS status;
	FILE_POSITION_INFORMATION NewPos;	

	//修改为向下层Call
	status = FltQueryInformationFile(FltObjects->Instance,
									 FltObjects->FileObject,
									 &NewPos,
									 sizeof(FILE_POSITION_INFORMATION),
									 FilePositionInformation,
									 NULL
									 ) ;
	if(NT_SUCCESS(status))
	{
		FileOffset->QuadPart = NewPos.CurrentByteOffset.QuadPart;
	}

	return status;
}
Example #4
0
/*---------------------------------------------------------
函数名称:	FileGetStandardInformation
函数描述:	非重入获取文件基本信息
输入参数:
			pfiInstance			过滤器实例
			pfoFileObject		文件对象
			pnAllocateSize		申请大小
			pnFileSize			文件大小
			pbDirectory			是否是目录
输出参数:
返回值:		
			STATUS_SUCCESS 成功	否则返回相应状态

其他:		后三项参数为可选,不需要查询置为NULL即可

更新维护:	2011.4.3    最初版本
			2011.4.9    修改为使用FltXXX版本
---------------------------------------------------------*/
NTSTATUS
FileGetStandardInformation(
	__in PFLT_INSTANCE pfiInstance,
	__in PFILE_OBJECT pfoFileObject,
	__inout_opt PLARGE_INTEGER pnAllocateSize,
	__inout_opt PLARGE_INTEGER pnFileSize,
	__inout_opt BOOLEAN *pbDirectory
	)
{
	//返回值
	NTSTATUS status;

	PFILE_STANDARD_INFORMATION psiFileStandardInformation;

	//
	//首先分配内存 准备查询 如果失败 返回资源不足
	//
	psiFileStandardInformation = (PFILE_STANDARD_INFORMATION)
				ExAllocatePoolWithTag(NonPagedPool,sizeof(FILE_STANDARD_INFORMATION),MEM_FILE_TAG);

	if( !psiFileStandardInformation ){
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	//
	//查询信息 如果成功就筛选信息,否则直接返回
	//
	status = FltQueryInformationFile(
		pfiInstance,//实例 防止重入
		pfoFileObject,
		(PVOID)psiFileStandardInformation,
		sizeof(FILE_STANDARD_INFORMATION),
		FileStandardInformation,
		NULL//不需要了解返回了多少数据
		);

	if(NT_SUCCESS(status)){
		if(pnAllocateSize){
			*pnAllocateSize 
				= psiFileStandardInformation ->AllocationSize;
		}
		if(pnFileSize){
			*pnFileSize
				= psiFileStandardInformation -> EndOfFile;
		}
		if(pbDirectory != NULL){
			*pbDirectory = psiFileStandardInformation -> Directory;
		}
	}

	ExFreePool(psiFileStandardInformation);

	return status;
}
Example #5
0
EXTERN_C static NTSTATUS ScvnpScavenge(_Inout_ PFLT_CALLBACK_DATA Data,
                                       _In_ PCFLT_RELATED_OBJECTS FltObjects) {
  PAGED_CODE();

  // Ignore system threads. Thus, this program does not support activities of
  // kernel mode code.
  if (PsIsSystemThread(PsGetCurrentThread())) {
    return STATUS_SUCCESS;
  }

  const auto operationType = FltGetIrpName(Data->Iopb->MajorFunction);

  PFLT_FILE_NAME_INFORMATION fileNameInformation = nullptr;
  auto status = FltGetFileNameInformationUnsafe(
      FltObjects->FileObject, FltObjects->Instance, FLT_FILE_NAME_NORMALIZED,
      &fileNameInformation);
  if (!NT_SUCCESS(status)) {
    // This error is expected to happen and okay to ignore it.
    if (status != STATUS_FILE_DELETED) {
      LOG_ERROR_SAFE("%-25s : FltGetFileNameInformationUnsafe failed (%08x)",
                     operationType, status);
    }
    return status;
  }

  status = FltParseFileNameInformation(fileNameInformation);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : FltParseFileNameInformation failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Ignore directories
  BOOLEAN isDirectory = FALSE;
  status = FltIsDirectory(FltObjects->FileObject, FltObjects->Instance,
                          &isDirectory);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : FltIsDirectory failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }
  if (isDirectory) {
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Go through a white list
  if (ScvnpIsWhiteListedFile(&fileNameInformation->Name)) {
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Get a file size (etc).
  FILE_STANDARD_INFORMATION fileInfo = {};
  status = FltQueryInformationFile(FltObjects->Instance, FltObjects->FileObject,
                                   &fileInfo, sizeof(fileInfo),
                                   FileStandardInformation, nullptr);
  if (!NT_SUCCESS(status)) {
    // This error is expected to happen and okay to ignore it.
    if (status != STATUS_FILE_DELETED) {
      LOG_ERROR_SAFE("%-25s : FltQueryInformationFile failed (%08x) for %wZ",
                     operationType, status, &fileNameInformation->Name);
    }
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Ignore if the file is empty
  if (fileInfo.EndOfFile.QuadPart == 0) {
    FltParseFileNameInformation(fileNameInformation);
    return status;
  }

  // Ignore if the file size is greater than 4GB
  if (fileInfo.EndOfFile.HighPart != 0) {
    FltParseFileNameInformation(fileNameInformation);
    return STATUS_FILE_TOO_LARGE;
  }

  const auto targetFileSize = fileInfo.EndOfFile.LowPart;

  // Read entire contents of the file onto non paged memory. Thus, it may fail
  // to handle a file larger than the amount of available memory.
  const auto buffer = FltAllocatePoolAlignedWithTag(
      FltObjects->Instance, NonPagedPoolNx, targetFileSize, SCVN_POOL_TAG_NAME);
  if (!buffer) {
    LOG_ERROR_SAFE(
        "%-25s : FltAllocatePoolAlignedWithTag failed (%lu bytes) for %wZ",
        operationType, targetFileSize, &fileNameInformation->Name);
    goto End;
  }
  status = ScvnpReadFile(Data, FltObjects, buffer, targetFileSize);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : ScvnpReadFile failed (%08x) for %wZ", operationType,
                   status, &fileNameInformation->Name);
    goto End;
  }

  // Calculate SHA1 of the written data.
  UCHAR sha1Hash[20] = {};
  status = ScvnpGetSha1(sha1Hash, buffer, targetFileSize);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : ScvnpGetSha1 failed (%08x) for %wZ", operationType,
                   status, &fileNameInformation->Name);
    goto End;
  }
  wchar_t sha1HashW[41] = {};
  for (auto i = 0; i < RTL_NUMBER_OF(sha1Hash); ++i) {
    const auto outW = sha1HashW + i * 2;
    RtlStringCchPrintfW(outW, 3, L"%02x", sha1Hash[i]);
  }

  // Copy the read file contents to the out put folder as <SHA1>.bin.
  wchar_t outPathW[260];
  status = RtlStringCchPrintfW(outPathW, RTL_NUMBER_OF(outPathW), L"%s\\%s.bin",
                               SCVNP_OUT_DIRECTORY_PATH, sha1HashW);
  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : RtlStringCchPrintfW failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    goto End;
  }
  status =
      ScvnpWriteFile(FltObjects, outPathW, buffer, targetFileSize, FILE_CREATE);
  if (status == STATUS_DELETE_PENDING) {
    status = STATUS_SUCCESS;
    goto End;
  }

  if (status == STATUS_OBJECT_NAME_COLLISION) {
    // The same SHA1 is already there
    LOG_INFO_SAFE("%-25s for %wZ (dup with %S, %lu bytes, %wZ)", operationType,
                  &fileNameInformation->FinalComponent, sha1HashW,
                  targetFileSize, &fileNameInformation->Name);
    status = STATUS_SUCCESS;
    goto End;
  }

  if (!NT_SUCCESS(status)) {
    LOG_ERROR_SAFE("%-25s : ScvnpWriteFile failed (%08x) for %wZ",
                   operationType, status, &fileNameInformation->Name);
    goto End;
  }

  // Done
  LOG_INFO_SAFE("%-25s for %wZ (saved as %S, %lu bytes, %wZ)", operationType,
                &fileNameInformation->FinalComponent, sha1HashW, targetFileSize,
                &fileNameInformation->Name);

End:
  if (buffer) {
    FltFreePoolAlignedWithTag(FltObjects->Instance, buffer, SCVN_POOL_TAG_NAME);
  }
  if (fileNameInformation) {
    FltParseFileNameInformation(fileNameInformation);
  }
  return status;
}
NTSTATUS
CopyFile(
		 PFLT_CALLBACK_DATA Data,
		 PCFLT_RELATED_OBJECTS FltObjects,
		 PUNICODE_STRING pCompleteFileName
		 )
{
	NTSTATUS status;
	UNICODE_STRING tempDeletedFilePath;
	OBJECT_ATTRIBUTES tempDeletedObject;
	IO_STATUS_BLOCK ioStatusTempDeleted;
	LARGE_INTEGER allocate;
	FILE_STANDARD_INFORMATION fileStandardInformation;
	HANDLE tempDeletedHandle;
	ULONG returnedLength;
	allocate.QuadPart = 0x10000;

	
	
	InitializeObjectAttributes(
		&tempDeletedObject,
		pCompleteFileName,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL
		);
	status = FltQueryInformationFile(
		FltObjects->Instance,
		Data->Iopb->TargetFileObject,
		&fileStandardInformation,
		sizeof(FILE_STANDARD_INFORMATION),
		FileStandardInformation,
		&returnedLength
		);
	if(NT_SUCCESS(status))
	{
		allocate.QuadPart = fileStandardInformation.AllocationSize.QuadPart;
	} else {
		DbgPrint("CaptureFileMonitor: ERROR - Could not get files allocation size\n");
		return status;
	}

	status = FltCreateFile(
		FltObjects->Filter,
		NULL,
		&tempDeletedHandle,
		GENERIC_WRITE,
		&tempDeletedObject,
		&ioStatusTempDeleted,
		&allocate,
		FILE_ATTRIBUTE_NORMAL,
		0,
		FILE_CREATE,
		FILE_NON_DIRECTORY_FILE,
		NULL,
		0,
		0
		);

	if(NT_SUCCESS(status))
	{
		PVOID handleFileObject;
		PVOID pFileBuffer;
		LARGE_INTEGER offset;
	
		ULONG bytesRead = 0;
		ULONG bytesWritten = 0;
		offset.QuadPart = 0;
		status = ObReferenceObjectByHandle(
			tempDeletedHandle,
			0,
			NULL,
			KernelMode,
			&handleFileObject,
			NULL);
		if(!NT_SUCCESS(status))
		{
			DbgPrint("CaptureFileMonitor: ERROR - ObReferenceObjectByHandle - FAILED - %08x\n", status);
			return status;
		}
		
		pFileBuffer = ExAllocatePoolWithTag(NonPagedPool, 65536, FILE_POOL_TAG);
		
		if(pFileBuffer != NULL)
		{
			ObReferenceObject(Data->Iopb->TargetFileObject);
			do {
				IO_STATUS_BLOCK IoStatusBlock;
				bytesWritten = 0;
				status = FltReadFile(
					FltObjects->Instance,
					Data->Iopb->TargetFileObject,
					&offset,
					65536,
					pFileBuffer,
					FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
					&bytesRead ,
					NULL,
					NULL
					);
			
				if(NT_SUCCESS(status) && bytesRead > 0)
				{
					/* You can't use FltWriteFile here */
					/* Instance may not be the same instance we want to write to eg a
					   flash drive writing a file to a ntfs partition */
					status = ZwWriteFile(
						tempDeletedHandle,
						NULL,
						NULL,
						NULL,
						&IoStatusBlock,
						pFileBuffer,
						bytesRead,
						&offset,
						NULL
						);
					if(NT_SUCCESS(status))
					{
						//DbgPrint("WriteFile: FltReadFile - %08x\n", status);
					}
					/*
					status = FltWriteFile(
						FltObjects->Instance,
						handleFileObject,
						&offset,
						bytesRead,
						pFileBuffer,
						FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
						&bytesWritten,
						NULL,
						NULL
						);
						*/
				} else {
					//DbgPrint("CopyFile: FltReadFile - %08x\n", status);
					break;
				}
				offset.QuadPart += bytesRead;
			} while(bytesRead == 65536);
			ObDereferenceObject(Data->Iopb->TargetFileObject);
			ExFreePoolWithTag(pFileBuffer, FILE_POOL_TAG);
		}
		ObDereferenceObject(handleFileObject);
		FltClose(tempDeletedHandle);
	} else {
		if(status != STATUS_OBJECT_NAME_COLLISION)
		{
			DbgPrint("CaptureFileMonitor: ERROR - FltCreateFile FAILED - %08x\n",status);
			return status;
		}
	}
	return STATUS_SUCCESS;
}