📄 hookfile.cpp
字号:
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 = ClearFilesInfo(buff,InputLength,OutputLength,&BytesTxd); break;
case IOCTL_QUERY_FILE_NAME:
status = QueryFilesInfo(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("File Hook installing error\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();
vFilesInfo::iterator it = sFilesInfo.begin();
while(sFilesInfo.end() != it)
{
(*it).Clear();
++it;
}
sFilesInfo.clear();
sFileWRSync.Done();
}
bool CheckNameReserved(UNICODE_STRING* pFileName)
{
size_t str_size = pFileName->Length/2;
WCHAR* str = pFileName->Buffer;
if(str_size ==1 && str[0] == L'.')
return true;
if(str_size ==2 && str[0] == L'.' && str[1] == L'.')
return true;
return false;
}
bool CheckFileName(UNICODE_STRING* pNameToCheck,UNICODE_STRING* pSavedName)
/*++
Routine Description:
Checks if file should be hided by file name
Arguments:
Return Value:
--*/
{
if(CheckNameReserved(pNameToCheck))
return false;
return ApplyMask(pSavedName,pNameToCheck);
}
bool CompareFilePath(PUNICODE_STRING pRecord,PUNICODE_STRING pDevName,PUNICODE_STRING pFilePath)
/*++
Routine Description:
Checks if file should be hided by file path
Arguments:
Return Value:
--*/
{
// Length/2 - for Unicode string weight
int RecordSize = pRecord->Length/2;
int FilePatthSize = pFilePath->Length/2;
int DevNameSize = pDevName->Length/2;
if(RecordSize != (FilePatthSize+DevNameSize))
return false;
for(int i=0; i< RecordSize;++i)
{
if(i< DevNameSize)
{
if(pRecord->Buffer[i] != pDevName->Buffer[i])
return false;
}
else
{
if( (i-DevNameSize) > FilePatthSize)
return false;
if(pRecord->Buffer[i] != pFilePath->Buffer[i - DevNameSize])
return false;
}
}
return true;
}
bool CheckFilePath(HANDLE FileHandle,PUNICODE_STRING pFilePath)
/*++
Routine Description:
Checks if file should be hided by file path
Arguments:
Return Value:
--*/
{
UNICODE_STRING DevName;
PFILE_OBJECT file_obj;
PDEVICE_OBJECT dev_obj;
NTSTATUS ret_status;
ret_status=ObReferenceObjectByHandle(FileHandle,FILE_ALL_ACCESS,*IoFileObjectType,
KernelMode,(PVOID*)(&file_obj),NULL);
if(ret_status != STATUS_SUCCESS)
{
DbgPrint("ERROR ObReferenceObjectByHandle\n");
return false;
}
dev_obj = file_obj->DeviceObject;
RtlVolumeDeviceToDosName(dev_obj,&DevName);
if(CompareFilePath(pFilePath,&DevName,&file_obj->FileName))
{
ObDereferenceObject(file_obj);
return true;
}
else
{
ObDereferenceObject(file_obj);
return false;
}
}
bool CheckFile(PUNICODE_STRING pFileName,HANDLE FileHandle)
{
sFileWRSync.WaitToRead();
vFilesInfo::iterator it = sFilesInfo.begin();
for(;sFilesInfo.end() != it;++it)
{
// check file name
if( !CheckFileName( pFileName,&(*it).FileName) )
continue;
// check full file path
if( !CheckFilePath( FileHandle,&(*it).FilePath) )
continue;
// check access process
if( !CheckProcessAccess( &(*it).Proc) )
continue;
sFileWRSync.Done();
return true;
}
sFileWRSync.Done();
return false;
}
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;
UnicodeFileName.MaximumLength = pFileInfo->FileNameLength;
if(!CheckFile(&UnicodeFileName,FileHandle))
continue;
// if the file is first
if(PreviousDelta == 0)
{
// if there are no any file
if( pFileInfo->NextEntryOffset == 0 )
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:
Function call every time when NtQueryDirectoryFile function call in the system.
For hiding files we need to change one of supported FileInformation structure.
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: // Used by Vista explorer
return HideFile<PFILE_ID_BOTH_DIR_INFORMATION>(FileHandle,FileInformation);
case FileIdFullDirectoryInformation: // Used by Vista explorer
return HideFile<PFILE_ID_FULL_DIR_INFORMATION>(FileHandle,FileInformation);
default:return status;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -