内核的枚举文件

这个还是糅合了 很多资料搞定的 

感觉内核 枚举 文件还是简单的   核心函数就一个  ZwQueryDirectoryFile 得出来  _FILE_BOTH_DIR_INFORMATION  结构体 然后枚举 就可以了   然后 可以 封装两个函数   MyFindFirstFile  MyFindNextFile 。MyFindFirstFile  可以用 IoCreateFile 来获取句柄 

然后 可以用   ZwQueryDirectoryFile 可以验证一下  是否真的可以。。

然后 用 MyFindNextFile 获得 然后就可以  枚举了   这次是用的windows 黑客编程技术详解源码 其中也有 照着看雪论坛写的代码 

发现 两者好像差不多  这大概就是传说中 的好多年的轮子吧。。。、

只不过  windows  黑客编程技术详解把两个封装的函数 给取消了  直接变成了一个函数  

其实就是  获取句柄 获取结构体 枚举就完事了

下面是代码

#include <ntddk.h>
#define  HANDLE_VALUE (HANDLE)-1
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;
NTKERNELAPI NTSTATUS ZwQueryDirectoryFile
(
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
);
VOID DriverUnload(PDRIVER_OBJECT driver)
{
	KdPrint(("goodbye"));
}
BOOLEAN MyQueryFileAndFileFolder(UNICODE_STRING ustrPath)
{
	HANDLE hFile = NULL;
	OBJECT_ATTRIBUTES objectAttributes = { 0 };
	IO_STATUS_BLOCK iosb = { 0 };
	NTSTATUS status = STATUS_SUCCESS;

	// 获取文件句柄
	InitializeObjectAttributes(&objectAttributes, &ustrPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	status = ZwCreateFile(&hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,
		&objectAttributes, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE,
		FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT,
		NULL, 0);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("ZwCreateFile", status));
		return FALSE;
	}

	// 遍历文件
	// 注意此处的大小!!!一定要申请足够内存,否则后面ExFreePool会蓝屏
	ULONG ulLength = (2 * 4096 + sizeof(FILE_BOTH_DIR_INFORMATION)) * 0x2000;
	PFILE_BOTH_DIR_INFORMATION pDir = ExAllocatePool(PagedPool, ulLength);
	// 保存pDir的首地址,用来释放内存使用!!!
	PFILE_BOTH_DIR_INFORMATION pBeginAddr = pDir;
	// 获取信息
	status = ZwQueryDirectoryFile(hFile, NULL, NULL, NULL, &iosb, pDir, ulLength,
		FileBothDirectoryInformation, FALSE, NULL, FALSE);
	if (!NT_SUCCESS(status))
	{
		ExFreePool(pDir);
		ZwClose(hFile);
		KdPrint(("ZwQueryDirectoryFile", status));
		return FALSE;
	}
	// 遍历
	UNICODE_STRING ustrTemp;
	UNICODE_STRING ustrOne;
	UNICODE_STRING ustrTwo;
	RtlInitUnicodeString(&ustrOne, L".");
	RtlInitUnicodeString(&ustrTwo, L"..");
	WCHAR wcFileName[1024] = { 0 };
	while (TRUE)
	{
		// 判断是否是上级目录或是本目录
		RtlZeroMemory(wcFileName, 1024);
		RtlCopyMemory(wcFileName, pDir->FileName, pDir->FileNameLength);
		RtlInitUnicodeString(&ustrTemp, wcFileName);
		if ((0 != RtlCompareUnicodeString(&ustrTemp, &ustrOne, TRUE)) &&
			(0 != RtlCompareUnicodeString(&ustrTemp, &ustrTwo, TRUE)))
		{
			if (pDir->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				// 目录
				KdPrint(("[DIRECTORY]\t%wZ\n", &ustrTemp));
			}
			else
			{
				// 文件
				KdPrint(("[FILE]\t\t%wZ\n", &ustrTemp));
			}
		}
		// 遍历完毕
		if (0 == pDir->NextEntryOffset)
		{
			KdPrint(("\n[QUERY OVER]\n\n"));
			break;
		}
		// pDir指向的地址改变了,所以下面ExFreePool(pDir)会出错!!!所以,必须保存首地址
		pDir = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)pDir + pDir->NextEntryOffset);
	}
	// 释放内存, 关闭文件句柄
	ExFreePool(pBeginAddr);
	ZwClose(hFile);

	return TRUE;
}
HANDLE MyFindfile(LPSTR lp, PFILE_BOTH_DIR_INFORMATION pDir, ULONG ulen)
{
	char strFolder[4096] = { 0 };
	STRING ast;
	UNICODE_STRING ustr;
	OBJECT_ATTRIBUTES ob;
	IO_STATUS_BLOCK io;
	NTSTATUS nt;
	HANDLE hfine = HANDLE_VALUE;
	memset(strFolder, 0, 4096);
	strcpy(strFolder, "\\??\\");
	strcat(strFolder, lp);
	RtlInitString(&ast, strFolder);
	if (RtlAnsiStringToUnicodeString(&ustr, &ast, TRUE) == 0)
	{
		InitializeObjectAttributes(&ob, &ustr, OBJ_CASE_INSENSITIVE, NULL, NULL);
		nt = IoCreateFile(&hfine,
			FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,
			&ob,
			&io,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ | FILE_SHARE_WRITE,
			FILE_OPEN,
			FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT,
			NULL,
			0,
			CreateFileTypeNone,
			NULL,
			IO_NO_PARAMETER_CHECKING);
		RtlFreeUnicodeString(&ustr);
		if (nt == STATUS_SUCCESS&&hfine != HANDLE_VALUE)
		{
			nt = ZwQueryDirectoryFile(
				hfine,
				NULL,
				NULL,
				NULL,
				&io,
				pDir,
				ulen,
				FileBothDirectoryInformation,
				TRUE,
				NULL,
				FALSE
				);
			if (!NT_SUCCESS(nt))
			{
				ZwClose(hfine);
				return HANDLE_VALUE;
			}

		}
	}
	return hfine;
}
BOOLEAN Nextfile(HANDLE hfile, PFILE_BOTH_DIR_INFORMATION pDir, ULONG ulen)
{
	IO_STATUS_BLOCK io;
	NTSTATUS nt;
	nt = ZwQueryDirectoryFile(
		hfile,
		NULL,
		NULL,
		NULL,
		&io,
		pDir,
		ulen,
		FileBothDirectoryInformation,
		FALSE,
		NULL,
		FALSE
		);
	if (NT_SUCCESS(nt))
		return TRUE;
	else
		return FALSE;

}
ULONG Searchflie(LPSTR lpPath)
{
	ULONG count = 0;
	HANDLE hfine = HANDLE_VALUE;
	PFILE_BOTH_DIR_INFORMATION  pDir;
	char *strBuffer = NULL;
	char strfilename[255 * 2];
	ULONG ulen = 4096 * 2 + sizeof(PFILE_BOTH_DIR_INFORMATION);
	strBuffer = (PCHAR)ExAllocatePool(NonPagedPool, ulen);
	pDir = (PFILE_BOTH_DIR_INFORMATION)strBuffer;
	hfine = MyFindfile(lpPath, pDir, ulen);
	if (hfine != HANDLE_VALUE)
	{
		ExFreePool(strBuffer);
		ulen = (4096 * 2 + sizeof(FILE_BOTH_DIR_INFORMATION))*0x2000;
		strBuffer = (PCHAR)ExAllocatePool(NonPagedPool, ulen);
		pDir = (PFILE_BOTH_DIR_INFORMATION)strBuffer;
		if (Nextfile(hfine, pDir, ulen))
		{
			while (TRUE)
			{
				memset(strfilename, 0, 255 * 2);
				memcpy(strfilename, pDir->FileName, pDir->FileNameLength);
				if (strcmp(strfilename, "..") != 0 && strcmp(strfilename, ".") != 0)
				{
                 if (pDir->FileAttributes&FILE_ATTRIBUTE_DIRECTORY)
				{
					KdPrint(("目录: %s\n", strfilename));

				}
				else
				{
					KdPrint(("文件: %s\n", strfilename));
				
				}
                     count++;
				}
				if (pDir->NextEntryOffset == 0) 
					break;
				pDir = (PFILE_BOTH_DIR_INFORMATION)((char *)pDir + pDir->NextEntryOffset);
			}
			ExFreePool(strBuffer);

		}
		KdPrint(("搜索完毕!\n"));
		ZwClose(hfine);
	}
	return count;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
	UNICODE_STRING ustrQueryFile;
	RtlInitUnicodeString(&ustrQueryFile, L"\\??\\C:\\Windows");
	MyQueryFileAndFileFolder(ustrQueryFile);
	DriverObject->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

 

下面是 效果图 

 

 

 

参考代码 

看雪论坛 

windows 黑客编程技术详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值