⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 specialiofunction.cpp

📁 一个过滤层文件系统驱动的完整代码,实现了文件的加密,操作截获等
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		{
			PUNICODE_STRING FileName =  ObjectAttributes->ObjectName;

			if (FileName->Length < 0x38)
			{
				NewFileObject->FileName.MaximumLength =  0x38;
			}

			else if (FileName->Length < 0x78)
			{
				NewFileObject->FileName.MaximumLength =  0x78;
			}

			else if (FileName->Length < 0xF8)
			{
				NewFileObject->FileName.MaximumLength =  0xF8;
			}

			else
			{
				NewFileObject->FileName.MaximumLength =  FileName->Length;
			}

			NewFileObject->FileName.Buffer =(unsigned short *)ExAllocatePool(NonPagedPool, NewFileObject->FileName.MaximumLength);

			if (!NewFileObject->FileName.Buffer)
			{
				try_return(Status =  STATUS_INSUFFICIENT_RESOURCES);
			}

		}
		NewFileObject->Vpb=Vcb->pVpb;

		RtlCopyUnicodeString(&NewFileObject->FileName, ObjectAttributes->ObjectName);

		KeInitializeEvent(&NewFileObject->Event, NotificationEvent, FALSE);

		//
		// Before we call the FSD to process this request we must set
		// completion routine which will be responsible to free the Irp
		// and to do some little postprocessing.
		//

		IoSetCompletionRoutine( Irp,FsTPMSynchronousApiCompletion,NULL,TRUE,TRUE,TRUE );

		//
		// Call the File System Driver to do the task requested by caller.
		//

		Status = IoCallDriver(Vcb->pVpb->DeviceObject, Irp);

		Irp =  NULL;

		if (Status ==  STATUS_PENDING)
		{
			(VOID)KeWaitForSingleObject(&Event, Executive, KernelMode, 	FALSE, NULL);
			Status =  IoStatus.Status;
		}

		if (!NT_SUCCESS(Status))
		{
			try_return(Status);
		}

		ASSERT(Status !=  STATUS_REPARSE);

		//
		// Return desired FileObject and Information.
		//

		FileObject =  NewFileObject;
		*Information =  IoStatus.Information;

		//
		// If the caller requests handle now is the right time
		// to insert the file object into Object Manager.
		//

		if (FileHandle !=  NULL)
		{
			Status =  ObInsertObject( NewFileObject,NULL,DesiredAccess,0,NULL,FileHandle );
			ASSERT(NT_SUCCESS(Status));
			SetFlag(NewFileObject->Flags, FO_HANDLE_CREATED);
		}

		try_exit:NOTHING;
	}

	__finally
	{	
		//
		// Unwind neccessary things
		//

		//	ASSERT(!AbnormalTermination());  //<<<<<<<<<<<<<Notice 

		if (CreatedAccessState)
		{
			SeDeleteAccessState(&AccessState);
		}

		if (!NT_SUCCESS(Status))
		{
			if (Irp)
			{
				IoFreeIrp(Irp);
			}

			if (NewFileObject)
			{
				if (NewFileObject->FileName.Length)
				{		
					ExFreePool(NewFileObject->FileName.Buffer);
					NewFileObject->FileName.Length =  0;
				}

				NewFileObject->DeviceObject =  NULL;

				// ASSERT(ObGetObjectPointerCount(NewFileObject) == 1);
				ObDereferenceObject(NewFileObject);
			}
		}

		else
		{
			FsTPMReferenceDeviceAndVpb(NewFileObject);
		}
		ExFreePool(pAuxData);

	}

	return Status;

}


//
//  本函数用于创建目录,可以有如下形式的参数:  C:\  , C:\WINDOWS\ , C:\WINDOWS\A.TXT ,注意 完整的目录应最后至少有一个"\ "
//  若其后还跟有文件名,本函数可以忽略文件名
//
NTSTATUS
FsTPMCreateDirectory(
					   const WCHAR *pDir
					   )
{
	FILE_OBJECT DirectoryFileObject;
	HANDLE DirectoryHandle;
	NTSTATUS ntStatus;
	UNICODE_STRING Uni_Dir;
	OBJECT_ATTRIBUTES DirectoryAttributes;
	int Layer=-1,Len=FsTPMwcslen(pDir),pos,TmpLayer;
	ULONG ThrowInf; // We don't want to see the value of the returned informatiom
	UNICODE_STRING UDir={0};
	// So throw it.


	while (Pos<Len)
	{
		Layer++;
		pos=-1; 	TmpLayer=Layer;
		while (!((pos>=Len) || (L'\\'==pDir[++pos] && TmpLayer==0)))
			if (L'\\'==pDir[pos])
				--TmpLayer;
		if (pos>=Len)
			break;

		ASSERT((pos>=0 && pos<=Len));

		pos++;

		Uni_Dir.Buffer=(PWCHAR)ExAllocatePool(PagedPool,(pos+1)*sizeof(WCHAR));
		ASSERT((Uni_Dir.Buffer!=NULL));
		Uni_Dir.MaximumLength=Uni_Dir.Length=(pos+1)*sizeof(WCHAR);
		RtlCopyMemory(Uni_Dir.Buffer,pDir,(pos+1)*sizeof(WCHAR));
		Uni_Dir.Buffer[pos]=0;

		RtlInitUnicodeString(&UDir,&(Uni_Dir.Buffer[2]));

		// Then we should initialize the file object's attributes
		InitializeObjectAttributes(
			&DirectoryAttributes,
			&UDir,
			OBJ_CASE_INSENSITIVE,
			NULL, NULL
			);

		ntStatus=FsTPMCreateFile(&(((PHOOK_EXTENSION)(DriveHookDevices[pDir[0]-L'A']->DeviceExtension))->Vcb),
			FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA,
			&DirectoryAttributes,
			0,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ|FILE_SHARE_WRITE,
			FILE_OPEN_IF ,
			FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE|FILE_NO_INTERMEDIATE_BUFFERING,
			NULL,
			0,
			FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE|FILE_NO_INTERMEDIATE_BUFFERING,
			&ThrowInf,
			&DirectoryFileObject,
			&DirectoryHandle
			);
		if (!NT_SUCCESS(ntStatus))
		{
			FsTPM_DbgPrint(("Create %S Failed! Reason:",Uni_Dir.Buffer));
			ErrorString(ntStatus);

			ExFreePool(Uni_Dir.Buffer);
			return ntStatus;
		}
		NtClose(DirectoryHandle);

		ExFreePool(Uni_Dir.Buffer);
	}
	return STATUS_SUCCESS;
}


//
// 注意:pAnsiString 要求在函数调用前已经分配好空间
//
NTSTATUS 
GetFileFullNameByObjectA(
						IN PFILE_OBJECT FileObject,
						IN PHOOK_EXTENSION hookExt,
						IN OUT PCHAR pAnsiString,
						IN int       StringLength
						)
{	
	CHAR CUFileName[512]={0};
	CHAR Temp[512]={0};
	int ret;
	PFILE_OBJECT RelateObject;

	ASSERT(pAnsiString!=NULL);
	ret=_snprintf(CUFileName,511,"%S",FileObject->FileName.Buffer);

	if (ret<0)
	{
		return (!STATUS_SUCCESS);
	}

     RelateObject=FileObject->RelatedFileObject;

	if ('\\'!=CUFileName[0] && NULL!=RelateObject && 
		NULL!=RelateObject->FileName.Buffer && 0!=RelateObject->FileName.Length)
	{
		if (RelateObject->FileName.Buffer[RelateObject->FileName.Length/2-1]==L'\\' )
		{
			_snprintf(Temp,511,"%S%s",RelateObject->FileName.Buffer,CUFileName);
			copy_inA(CUFileName,512,Temp);
		}   
		else
		{
			_snprintf(Temp,511,"%S\\%s",RelateObject->FileName.Buffer,CUFileName);
			copy_inA(CUFileName,512,Temp);
		}
	}
	if ('\\'!=CUFileName[0])
	{
		_snprintf(Temp,511,"X:\\%s",CUFileName);
		copy_inA(CUFileName,512,Temp);
	}
	else
	{
		_snprintf(Temp,511,"X:%s",CUFileName);
		copy_inA(CUFileName,512,Temp);
	}

	ASSERT((CUFileName[2]=='\\' && CUFileName[3]!='\\'));

	CUFileName[0]=hookExt->LogicalDrive;

	ret=_snprintf(pAnsiString,StringLength,"%s",CUFileName);
	if (ret<0)
		return (!STATUS_SUCCESS);
	else
		return (STATUS_SUCCESS);
}


//
// 注意:pWString 要求在函数调用前已经分配好空间
//
NTSTATUS 
GetFileFullNameByObjectW(
						 IN PFILE_OBJECT FileObject,
						 IN PHOOK_EXTENSION hookExt,
						 IN OUT WCHAR * pWString,
						 IN int       StringLength
						 )
{	
	WCHAR Temp[256];
	WCHAR CUFileName[256]={0};
	int ret=_snwprintf(CUFileName,255,L"%s",FileObject->FileName.Buffer);
	PFILE_OBJECT RelateObject;

	ASSERT(pWString!=NULL);

	if (ret<0)
	{
		return (!STATUS_SUCCESS);
	}

	RelateObject=FileObject->RelatedFileObject;

	if (L'\\'!=CUFileName[0] && NULL!=RelateObject && 
		NULL!=RelateObject->FileName.Buffer && 0!=RelateObject->FileName.Length)
	{
		if (RelateObject->FileName.Buffer[RelateObject->FileName.Length/2-1]==L'\\' )
		{
			_snwprintf(Temp,255,L"%s%s",RelateObject->FileName.Buffer,CUFileName);
			copy_inW(CUFileName,255,Temp);
		}   
		else
		{
			_snwprintf(Temp,255,L"%s\\%s",RelateObject->FileName.Buffer,CUFileName);
			copy_inW(CUFileName,255,Temp);
		}
	}
	if (L'\\'!=CUFileName[0])
	{
		_snwprintf(Temp,255,L"X:\\%s",CUFileName);
		copy_inW(CUFileName,255,Temp);
	}
	else
	{
		_snwprintf(Temp,255,L"X:%s",CUFileName);
		copy_inW(CUFileName,255,Temp);
	}

	ASSERT((CUFileName[2]==L'\\' && CUFileName[3]!=L'\\'));

	CUFileName[0]=(WCHAR)hookExt->LogicalDrive;

	ret=_snwprintf(pWString,StringLength-1,L"%s",CUFileName);
	if (ret<0)
		return (!STATUS_SUCCESS);
	else
		return (STATUS_SUCCESS);
}

BOOL 
Is_Exist_File(
			  PHOOK_EXTENSION pHookExt,
			  PFILE_OBJECT pFileObject
			  )
{
	WCHAR     WTarget[512]={0};

	UNICODE_STRING  CUTarget;

	PFILE_OBJECT	  pTargetFileObject=NULL; 
	HANDLE			  TargetFileHandle;
	FILE_OBJECT		  TargetFileObject;
	VCB				  TargetVCB;
	OBJECT_ATTRIBUTES TargetAttributes;

	ULONG ThrowInf; // We don't want to see the value of the returned informatiom
	// So throw it.
	NTSTATUS ntStatus;


	RtlInitUnicodeString(&CUTarget,WTarget);
	CUTarget.MaximumLength=1024;

	_snwprintf(WTarget,511,L"X:%s",pFileObject->FileName.Buffer);

	WTarget[0]=(WCHAR)pHookExt->LogicalDrive;
	// Build VCB. here , the next lower device and real device are the same
	TargetVCB=pHookExt->Vcb;
	// Then we should initialize the file object's attributes
	InitializeObjectAttributes(
		&TargetAttributes,
		&CUTarget,
		OBJ_CASE_INSENSITIVE,
		NULL, NULL
		);

	ntStatus=FsTPMCreateFile(&TargetVCB,
		FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA,
		&TargetAttributes,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		FILE_OPEN ,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0,
		FILE_SYNCHRONOUS_IO_NONALERT,
		&ThrowInf,
		&TargetFileObject,
		&TargetFileHandle
		);

	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(("Create Target File Failed!\n"));
		ZwClose(TargetFileHandle);
		return FALSE;
	}

	ZwClose(TargetFileHandle);

	ObDereferenceObject( &TargetFileObject );

	return TRUE;
}

BOOL 
Is_Directory_File(
				  ULONG Options
				  )
{
	if (Options & FILE_DIRECTORY_FILE)
		return TRUE;	
	else
		return FALSE;
}


//
//TargetFileName like C:\A.TXT , SourceFileName is so 
//
NTSTATUS 
FsTPMCopyFileByName(
					  IN WCHAR* TargetFileName,
					  IN WCHAR* SourceFileName,
					  IN PFILE_OBJECT pSourceFileObject
					  )
{
	// We make the string like this "\??\B:\*.*"
	WCHAR           UTarget[256]=L"";
	UNICODE_STRING	CUTarget;

	WCHAR           USource[256]=L"";
	UNICODE_STRING	CUSource;

	PFILE_OBJECT pTargetFileObject=NULL; 
	HANDLE		 TargetFileHandle=NULL,SourceFileHandle=NULL;
	FILE_OBJECT TargetFileObject,SourceFileObject;
	VCB				  TargetVCB,SourceVCB;
	OBJECT_ATTRIBUTES TargetAttributes,SourceAttributes;

	ULONG ThrowInf; // We don't want to see the value of the returned informatiom
	// So throw it.
	NTSTATUS ntStatus;

	_snwprintf(UTarget,255,L"%s",TargetFileName);
	RtlInitUnicodeString(&CUTarget,&UTarget[2]);
	CUTarget.MaximumLength=512;
	_snwprintf(USource,255,L"%s",SourceFileName);
	RtlInitUnicodeString(&CUSource,&USource[2]);
	CUSource.MaximumLength=512;


	// We should make sure the path's name is like this : "C:\*\*.*"
	ASSERT( (TargetFileName[0]>=L'A' && TargetFileName[0]<=L'Z')&&
		(SourceFileName[0]>=L'A' && SourceFileName[0]<=L'Z'));

	ntStatus=FsTPMCreateDirectory(UTarget);
	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(("Create Directory Fail!\n"));
		return ntStatus;
	}

	FsTPM_DbgPrint(("Enter Copy File now!!!\n"));

	// Build VCB. here , the next lower device and real device are the same
	TargetVCB=((PHOOK_EXTENSION)(DriveHookDevices[TargetFileName[0]-L'A']->DeviceExtension))->Vcb;

	SourceVCB=((PHOOK_EXTENSION)(DriveHookDevices[SourceFileName[0]-L'A']->DeviceExtension))->Vcb;

	// Then we should initialize the file object's attributes
	InitializeObjectAttributes(
		&TargetAttributes,
		&CUTarget,
		OBJ_CASE_INSENSITIVE,
		NULL, NULL
		);

	ntStatus=FsTPMCreateFile(&TargetVCB,
		FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA,
		&TargetAttributes,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		FILE_OPEN_IF ,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0,
		FILE_SYNCHRONOUS_IO_NONALERT,
		&ThrowInf,
		&TargetFileObject,
		&TargetFileHandle
		);
	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(("Create Target File Failed!"));
		ErrorString(ntStatus);

		return ntStatus;
	}
	ntStatus = ObReferenceObjectByHandle( TargetFileHandle, FILE_READ_DATA|FILE_WRITE_DATA, 
		NULL, KernelMode, (void**)&pTargetFileObject, NULL );
	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(("Get Target File Object Fail :Reason: "));
		ErrorString(ntStatus);
		return ntStatus;
	} 

	ASSERT(pTargetFileObject!=NULL);


	if (NULL==pSourceFileObject)
	{
		InitializeObjectAttributes(
			&SourceAttributes,
			&CUSource,
			OBJ_CASE_INSENSITIVE,
			NULL, NULL
			);

		ntStatus=FsTPMCreateFile(&SourceVCB,
			FILE_READ_DATA|SYNCHRONIZE,
			&SourceAttributes,
			0,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ|FILE_SHARE_WRITE,
			FILE_OPEN_IF ,
			FILE_SYNCHRONOUS_IO_ALERT,
			NULL,
			0,
			FILE_SYNCHRONOUS_IO_ALERT,
			&ThrowInf,
			&SourceFileObject,
			&SourceFileHandle
			);	

		if (!NT_SUCCESS(ntStatus))
		{
			FsTPM_DbgPrint(("Create Source File Failed!"));
			ErrorString(ntStatus);

			return ntStatus;
		}

		ntStatus = ObReferenceObjectByHandle( SourceFileHandle, FILE_READ_DATA, 
			NULL, KernelMode, (void**)&pSourceFileObject, NULL );

		if (!NT_SUCCESS(ntStatus))
		{
			FsTPM_DbgPrint(("Get Source File Object Fail :Reason: "));
			ErrorString(ntStatus);

		} 
		ASSERT(pSourceFileObject!=NULL);
	}
	else
	{
		// FsTPM_DbgPrint(("Source File Object Count = %d \n",ObGetObjectPointerCount(pSourceFileObject)));

		ntStatus = ObReferenceObjectByPointer( pSourceFileObject, FILE_READ_DATA, 
			NULL,KernelMode );

		if (!NT_SUCCESS(ntStatus))
		{
			FsTPM_DbgPrint(("Inc File Object Count  Error: "));
			ErrorString(ntStatus);
			return ntStatus;
		} 
	}
	
	ntStatus=FsTPMCopyFile(pTargetFileObject,pSourceFileObject,SourceVCB.NextLowerDevice,TargetVCB.NextLowerDevice);

	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(("Copy File Failed!"));
		ErrorString(ntStatus);

		return ntStatus;
	}
	else
	{
		FsTPM_DbgPrint((("Copy File Success! \n")));
	}


	// We should close the handle
	ObDereferenceObject(pTargetFileObject);

	ObDereferenceObject(pSourceFileObject);

	// FsTPM_DbgPrint(("After Dereference Source File Object Count = %d \n",ObGetObjectPointerCount(pSourceFileObject)));

	FsTPM_DbgPrint((("Now Close Source File !\n")));

	if (NULL!=SourceFileHandle)
	{
		ntStatus=ZwClose(SourceFileHandle);
		if (!NT_SUCCESS(ntStatus))
		{
			FsTPM_DbgPrint(("Close Source File Failed! "));
			ErrorString(ntStatus);
			return ntStatus;
		}
	}

	FsTPM_DbgPrint((("Now Close Source File !\n")));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -