本文来自转载,补充了函数参考文档地址,调整了代码格式
原文地址

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;
}