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

📄 specialiofunction.cpp

📁 一个过滤层文件系统驱动的完整代码,实现了文件的加密,操作截获等
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	ntStatus=ZwClose(TargetFileHandle);
	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(("Close Target File Failed!"));
		ErrorString(ntStatus);
		return ntStatus;
	}
	return STATUS_SUCCESS;
}


NTSTATUS
FsTPMCopyFile(
				PFILE_OBJECT TargetFileObject, 
				PFILE_OBJECT SourceFileObject,
				PDEVICE_OBJECT pSourceDeviceObject,
				PDEVICE_OBJECT pTargetDeviceObject
				)
				//++
				// Function:	FsTPMCopyFile
				//
				// Description:
				//		Copy file 
				//
				// Arguments:
				//		TargetFileObject - Target file object 
				//		SourceFileObject - Source file object
				//
				// Return value:
				//		STATUS_SUCCESS if successful,
				//		STATUS_UNSUCCESSFUL otherwise
				//
				// Notice :
				//		This function is provided by OSR
				//--
{
	PVOID buffer;
	PMDL mdl;
	IO_STATUS_BLOCK iosb;
	FILE_STANDARD_INFORMATION standardInformation;
	LARGE_INTEGER currentOffset;
	LONGLONG bytesToTransfer;


	//
	// The algorithm used by this routine is straight-forward: read 64k chunks from the
	// source file and write it to the target file, until the entire file itself has been copied.
	//

	buffer = ExAllocatePoolWithTag(NonPagedPool,
		MAX_TRANSFER_SIZE,
		'BcfK');


	if (!buffer) {
		//
		// Allocation must have failed.
		//

		return STATUS_INSUFFICIENT_RESOURCES;

	}

	//
	// Build an MDL describing the buffer.  We'll use THAT to do the
	// I/O (rather than a direct buffer address.)
	//

	mdl = IoAllocateMdl(buffer, MAX_TRANSFER_SIZE, FALSE, TRUE, 0);

	MmBuildMdlForNonPagedPool(mdl);

	//
	// Set up the current offset information
	//

	currentOffset.QuadPart = 0;

	//
	// Get the size of the input file.
	//

	FsTPMGetFileStandardInformation(SourceFileObject, &standardInformation, &iosb,pSourceDeviceObject);

	if (!NT_SUCCESS(iosb.Status)) {
		//
		// This is a failure condition.
		//

		return (iosb.Status);

	}

	//
	// Set the allocation size of the output file.
	//

	FsTPMSetFileAllocation(TargetFileObject,
		&standardInformation.AllocationSize,
		&iosb,pTargetDeviceObject);

	if (!NT_SUCCESS(iosb.Status)) {

		//
		// Failure...
		//

		return (iosb.Status);

	}

	//
	// Save away the information about the # of bytes to transfer.
	//

	bytesToTransfer = standardInformation.EndOfFile.QuadPart;

	//
	// Now copy the source to the target until we run out...
	//

	while (bytesToTransfer) {
		ULONG nextTransferSize;

		//
		// The # of bytes to copy in the next operation is based upon the maximum of
		// the balance IN the file, or KFC_MAX_TRANSFER_SIZE
		//

		nextTransferSize = (bytesToTransfer < MAX_TRANSFER_SIZE) ?
			(ULONG) bytesToTransfer : MAX_TRANSFER_SIZE;

		FsTPMRead(SourceFileObject, &currentOffset, nextTransferSize, mdl, &iosb,pSourceDeviceObject);

		if (!NT_SUCCESS(iosb.Status)) {

			//
			// An error condition occurred.
			//

			return (iosb.Status);

		}

		FsTPMWrite(TargetFileObject, &currentOffset, nextTransferSize, mdl, &iosb,pTargetDeviceObject);

		if (!NT_SUCCESS(iosb.Status)) {

			//
			// An error condition occurred.
			//

			return (iosb.Status);

		}

		//
		// Now, update the offset/bytes to transfer information
		//

		currentOffset.QuadPart += nextTransferSize;

		bytesToTransfer -= nextTransferSize;

	}

	//
	// At this point, we're done with the copy operation.  Return success
	// 

	return (STATUS_SUCCESS);
}


// Notice  you should be sure that the file is shared.
NTSTATUS
FsTPMCreateFileObject(
						IN PWCHAR TargetFileName,
						OUT PFILE_OBJECT* ppFileObject
						)
{
	//WCHAR  *UTarget=NULL;
	//UTarget=(WCHAR*)ExAllocatePool(NonPagedPool,512);

	WCHAR UTarget[256];
	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;

	_snwprintf(UTarget,256,L"\\??\\%s",TargetFileName);
	RtlInitUnicodeString(&CUTarget,UTarget);
	CUTarget.MaximumLength=512;

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

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

	FsTPM_DbgPrint(("Enter Create File Object now!!!\n"));

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

//	ntStatus=ZwCreateFile(&TargetFileHandle,
//				FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA|DELETE,
//				&TargetAttributes,
//				&temp,
//				0,
//				FILE_ATTRIBUTE_NORMAL,
//				FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
//				FILE_OPEN_IF ,
//				FILE_SYNCHRONOUS_IO_ALERT,
//				NULL,
//				0
//				);
//				
	ntStatus=FsTPMCreateFile(&TargetVCB,
		FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA|DELETE,
		&TargetAttributes,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
		FILE_OPEN_IF ,
		FILE_SYNCHRONOUS_IO_ALERT,
		NULL,
		0,
		FILE_SYNCHRONOUS_IO_ALERT,
		&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\n")));
		ErrorString(ntStatus);
		return ntStatus;
	} 
	ASSERT(pTargetFileObject!=NULL);

	*ppFileObject=pTargetFileObject;

	return STATUS_SUCCESS;
}


VOID 
FsTPMWriteIRP(
			 PFILE_OBJECT FileObject,
			 PDEVICE_OBJECT   pDevice,
			 PIRP             pOrgIrp,
			 PIO_STACK_LOCATION pOrgIoStk,
			 PIO_STATUS_BLOCK IoStatusBlock,
			 PMDL mdl
			 )
			 //++
			 // Function:	FsTPMWriteIRP
			 //
			 // Description:
			 //		This routine is used to write to the file object from memory discribed by MDL
			 //
			 // Arguments:
			 //PFILE_OBJECT     FileObject,
			 //PDEVICE_OBJECT   pDevice,
			 //PIRP             pOrgIrp,
			 //PIO_STACK_LOCATION pOrgIoStk
			 //PIO_STATUS_BLOCK IoStatusBlock,
			 //
			 // Return value:
			 //		None
{
	PIRP irp;
	KEVENT event;
	PIO_STACK_LOCATION ioStackLocation;
	PDEVICE_OBJECT fsdDevice =pDevice;

	//
	// Set up the event we'll use.
	//

	KeInitializeEvent(&event, SynchronizationEvent, FALSE);


	//
	// Allocate and build the IRP we'll be sending to the FSD.
	//

	irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);

	if (!irp) {

		//
		// Allocation failed, presumably due to memory allocation failure.
		//

		IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;

		IoStatusBlock->Information = 0;
		
		return ;
	}

	irp->AssociatedIrp.SystemBuffer = pOrgIrp->AssociatedIrp.SystemBuffer;

	irp->MdlAddress = pOrgIrp->MdlAddress;

	irp->UserBuffer=pOrgIrp->UserBuffer;

	irp->UserEvent = &event;

	irp->UserIosb = IoStatusBlock;

	irp->Tail.Overlay.Thread = PsGetCurrentThread();

	irp->Tail.Overlay.OriginalFileObject= FileObject;

	irp->RequestorMode = KernelMode;


	//
	// Indicate that this is a WRITE operation.
	//

	irp->Flags = IRP_WRITE_OPERATION;


	//
	// Set up the next I/O stack location.  These are the parameters
	// that will be passed to the underlying driver.
	//

	ioStackLocation = IoGetNextIrpStackLocation(irp);

	ioStackLocation->MajorFunction = pOrgIoStk->MajorFunction;

	ioStackLocation->MinorFunction = pOrgIoStk->MinorFunction;

	ioStackLocation->DeviceObject = fsdDevice;

	ioStackLocation->FileObject = FileObject;


	//
	// We use a completion routine to keep the I/O Manager from doing
	// "cleanup" on our IRP - like freeing our MDL.
	//

	IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);

	ioStackLocation->Parameters.Write.Length = pOrgIoStk->Parameters.Write.Length;

	ioStackLocation->Parameters.Write.ByteOffset = pOrgIoStk->Parameters.Write.ByteOffset;

	ioStackLocation->Parameters.Write.Key = pOrgIoStk->Parameters.Write.Key;


	//
	// Send it on.  Ignore the return code.
	//

	(void) IoCallDriver(fsdDevice, irp);


	//
	// Wait for the I/O to complete.
	//

	KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);


	//
	// Done.  Return results are in the io status block.
	//

	return;

}



NTSTATUS 
GetFileFullNameByQuery(	
					   OUT PUNICODE_STRING SourceFileName,
					   IN  PHOOK_EXTENSION pHookExt ,
					   IN	PFILE_OBJECT  FileObject
					   )
{
	VCB Vcb;
	ULONG ResultLen;
	NTSTATUS ntStatus;

	WCHAR   USName[256];

	_snwprintf(USName,256,L"A:");

	UNICODE_STRING CUSourceName;

	RtlInitUnicodeString(&CUSourceName,USName);
	CUSourceName.MaximumLength=512;

	Vcb=pHookExt->Vcb;

	PFILE_NAME_INFORMATION fileNameInfo;

	if (0==FileObject->FileName.Length)   // 我不知道为什么会有这样的情况
		return STATUS_UNSUCCESSFUL;

	//调查"家底",确认其真实文件名
	fileNameInfo = (PFILE_NAME_INFORMATION)ExAllocatePool( NonPagedPool, MAXPATHLEN*sizeof(WCHAR));

	if (NULL==fileNameInfo)
	{
		FsTPM_DbgPrint((("Memory Allocate Fail!\n")));
		if (fileNameInfo!=NULL)
			ExFreePool(fileNameInfo);
		return STATUS_UNSUCCESSFUL;
	}
	ntStatus=FsTPMQueryInformationFile(&Vcb,FileObject,FileNameInformation,fileNameInfo,(MAXPATHLEN-5)*sizeof(WCHAR),&ResultLen);
	if (!NT_SUCCESS(ntStatus))
	{
		FsTPM_DbgPrint(((" Query Name Information of file Fail\n")));
		ErrorString(ntStatus);
		if (fileNameInfo!=NULL)
			ExFreePool(fileNameInfo);
		return ntStatus;
	}

	fileNameInfo->FileName[fileNameInfo->FileNameLength/2]=0;

	_snwprintf(CUSourceName.Buffer+wcslen(CUSourceName.Buffer),256-wcslen(CUSourceName.Buffer),L"%s",fileNameInfo->FileName);

	CUSourceName.Buffer[0]=(WCHAR)(pHookExt->LogicalDrive);

	CUSourceName.Length=wcslen(CUSourceName.Buffer)*sizeof(WCHAR);

	RtlCopyUnicodeString( SourceFileName, &(UNICODE_STRING)CUSourceName );

	if (fileNameInfo!=NULL)
		ExFreePool(fileNameInfo);

	return STATUS_SUCCESS;
}



VOID CreateFileSizeZero(PUNICODE_STRING pUniFile,BOOL isdir)
{
	// Then we should initialize the file object's attributes
	UNICODE_STRING uFile;
	FILE_OBJECT fileobject;
	HANDLE      fileHandle;
	ULONG       ThrowInf;

	ULONG op1;
	ULONG op2;
	NTSTATUS ntStatus;
	OBJECT_ATTRIBUTES FileAttrib;

	RtlInitUnicodeString(&uFile,&pUniFile->Buffer[2]);
	
	InitializeObjectAttributes(
		&FileAttrib,
		&uFile,
		OBJ_CASE_INSENSITIVE,
		NULL, NULL
		);

	if (isdir)
	{
		op1=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING|FILE_DIRECTORY_FILE;
		op2=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING|FILE_DIRECTORY_FILE;
	}
	else
	{
		op1=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING;
		op2=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING;
	}

	ntStatus=FsTPMCreateFile(&(((PHOOK_EXTENSION)(DriveHookDevices[pUniFile->Buffer[0]-L'A']->DeviceExtension))->Vcb),
		FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA,
		&FileAttrib,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		FILE_CREATE ,
		op1,
		NULL,
		0,
		op2,
		&ThrowInf,
		&fileobject,
		&fileHandle
		);

	ZwClose(fileHandle);
}


//----------------------------------------------------------------------
//
// FsTPMGetProcess
//
// Uses undocumented data structure offsets to obtain the name of the
// currently executing process.
//
//----------------------------------------------------------------------
PCHAR
FsTPMGetProcess( 
				  PCHAR ProcessName 
				  )
{
	PEPROCESS       curproc;
	char            *nameptr;
	//    ULONG           i;

	//
	// We only do this if we determined the process name offset
	//
	if( ProcessNameOffset ) {

		//
		// Get a pointer to the current process block
		//
		curproc = PsGetCurrentProcess();

		//
		// Dig into it to extract the name. Make sure to leave enough room
		// in the buffer for the appended process ID.
		//
		nameptr   = (PCHAR) curproc + ProcessNameOffset;

		strncpy( ProcessName, nameptr, NT_PROCNAMELEN-1 );
		ProcessName[NT_PROCNAMELEN-1] = 0;
		//       sprintf( ProcessName + strlen(ProcessName), ":%d", PsGetCurrentProcessId());

	} else {

		strcpy( ProcessName, "???" );
	}
	return ProcessName;
}

//----------------------------------------------------------------------
//
// FsTPMGetProcessNameOffset
//
// In an effort to remain version-independent, rather than using a
// hard-coded into the KPEB (Kernel Process Environment Block), we
// scan the KPEB looking for the name, which should match that
// of the system process. This is because we are in the system process'
// context in DriverEntry, where this is called.
//
//----------------------------------------------------------------------
ULONG 
FsTPMGetProcessNameOffset(
						  VOID
						  )
{
	PEPROCESS       curproc;
	int             i;

	curproc = PsGetCurrentProcess();

	//
	// Scan for 12KB, hoping the KPEB never grows that big!
	//
	for( i = 0; i < 3*PAGE_SIZE; i++ ) {

		if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {

			return i;
		}
	}

	//
	// Name not found - oh, well
	//
	return 0;
}

⌨️ 快捷键说明

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