驱动级彻底隐藏文件或文件夹的方法网上有很多,方法大致一样,不过网上贴出来的代码都忽略了一些东西,我先把我的通过验证的代码贴出来,再一一说明
ssdt hook那块的实现就不贴了,主要是对hook到ZwQueryDirectoryFile之后的实现
我做的是要隐藏指定目录下的指定后缀名的文件
NTSTATUS __stdcall NtQueryDirectoryFile_HOOK(HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass,
BOOLEAN ReturnSingleEntry,
PUNICODE_STRING FileName,
BOOLEAN RestartScan)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PFILE_BOTH_DIR_INFORMATION pFileInfo = NULL;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo = NULL;
UNICODE_STRING usFilePathProfix = {0};
UNICODE_STRING usFileName = {0};
UNICODE_STRING usDirName = {0};
char szFileName[MAX_PATH] = {0};
ntStatus = ((NtQueryDirectoryFile_T)(g_fNtQueryDirectoryFile.trampoline))
(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
Length, FileInformationClass, ReturnSingleEntry, FileName, RestartScan);
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
if (pFileInfo == NULL)
return ntStatus;
if (NT_SUCCESS(ntStatus) && (FileInformationClass == FileBothDirectoryInformation))
{
BOOLEAN bLastOne = FALSE;
PFILE_OBJECT FileObj = NULL;
status = ObReferenceObjectByHandle(FileHandle, FILE_READ_DATA, *IoFileObjectType,
KernelMode, &FileObj, NULL);
if(NT_SUCCESS(status))
{
ObDereferenceObject(FileObj);
RtlVolumeDeviceToDosName(FileObj->DeviceObject, &usDirName);
if (..) // 这里是判断是否是指定目录
{
KStr_SetValue_WChar(&usFilePathProfix, L".txt");
pLastFileInfo = pFileInfo;
do
{
if (pFileInfo == NULL)
break;
bLastOne = !(pFileInfo->NextEntryOffset);
if (..) // 这里判断是否是以指定后缀名结尾
{
if (bLastOne)
{
if (pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformation)
{
ntStatus = ((NtQueryDirectoryFile_T)(g_fNtQueryDirectoryFile.trampoline))
(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
Length, FileInformationClass, ReturnSingleEntry, FileName, FALSE);
if (!NT_SUCCESS(ntStatus))
return ntStatus;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
bLastOne = FALSE;
continue; }
else
pLastFileInfo->NextEntryOffset = 0;
break;
}
else
{
int iPos = (ULONG)pFileInfo - (ULONG)FileInformation;
int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory((PVOID)pFileInfo, (PVOID)((char*)pFileInfo + pFileInfo->NextEntryOffset), (DWORD)iLeft);
continue;
}
}
pLastFileInfo = pFileInfo;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char*)pFileInfo + pFileInfo->NextEntryOffset);
} while (!bLastOne);
}
}
}
return ntStatus;
}
蓝色部分是很多地方都遗漏的,如果查找到第一个文件需要隐藏的话,实际应该是上面调用了FindFirstFile,返回 0x80000006,导致的后果是,该目录下的所有文件都无法显示。所以出现这种情况应该继续查找。
浙公网安备 33010602011771号