博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于彻底隐藏文件或文件夹

Posted on 2011-11-29 14:35  gaozili  阅读(337)  评论(0编辑  收藏  举报

驱动级彻底隐藏文件或文件夹的方法网上有很多,方法大致一样,不过网上贴出来的代码都忽略了一些东西,我先把我的通过验证的代码贴出来,再一一说明

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,导致的后果是,该目录下的所有文件都无法显示。所以出现这种情况应该继续查找。

参考资料:http://www.codeproject.com/KB/system/hide-driver.aspx

http://topic.csdn.net/t/20041020/11/3473098.html