win下驱动文件操作相关函数封装

创建文件

//创建文件
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值