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

📄 fghook.cpp

📁 文件加密的过滤驱动程序源代码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// FGHOOK.cpp - main module for VxD FGHOOK

#define DEVICE_MAIN
#include "FGHOOK.h"
Declare_Virtual_Device(FGHOOK)
#undef DEVICE_MAIN

ppIFSFileHookFunc PrevHookProc=NULL;			//Previos hook function.

KProtectedFileList protFileList;
KProtectedFileList recycledPathList;        //Path of Recycle.

KHandleTable	findHTable, openHTable;
KHotKey		*pHotKey;

HANDLE hIniFile,hVM;
HANDLE hAppWnd=NULL;										//Handle of win32 app.
char iniFilePath[MAX_PATH+1]="";
ParsedPath *pPPath;

BOOL bBusy, bAppReqBusy=FALSE;							//bAppReqBusy--win32 app is about be write file.
WORD lastError=FG_ERR_SUCCESS;
UINT maxBakNum=DEF_MAX_BAK_NUM;		//max backup file number.

//NOTICE: I don't know whether more than one object files will be linked properly,
//(And I haven't try it.) So I just include other cpp files in the main cpp file. 
//This did not cause any problem.
#include "..\HookShr\KProtectedFileList.cpp"
#include "..\HookShr\HookCom.cpp"
#include "KHandleTable.cpp"
#include "KHotKey.cpp"

///////////////////////////////////////////////////////////////////
//Main interface:
FGHookVM::FGHookVM(VMHANDLE hVM) : VVirtualMachine(hVM) {}

FGHookThread::FGHookThread(THREADHANDLE hThread) : VThread(hThread) {}


BOOL FGHookDevice::OnSysDynamicDeviceInit()
{
#ifdef DEBUG
		dout << "Hello from FGHook!" << endl;
#endif
	
	bBusy=FALSE;

	if(!(pPPath=(ParsedPath *)malloc(MAX_PATH*sizeof(WCHAR)+sizeof(ParsedPath))))
	{
		ErrorHandler(FG_ERR_NOT_ENOUGH_MEMORY);
		ShellUnloadDevice();
		return FALSE;
	}

	//Add recycled path.
	int i;
	char recycledPath[MAX_PATH]="A:\\RECYCLED\\*";
	for(i=1; i<=32; i++)		//Windows supports up to 32 drives.
	{
		recycledPath[0]=i+'A'-1;
		recycledPathList.Add(recycledPath);
	}

	//intall key board hook:
	pHotKey=new KHotKey;
	pHotKey->hook();

	return TRUE;
}

BOOL FGHookDevice::OnSysDynamicDeviceExit()
{
	free(pPPath);
	if(PrevHookProc)
		IFSMgr_RemoveFileSystemApiHook(HookProc);

	delete pHotKey;

#ifdef DEBUG
	dout<<"Hook exit."<<endl;
#endif

	return TRUE;
}

#ifdef DEBUG
void PrintUni(WCHAR *p, unsigned int len)
{
	int i=0;

	while(p[i] && i<len)
		dout<<(char)p[i++];
	
	dout<<endl;
	i=0;
	while(p[i] && i<len)
		dout<<p[i++]<<" ";

	dout<<endl;
}
#endif



DWORD FGHookDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
	switch(pDIOCParams->dioc_IOCtlCode)
	{
		case DIOC_OPEN:
			//SHELL_Message(pDIOCParams->dioc_hvm,MB_OK,"Device initialize.","FGHook message:",0,0,0);
			break;

#ifdef DEBUG
		case FG_DIOC_DEBUG:	
			break;
#endif

		case FG_DIOC_INSTALL_HOOK:
#ifdef DEBUG
			dout<<"Now install hook..."<<endl;
#endif
			if((PrevHookProc=IFSMgr_InstallFileSystemApiHook(HookProc))==NULL)
				ErrorHandler(FG_ERR_INSTALL_HOOK_FAIL);
			protFileList.bDelBak=(UINT)pDIOCParams->dioc_InBuf & 0x1;						//Get del & write proteciton options.
			protFileList.bWriteBak=(((UINT)pDIOCParams->dioc_InBuf & 0x2)== 0x2);
			break;

		case FG_DIOC_UNINSTALL_HOOK:
			if(PrevHookProc && IFSMgr_RemoveFileSystemApiHook(HookProc)==0)
					PrevHookProc=NULL;
			break;

		case FG_DIOC_GET_HWND:
			hAppWnd=*((HANDLE *)pDIOCParams->dioc_InBuf);		//Retrieve hwnd of main window of win32 app.
			break;

		case FG_DIOC_FLUSH_PROTECTED_FILE_INFO: //==FG_DIOC_READ_PROTECTED_FILE_INFO
			//Flush file information by reread from ini file.
			protFileList.Empty();
			if(pDIOCParams->dioc_InBuf)
				strcpy(iniFilePath,(char *)pDIOCParams->dioc_InBuf);
			else if(!*iniFilePath)  strcpy(iniFilePath, "ProtFile.ini");			//default ini path.
#ifdef DEBUG
			dout<<"INI Path:"<<iniFilePath<<endl;
#endif
			ReadProtectedFileInfo(iniFilePath);
			break;

		case FG_DIOC_ADD_PROTECTED_FILE:
			//Add new protected file.
			protFileList.Add((PROTECTED_FILE *)pDIOCParams->dioc_InBuf);
			break;

		case FG_DIOC_REMOVE_PROTECTED_FILE:
			protFileList.Remove((char *)pDIOCParams->dioc_InBuf);
			break;

		case FG_DIOC_EXTRA_INFO:
			protFileList.bDelBak=(UINT)pDIOCParams->dioc_InBuf & 0x1;						//Get del & write proteciton options.
			protFileList.bWriteBak=(((UINT)pDIOCParams->dioc_InBuf & 0x2)== 0x2);
			maxBakNum=(UINT)pDIOCParams->dioc_OutBuf;
			break;

		case FG_SET_DEVICE_BUSY:
			bAppReqBusy=(BOOL)pDIOCParams->dioc_InBuf;
			break;
	}

	_asm clc
	return 0;
}

VOID FGHookDevice::PM_API_Entry(VMHANDLE hVM, CLIENT_STRUCT* pRegs)
{
}

//Hook Procedure:	all protection is done though this function.
// Argument         : pIFSFunc pfn
//		address of the function which will perform this file operation.
// Argument         : int fn
//		number of the function which will perform this file operation.
// Argument         : int CodePage
//		current code page.
// Argument         : pioreq pir
//		It is the parameter to be passed to FSD function pfn. 
//		In many cases, pir->ir_ppath contain ParsedPath.
int _cdecl HookProc(pIFSFunc pfn, int fn, int Drive, int ResType, int CodePage, pioreq pir)
{
	struct _QWORD res;
	BOOL bLogHandle=FALSE;		//Determine whether to add a handle to handle table(use in IFSFN_OPEN);

	//bAppReqBusy: Win32 application of fileguard request busy.		bBusy: used to prevent reentry.
	if(bAppReqBusy || bBusy) 
		goto EXIT;

	bBusy=TRUE;

	if(protFileList.bIsHideOn && (fn==IFSFN_FILEATTRIB || fn==IFSFN_DIR || fn==IFSFN_SEARCH || fn==IFSFN_RENAME))
	{
		//Hide a file:
		if(protFileList.IsUnderProtection(Drive, pir->ir_ppath, PT_HIDE)) 
			{
				bBusy=FALSE;
				return (IFSFN_DIR? ERROR_PATH_NOT_FOUND : ERROR_FILE_NOT_FOUND);	
			}
	}
	

	switch(fn)
	{
	case IFSFN_DELETE:
		{
			//do delete protection:

			if(!protFileList.bIsDelOn && !protFileList.bIsHideOn)
				//If there is not protected file has protection type of PT_DELETE or PT_HIDE, skip.
				break;
		
			if(DoDeleteProtection(pir, Drive, CodePage)!=ERROR_SUCCESS)
			{
				bBusy=FALSE;
				return pir->ir_error;
			}
			break;
		}		//case IFSFN_DELETE

	case IFSFN_RENAME:
		{
			//prevent moving protected file to recycled.

			if(!protFileList.bIsDelOn && !protFileList.bIsHideOn)	
				//If there is not protected file has protection type of PT_DELETE or PT_HIDE, skip.
				break;
		
			//Is the file being renamed to the recycle?
			if(!recycledPathList.IsUnderProtection(Drive, pir->ir_ppath2) 
				|| DoDeleteProtection(pir, Drive, CodePage)==ERROR_SUCCESS)
				break;

			bBusy=FALSE;
			return pir->ir_error;
		}		//case IFSFN_RENAME

	case IFSFN_OPEN:
		{
			//If a file is opened with ACTION_REPLACEEXISTING, content of the file will be lost.
			//so prevent this.
			//And prevent opening hidden file.

			//Determine whether or not to log open handle:
			PROTECTED_FILE *pProtFile;
			if(!(pProtFile=protFileList.IsUnderProtection(Drive, pir->ir_ppath)))
				break;
			else if(pProtFile->PF_type&(PT_READ|PT_DELETE))
				bLogHandle=TRUE;

			//determine whether the file is under protection.
			if(!(protFileList.bIsHideOn || protFileList.bIsDelOn) || !(pProtFile=protFileList.IsUnderProtection(Drive, pir->ir_ppath, PT_DELETE|PT_HIDE)))
				break;

			if(!(ACTION_REPLACEEXISTING&pir->ir_options) && !(pProtFile->PF_type&PT_HIDE))
				//the file is not to be hidden and it is not opened with ACTION_REPLACEEXISTING, skip.
				break;

			if(pProtFile->PF_type&PT_HIDE)		
			{
				//protect hidden file.
				bBusy=FALSE;
				pir->ir_error=ERROR_FILE_NOT_FOUND;
				return pir->ir_error;
			}
			else if(!protFileList.bDelBak)		
			{
				//deny file operation.
				ShellPostError(FG_ERR_WARNING, FG_WARN_PT_DELETE);           //Send a warning.
				bBusy=FALSE;
				pir->ir_error=ERROR_ACCESS_DENIED;
				return pir->ir_error;
			}

			//protect the file by rename it to *.BAK .
			char pBCSPath[MAX_PATH+1];
			UniToBCSPathEx((PUCHAR)pBCSPath,pir->ir_ppath->pp_elements,Drive,MAX_PATH,CodePage,&res);	
			if(FileRename(pBCSPath)==ERROR_SUCCESS)
			{
				//The file exists, so recreate it. 
				WORD error;
				BYTE action;
				HANDLE h=R0_OpenCreateFile(TRUE,pBCSPath,0,ATTR_NORMAL,ACTION_IFEXISTS_FAIL|ACTION_IFNOTEXISTS_CREATE,0,&error,&action);
				R0_CloseFile(h,&error);
			}
			break;
		}	//case IFSFN_OPEN	

		case IFSFN_WRITE:
		{
			//do write protection.

			if(!protFileList.bIsWriteOn)
				//If there is not protected file has protection type of PT_WRITE, skip.
				break;

			//sometimes, a process writes zero bytes only to verify.
			if(pir->ir_length==0) break;
        	
			//get full path.
			int drive=Drive;
			if(!GetFullNameByHandle(pir,drive,ResType,CodePage,pPPath, FALSE)) 
				break;

			//determine whether the file is under protection.
			if(!protFileList.IsUnderProtection(drive, pPPath, PT_WRITE))
				break;
			
			if(!protFileList.bWriteBak)		
			{
				//Deny write.
				ShellPostError(FG_ERR_WARNING, FG_WARN_PT_WRITE);           //Send a warning.
				bBusy=FALSE;
				pir->ir_error=ERROR_ACCESS_DENIED;
				return pir->ir_error;
			}

			//protect the file by copying it to the .BAK file.
			char pBCSPath[MAX_PATH+1];
			UniToBCSPathEx((PUCHAR)pBCSPath,pPPath->pp_elements,Drive,MAX_PATH,CodePage,&res);	
			if(FileBackupByHandle(pir,drive,ResType,CodePage,pBCSPath)!=ERROR_SUCCESS && FileBackup(pBCSPath)!=ERROR_SUCCESS)
			{
				//if fail to back up the file then deny access.
				bBusy=FALSE;
				pir->ir_error=ERROR_ACCESS_DENIED;
				return pir->ir_error;
			}
			break;
		}		//case IFSFN_WRITE

	case IFSFN_READ:
		{
			//prevent process to read protected file.

			//Read protection is not on or it is a pagging file.
			if(!protFileList.bIsReadOn)
				break;

			//Get full path.
			int drive=Drive;
			if(!GetFullNameByHandle(pir,drive,ResType,CodePage,pPPath, FALSE)) 
				break;

			//determine whether the file is under protection.
			if(!protFileList.IsUnderProtection(drive, pPPath, PT_READ))
				break;

			//deny read
			ShellPostError(FG_ERR_WARNING, FG_WARN_PT_READ);           //Send a warning.
			bBusy=FALSE;
			pir->ir_error=ERROR_ACCESS_DENIED;
			return pir->ir_error;

			break;
		}		//case IFSFN_READ

	}

	bBusy=FALSE;	
	EXIT:	
	int nRetVal=(*PrevHookProc)(pfn,fn,Drive,ResType,CodePage,pir);

	//Win32 application of fileguard request busy.
	if(bAppReqBusy)
		return nRetVal;

	//log open handle.
	if(bLogHandle)
		openHTable.Add(pir->ir_fh, Drive, pir->ir_ppath);

	//if find or file is closed, delete the handle in handle table.
	if(fn==IFSFN_FINDCLOSE)
		findHTable.Delete(pir->ir_fh);
	else if(fn==IFSFN_CLOSE && pir->ir_flags==CLOSE_FINAL)
		openHTable.Delete(pir->ir_fh);

	if(!bBusy && protFileList.bIsHideOn && !nRetVal && (fn==IFSFN_FINDNEXT || fn==IFSFN_FINDOPEN))
	{
		//Hide file in file operation FINDOPEN & FINDNEXT. 

		bBusy=TRUE;

		int drive=Drive;
		_WIN32_FIND_DATA   *findData;

		//Get search path:
		switch(fn)
		{
			case IFSFN_FINDOPEN:
				memcpy(pPPath, pir->ir_ppath, IFSPathSize(pir->ir_ppath)+sizeof(WCHAR));
				findHTable.Add(pir->ir_fh, Drive, pPPath);
				break;
			case IFSFN_FINDNEXT:
				if(!GetFullNameByHandle(pir, drive, ResType, CodePage, pPPath, TRUE))
				{
					bBusy=FALSE;
					return nRetVal;
				}
				break;
		}
		//Now we will change the search path to file path which is found by FINDOPEN or FINDNEXT.

		//get file directory from search path by removing the last component:
		pPPath->pp_totalLength-=IFSLastElement(pPPath)->pe_length;

		//get full path by adding file name to file directory.
		findData=(_WIN32_FIND_DATA *)pir->ir_data;
		IFSLastElement(pPPath)->pe_length=wstrlen(findData->cFileName)+sizeof(WCHAR);
		memcpy(IFSLastElement(pPPath)->pe_unichars, findData->cFileName, IFSLastElement(pPPath)->pe_length);
		StringUpper((WCHAR *)IFSLastElement(pPPath)->pe_unichars, IFSLastElement(pPPath)->pe_length-sizeof(WCHAR));
		pPPath->pp_totalLength+=IFSLastElement(pPPath)->pe_length;
		*(WCHAR *)((char *)pPPath+pPPath->pp_totalLength)=NULL;

		//determine whether the file is under protection.
		if(protFileList.IsUnderProtection(drive, pPPath, PT_HIDE)) 
		{
			bBusy=FALSE;

			//now we are going to hide the protected file...
			if(fn==IFSFN_FINDOPEN)
			{
				//if it is FINDOPEN operation, we should return the next file.

				//using IFSMgr_Ring0_FileIO to find the next file.
				_WIN32_FIND_DATA_BCS bcsFindData;
				BOOL retVal;
				retVal=R0_FindNextFile(pir->ir_fh, &bcsFindData, (PWORD)&pir->ir_error);

				if(retVal)
				{
					//if the next file is found, convert _WIN32_FIND_DATA_BCS (the find data return by IFSMgr_Ring0_FileIO) to _WIN32_FIND_DATA ( the find data used by FS_FINDOPEN).
					memcpy(pir->ir_data, &bcsFindData, sizeof(_WIN32_FIND_DATA_BCS)-sizeof(bcsFindData.cFileName)-sizeof(bcsFindData.cAlternateFileName));
					BCSToUni(((_WIN32_FIND_DATA *)pir->ir_data)->cFileName, bcsFindData.cFileName, strlen((char *)bcsFindData.cFileName), CodePage, &res);
					((_WIN32_FIND_DATA *)pir->ir_data)->cFileName[res.ddLower]=0;
					BCSToUni(((_WIN32_FIND_DATA *)pir->ir_data)->cAlternateFileName, bcsFindData.cAlternateFileName, strlen((char *)bcsFindData.cAlternateFileName), CodePage, &res);
					((_WIN32_FIND_DATA *)pir->ir_data)->cAlternateFileName[res.ddLower]=0;
				}
				return retVal;	
			}
			else goto EXIT;		//if it is FINDNEXT operation, go on to find next file.
		}
	bBusy=FALSE;
	}

	return nRetVal;
}

//Protected file on file delete, rename operation.
//Return value:   return ERROR_SUCCESS indicates that the protected file has been back up, and 
//						   the file operation can be continue. Otherwise the file operation should stop.
WORD DoDeleteProtection(ioreq *pir, int Drive, int CodePage)
{
	struct _QWORD res;
	char pBCSPath[MAX_PATH+1];
	PROTECTED_FILE *pProtFile;
	if(pir->ir_attr&FILE_FLAG_WILDCARDS || pir->ir_attr&FILE_FLAG_HAS_STAR)
	{
		//Deal with file name with wildcards.

		//Convert from ParsedPath to BCS path.
		UniToBCSPathEx((PUCHAR)pBCSPath, pir->ir_ppath->pp_elements, Drive, MAX_PATH, CodePage, &res);

		//find first file.
		_WIN32_FIND_DATA_BCS bcsFindData;
		WORD error;
		HANDLE hFind;
		hFind=R0_FindFirstFile((PCHAR)pBCSPath, pir->ir_attr, &bcsFindData, &error);

		CHAR pFindPath[MAX_PATH];
		strcpy(pFindPath, pBCSPath);
		_strupr(pFindPath);

		while(error==ERROR_SUCCESS)
		{
			//Get full path by adding file name to file directory.
			GetDir(pFindPath);
			_strupr((PCHAR)bcsFindData.cFileName);
			strcat(pFindPath, (PCHAR)bcsFindData.cFileName);

			if((pProtFile=protFileList.IsUnderProtection(pFindPath, PT_DELETE|PT_HIDE))!=NULL)
			{
				if(pProtFile->PF_type&PT_HIDE)							
				{
					//Protect hidden file.
					pir->ir_error=ERROR_FILE_NOT_FOUND;
					return pir->ir_error;
				}
				else if(protFileList.bDelBak)
				{
					//Deny delete.
					if(!FileRename(pFindPath)==ERROR_SUCCESS)			//Cannot rename the file, so deny access to the file.
						return ERROR_ACCESS_DENIED;
				}
				else
				{
					//Back up on delete.
					pir->ir_error=ERROR_ACCESS_DENIED;

⌨️ 快捷键说明

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