本文来自转载,补充了函数参考文档地址,调整了代码格式
原文地址
0x00 文件操作函数
ZwDeleteFile 删除指定的文件
ZwOpenFile 打开现有文件、目录、设备或卷
ZwClose 关闭对象句柄
ZwQueryInformationFile 返回有关文件对象的各种信息
ZwReadFile 从打开的文件读取数据
ZwWriteFile 将数据写入打开的文件
ZwCreateFile 创建新文件或打开现有文件
调用Zw函数会进行参数检查,检查完成后再调用nt函数
代码示例
#include <Ntifs.h>
#include <wdm.h>
//文件删除
NTSTATUS FileDelete(PWSTR wFilePath)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING uFilePath = { 0 };
RtlInitUnicodeString(&uFilePath, wFilePath);
OBJECT_ATTRIBUTES objectAttributes = { 0 };
InitializeObjectAttributes(&objectAttributes, &uFilePath, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwDeleteFile(&objectAttributes);
if (status == STATUS_SUCCESS)
DbgPrint("FileDelete -> DeleteFile success");
else
DbgPrint("FileDelete -> DeleteFile failed");
return status;
}
//文件复制
NTSTATUS FileCopy(PWSTR wDestinationPath, PWSTR wSourcePath)
{
NTSTATUS status = STATUS_SUCCESS;
//打开源文件
HANDLE hSourceFile = NULL; //句柄 - 参数1
UNICODE_STRING uSourcePath = { 0 }; //路径名
RtlInitUnicodeString(&uSourcePath, wSourcePath);
OBJECT_ATTRIBUTES oaSourceFile = { 0 }; //对象属性,包含路径名 - 参数3
InitializeObjectAttributes(&oaSourceFile, &uSourcePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
IO_STATUS_BLOCK isbSourceFile = { 0 }; //IO_STATUS_BLOCK -> 接收完成状态 -> 参数4
status = ZwOpenFile(&hSourceFile, GENERIC_READ, &oaSourceFile, &isbSourceFile, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT);
if (status != STATUS_SUCCESS)
{
//没有需要释放的资源
DbgPrint("FileCopy -> ZwOpenFile failed");
return status;
}
//获取文件大小
IO_STATUS_BLOCK isbQuery = { 0 }; //IO_STATUS_BLOCK -> 接收完成状态
FILE_STANDARD_INFORMATION FileInformation = { 0 };
status = ZwQueryInformationFile(hSourceFile, &isbQuery, &FileInformation, sizeof(FileInformation), FileStandardInformation);
if (status != STATUS_SUCCESS)
{
//需要释放资源
ZwClose(hSourceFile); //关闭源文件
DbgPrint("FileCopy -> ZwQueryInformationFile failed");
return status;
}
if (FileInformation.EndOfFile.QuadPart == 0)
{
//需要释放资源
ZwClose(hSourceFile); //关闭源文件
DbgPrint("FileCopy -> ZwQueryInformationFile failed -> source file size is %Id ", FileInformation.EndOfFile.QuadPart);
return STATUS_NO_SUCH_FILE;
}
LONGLONG sourceRemainFileSize = FileInformation.EndOfFile.QuadPart; //源文件大小
//创建目标文件
HANDLE hDestinationFile = NULL; //句柄 - 参数1
UNICODE_STRING uDestinationPath = { 0 }; //路径名
RtlInitUnicodeString(&uDestinationPath, wDestinationPath);
OBJECT_ATTRIBUTES oaDestinationFile = { 0 }; //对象属性,包含路径名 - 参数3
InitializeObjectAttributes(&oaDestinationFile, &uDestinationPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
IO_STATUS_BLOCK isbDestinationFile = { 0 }; //IO_STATUS_BLOCK -> 接收完成状态 -> 参数4
status = ZwCreateFile(&hDestinationFile, GENERIC_WRITE, &oaDestinationFile, &isbDestinationFile, NULL, FILE_ATTRIBUTE_NORMAL, NULL, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, NULL);
if (status != STATUS_SUCCESS)
{
//需要释放资源
ZwClose(hSourceFile); //关闭
DbgPrint("FileCopy -> ZwOpenFile failed");
return status;
}
//通过缓冲区复制内容
//1 申请缓冲区
PVOID buffer = ExAllocatePoolWithTag(NonPagedPool, 1024, '1agT');
if (!buffer)
{
//需要释放资源
ZwClose(hDestinationFile); //关闭目标文件
ZwClose(hSourceFile); //关闭源文件
DbgPrint("FileCopy -> ExAllocatePoolWithTag failed");
return STATUS_NO_MEMORY;
}
IO_STATUS_BLOCK isbRead = { 0 }; //IO_STATUS_BLOCK -> 接收完成状态 -> ZwReadFile参数5
ULONG length = 0; //读取长度 ZwReadFile参数7
LARGE_INTEGER offset = { 0 }; //读取偏移 -> 从文件那个位置开始读 ZwReadFile参数8
while (sourceRemainFileSize)
{
if (sourceRemainFileSize > 1024)
length = 1024;
else
length = sourceRemainFileSize;
//DbgPrint("FileCopy -> while -> ZwReadFile");
//2 读取源文件数据至缓冲区
status = ZwReadFile(hSourceFile, NULL, NULL, NULL, &isbRead, buffer, length, &offset, NULL);
if (status != STATUS_SUCCESS)
{
//需要释放资源
ExFreePool(buffer); //释放缓冲区
ZwClose(hDestinationFile); //关闭目标文件
ZwClose(hSourceFile); //关闭源文件
DbgPrint("FileCopy -> ZwReadFile failed");
return status;
}
//DbgPrint("FileCopy -> while -> ZwWriteFile");
//3 将缓冲区数据写入目标文件
status = ZwWriteFile(hDestinationFile, NULL, NULL, NULL, &isbRead, buffer, length, &offset, NULL);
if (status != STATUS_SUCCESS)
{
//需要释放资源
ExFreePool(buffer); //释放缓冲区
ZwClose(hDestinationFile); //关闭目标文件
ZwClose(hSourceFile); //关闭源文件
DbgPrint("FileCopy -> ZwWriteFile failed");
return status;
}
sourceRemainFileSize -= length;
offset.QuadPart += length;
}
//关闭资源
ExFreePool(buffer); //释放缓冲区
ZwClose(hDestinationFile); //关闭目标文件
ZwClose(hSourceFile); //关闭源文件
DbgPrint("FileCopy success");
return status;
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("DriverUnload");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
DriverObject->DriverUnload = DriverUnload;
FileCopy(L"\\??\\C:\\2.exe", L"\\??\\C:\\1.exe");
//FileDelete(L"\\??\\C:\\1.exe");
return status;
}