创建文件
//创建文件
HANDLE KernelCreateFile(
IN PUNICODE_STRING pstrFile, // 文件路径符号链接
IN BOOLEAN bIsDir) // 是否为文件夹
{
HANDLE hFile = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK StatusBlock = { 0 };
ULONG ulShareAccess =
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
ULONG ulCreateOpt =
FILE_SYNCHRONOUS_IO_NONALERT;
// 1. 初始化OBJECT_ATTRIBUTES的内容
OBJECT_ATTRIBUTES objAttrib = { 0 };
ULONG ulAttributes =
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
InitializeObjectAttributes(
&objAttrib, // 返回初始化完毕的结构体
pstrFile, // 文件对象名称
ulAttributes, // 对象属性
NULL, NULL); // 一般为NULL
// 2. 创建文件对象
ulCreateOpt |= bIsDir ?
FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE;
Status = ZwCreateFile(
&hFile, // 返回文件句柄
GENERIC_ALL, // 文件操作描述
&objAttrib, // OBJECT_ATTRIBUTES
&StatusBlock, // 接受函数的操作结果
0, // 初始文件大小
FILE_ATTRIBUTE_NORMAL, // 新建文件的属性
ulShareAccess, // 文件共享方式
FILE_OPEN_IF, // 文件存在则打开不存在则创建
ulCreateOpt, // 打开操作的附加标志位
NULL, // 扩展属性区
0); // 扩展属性区长度
if (!NT_SUCCESS(Status))
return (HANDLE)-1;
return hFile;
}
获取文件大小
//获取文件大小
ULONG64 KernelGetFileSize(IN HANDLE hfile)
{
// 查询文件状态
IO_STATUS_BLOCK StatusBlock = { 0 };
FILE_STANDARD_INFORMATION fsi = { 0 };
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = ZwQueryInformationFile(
hfile, // 文件句柄
&StatusBlock, // 接受函数的操作结果
&fsi, // 根据最后一个参数的类型输出相关信息
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(Status))
return 0;
return fsi.EndOfFile.QuadPart;
}
读取文件
ULONG64 KernelReadFile(
IN HANDLE hfile, // 文件句柄
IN PLARGE_INTEGER Offset, // 从哪里开始读取
IN ULONG ulLength, // 读取多少字节
OUT PVOID pBuffer) // 保存数据的缓存
{
// 1. 读取文件
IO_STATUS_BLOCK StatusBlock = { 0 };
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = ZwReadFile(
hfile, // 文件句柄
NULL, // 信号状态(一般为NULL)
NULL, NULL, // 保留
&StatusBlock, // 接受函数的操作结果
pBuffer, // 保存读取数据的缓存
ulLength, // 想要读取的长度
Offset, // 读取的起始偏移
NULL); // 一般为NULL
if (!NT_SUCCESS(Status)) return 0;
// 2. 返回实际读取的长度
return StatusBlock.Information;
}
写入文件
//写文件
ULONG64 KernelWriteFile(
IN HANDLE hfile, // 文件句柄
IN PLARGE_INTEGER Offset, // 从哪里开始写入
IN ULONG ulLength, // 写入多少字节
IN PVOID pBuffer) // 欲写入的数据
{
// 1. 写入文件
IO_STATUS_BLOCK StatusBlock = { 0 };
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = ZwWriteFile(
hfile, // 文件句柄
NULL, // 信号状态(一般为NULL)
NULL, NULL, // 保留
&StatusBlock, // 接受函数的操作结果
pBuffer, // 欲写入的数据
ulLength, // 想要写入的长度
Offset, // 写入的起始偏移
NULL); // 一般为NULL
if (!NT_SUCCESS(Status)) return 0;
// 2. 返回实际写入的长度
// 2. 返回实际写入的长度
return StatusBlock.Information;
}
删除文件
/删除文件
NTSTATUS KernelDeleteFile(IN PUNICODE_STRING pstrFile)
{
// 1. 初始化OBJECT_ATTRIBUTES的内容
OBJECT_ATTRIBUTES objAttrib = { 0 };
ULONG ulAttributes =
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE;
InitializeObjectAttributes(
&objAttrib, // 返回初始化完毕的结构体
pstrFile, // 文件对象名称
ulAttributes, // 对象属性
NULL, // 根目录(一般为NULL)
NULL); // 安全属性(一般为NULL)
// 2. 删除指定文件/文件夹
return ZwDeleteFile(&objAttrib);
}
拷贝文件
//拷贝文件
VOID ZwMyCopyFile(
PUNICODE_STRING SouPath,//源地址
PUNICODE_STRING DenPath //目的地址
)
{
//1 打开源地址文件
HANDLE hSorHandle = KernelCreateFile(SouPath, FALSE);
//2 获取大小
ULONG64 FileSize = KernelGetFileSize(hSorHandle);
//3 申请空间,读取数据
PVOID buf = ExAllocatePool(NonPagedPool, (SIZE_T)FileSize);
RtlZeroMemory(buf, (SIZE_T)FileSize);
LARGE_INTEGER Offset = {0,0};
KernelReadFile(hSorHandle, &Offset, (SIZE_T)FileSize, buf);
//4 打开目的地址文件
HANDLE hDenHandle = KernelCreateFile(DenPath, FALSE);
//5 写入数据
KernelWriteFile(hDenHandle, &Offset, (SIZE_T)FileSize, buf);
//6 关闭句柄
ZwClose(hSorHandle);
ZwClose(hDenHandle);
}
文件遍历
#define _countof(arr) sizeof(arr)/sizeof(arr[0])
BOOLEAN KernelFindFirstFile(
IN HANDLE hFile, // 文件句柄
IN ULONG ulLen, // 信息长度
OUT PFILE_BOTH_DIR_INFORMATION pDir, // 文件信息
IN ULONG uFirstlLen, // 信息长度
OUT PFILE_BOTH_DIR_INFORMATION pFirstDir // 第一个文件信息
) {
NTSTATUS Status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK StatusBlock = { 0 };
// 1. 获取第一个文件信息,看是否成功
Status = ZwQueryDirectoryFile(
hFile, NULL, NULL, NULL,// 文件句柄
&StatusBlock, // 接受函数的操作结果
pFirstDir, // 文件信息
uFirstlLen, // “文件信息“的数据长度
FileBothDirectoryInformation, // 查询模式
TRUE, // 是否返回一条起始信息
NULL, // 文件句柄指向的文件(一般为NULL)
FALSE); // 是否从目录开始的第一项扫描
// 2. 若成功,则获取文件列表
if (NT_SUCCESS(Status) == FALSE) {
return FALSE;
}
Status = ZwQueryDirectoryFile(
hFile, NULL, NULL, NULL,// 文件句柄
&StatusBlock, // 接受函数的操作结果
pDir, // 文件信息
ulLen, // “文件信息“的数据长度
FileBothDirectoryInformation, // 查询模式
FALSE, // 是否返回一条起始信息
NULL, // 文件句柄指向的文件(一般为NULL)
FALSE); // 是否从目录开始的第一项扫描
return NT_SUCCESS(Status);
}
BOOLEAN KernelFindNextFile(
IN PFILE_BOTH_DIR_INFORMATION pDirList,//
OUT PFILE_BOTH_DIR_INFORMATION pDirInfo,
IN OUT LONG * Loc) {
// 如果有下一项,则移动指针指向下一项
PFILE_BOTH_DIR_INFORMATION pDir = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)pDirList + *Loc);
LONG StructLenth = 0;
if (pDir->FileName[0] != 0)
{
StructLenth = sizeof(FILE_BOTH_DIR_INFORMATION);
memcpy(pDirInfo, pDir, StructLenth + pDir->FileNameLength);
*Loc = *Loc + pDir->NextEntryOffset;
if (pDir->NextEntryOffset == 0) {
*Loc = *Loc + StructLenth + pDir->FileNameLength;
}
return TRUE;
}
return FALSE;
}
NTSTATUS EnmuFile()
{
UNICODE_STRING ustrFolder = { 0 };
WCHAR szSymbol[0x512] = L"\\??\\";
UNICODE_STRING ustrPath =
RTL_CONSTANT_STRING(L"C:\\");
HANDLE hFile = NULL;
SIZE_T nFileInfoSize =
sizeof(FILE_BOTH_DIR_INFORMATION) + 270 * sizeof(WCHAR);
SIZE_T nSize = nFileInfoSize * 0x256; //假设最多有0x256个文件
char strFileName[0x256] = { 0 };
PFILE_BOTH_DIR_INFORMATION pFileTemp = NULL;
PFILE_BOTH_DIR_INFORMATION pFileList = NULL;
pFileList = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool, nSize);
pFileTemp = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool,
nFileInfoSize);
// 1. 将路径组装为连接符号名,并打开文件
wcscat_s(szSymbol, _countof(szSymbol), ustrPath.Buffer);
RtlInitUnicodeString(&ustrFolder, szSymbol);
hFile = KernelCreateFile(&ustrFolder, TRUE);
if (KernelFindFirstFile(hFile, nSize, pFileList, nFileInfoSize, pFileTemp))
{
LONG Loc = 0;
do
{
RtlZeroMemory(strFileName, 0x256);
RtlCopyMemory(strFileName,
pFileTemp->FileName,
pFileTemp->FileNameLength);
if (strcmp(strFileName, "..") == 0
|| strcmp(strFileName, ".") == 0)
continue;
if (pFileTemp->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY)
DbgPrint("[目录]%S\n", strFileName);
else
DbgPrint("[文件]%S\n", strFileName);
memset(pFileTemp, 0, nFileInfoSize);
} while (KernelFindNextFile(pFileList, pFileTemp, &Loc));
}
return STATUS_SUCCESS;
}
转载于:https://blog.51cto.com/haidragon/2131404