To the pursuit of truth.
Windows 内核编程并没有提供像 Ring3 层的 CopyFile 这样的 API,看了看书中的例子自己写了一份 MyCopyFile,以后用来备用。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
#include <ntddk.h>#ifndef MEM_TAG#define MEM_TAG 'MyTt'#endifNTSTATUS MyOpenFile( HANDLE* handle, IO_STATUS_BLOCK* io_status, CONST PUNICODE_STRING file_path){ NTSTATUS status; OBJECT_ATTRIBUTES object_attributes; InitializeObjectAttributes( &object_attributes, file_path, OBJ_CASE_INSENSITIVE OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwCreateFile( handle, // 文件句柄 GENERIC_READ GENERIC_WRITE, // 打开文件的权限 &object_attributes, // 文件对象的描述信息 io_status, // 操作结果结构体 NULL, // 文件创建后的初始大小 FILE_ATTRIBUTE_NORMAL, // 文件属性信息 FILE_SHARE_READ, // 其他文件打开时的属性 FILE_OPEN_IF, // 如果文件存在,则打开;如果不存在,则创建 FILE_NON_DIRECTORY_FILE FILE_RANDOM_ACCESS FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); return status;}NTSTATUS MyCopyFile(PUNICODE_STRING target_path, PUNICODE_STRING source_path){ NTSTATUS status; // 创建源文件和目标文件句柄 HANDLE target = NULL; HANDLE source = NULL; // buffer PVOID buffer = NULL; // offset LARGE_INTEGER offset = { 0 }; // io_status IO_STATUS_BLOCK io_status = { 0 };#if DBG _asm int 3#endif do { // 分别打开文件得到文件句柄 MyOpenFile(&source, &io_status, source_path); MyOpenFile(&target, &io_status, target_path); // 分配一个缓冲区用来存储每次读取的内容 buffer = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, 4096, MEM_TAG); // ZwReadFile 和 ZwWriteFile 所需的两个参数 IO_STATUS_BLOCK IoStatus = { 0 }; ULONG length = 4 * 1024; while (1) { // 读取 status = ZwReadFile(source, NULL, NULL, NULL, &IoStatus, buffer, length, &offset, NULL); if (!NT_SUCCESS(status)) { if (status == STATUS_END_OF_FILE) { status = STATUS_SUCCESS; } break; } // 获取实际读到的大小 length = IoStatus.Information; // 根据读取到的实际大小写入到另外一个文件中 status = ZwWriteFile(target, NULL, NULL, NULL, &IoStatus, buffer, length, &offset, NULL); if (!NT_SUCCESS(status)) break; // offset 后移 offset.QuadPart += IoStatus.Information; } } while (0); if (target != NULL) ZwClose(target); if (source != NULL) ZwClose(source); if (buffer != NULL) ExFreePool(buffer); return STATUS_SUCCESS;}NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath){ UNICODE_STRING src = RTL_CONSTANT_STRING(L"\\??\\C:\\1.txt"); UNICODE_STRING dst = RTL_CONSTANT_STRING(L"\\??\\C:\\2.txt"); MyCopyFile(&dst, &src); return STATUS_UNSUCCESSFUL;}