zoukankan      html  css  js  c++  java
  • 实现FileCopy(Ring0 x86 x64)

    1.1 内核不接受一个字符串文件路径,必须填写一个OBJECT_ATTRIBUTES结构。
        这个结构,在InitializeObjectAttributes初始化
    
    
    typedef struct _OBJECT_ATTRIBUTES {
      ULONG  Length;
      HANDLE  RootDirectory;
      PUNICODE_STRING  ObjectName;                //路径
      ULONG  Attributes;
      PVOID  SecurityDescriptor;
      PVOID  SecurityQualityOfService;
    } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
    typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
    
    
    
    
    VOID 
      InitializeObjectAttributes(
        OUT POBJECT_ATTRIBUTES  InitializedAttributes,
        IN PUNICODE_STRING  ObjectName,                            //路径
        IN ULONG  Attributes,                                          //OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE  忽略大小写 |打开内核句柄
        IN HANDLE  RootDirectory,
        IN PSECURITY_DESCRIPTOR  SecurityDescriptor            //打开的是内核句柄  传NULL
        );
    
    NTSTATUS 
      ZwCreateFile(
        __out PHANDLE  FileHandle,
        __in ACCESS_MASK  DesiredAccess,                            //申请的权限GENERIC_ALL
        __in POBJECT_ATTRIBUTES  ObjectAttributes,
        __out PIO_STATUS_BLOCK  IoStatusBlock,                    //
        __in_opt PLARGE_INTEGER  AllocationSize,
        __in ULONG  FileAttributes,
        __in ULONG  ShareAccess,
        __in ULONG  CreateDisposition,
        __in ULONG  CreateOptions,
        __in_opt PVOID  EaBuffer,
        __in ULONG  EaLength
        );
    
    如果CreateOptions 带有FILE_NO_INTERMEDIATE_BUFFERING CreateOptions 表示不通过缓冲区 直接操作磁盘,所以每次
    操作读写都必须以磁盘扇区大小(通常为512字节)对齐,否则返回错误,
    typedef struct _IO_STATUS_BLOCK {
        union {
            NTSTATUS Status;            //成功则为STATUS_SUCCESS
            PVOID Pointer;
        } DUMMYUNIONNAME;
        ULONG_PTR Information;            //返回的更多信息
    } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
    
    
    
    
    
    
    NTSTATUS 
      ZwReadFile(
        IN HANDLE  FileHandle,
        IN HANDLE  Event  OPTIONAL,                        //用于异步完成时
        IN PIO_APC_ROUTINE  ApcRoutine  OPTIONAL,       //异步完成时的回调例程
        IN PVOID  ApcContext  OPTIONAL,                
        OUT PIO_STATUS_BLOCK  IoStatusBlock,
        OUT PVOID  Buffer,                                //缓冲区 
        IN ULONG  Length,                                  //缓冲区长度 
        IN PLARGE_INTEGER  ByteOffset  OPTIONAL,   //
        IN PULONG  Key  OPTIONAL
        );
    
    读取的实际长度在ioStatusBlock.Information里
    读取完  返回STATUS_END_OF_FILE
    
           
    
    NTSTATUS 
      ZwWriteFile(
        IN HANDLE  FileHandle,
        IN HANDLE  Event  OPTIONAL,
        IN PIO_APC_ROUTINE  ApcRoutine  OPTIONAL,
        IN PVOID  ApcContext  OPTIONAL,
        OUT PIO_STATUS_BLOCK  IoStatusBlock,
        IN PVOID  Buffer,
        IN ULONG  Length,
        IN PLARGE_INTEGER  ByteOffset  OPTIONAL,
        IN PULONG  Key  OPTIONAL
        );
     下面是实现代码:
    /***************************************************************************************
    * AUTHOR : icqw
    * DATE   : 2015-7-30
    * MODULE : FileOption.H
    *
    * IOCTRL Sample Driver
    *
    * Description:
    *        Demonstrates communications between USER and KERNEL.
    *
    ****************************************************************************************
    * Copyright (C) 2010 icqw.
    ****************************************************************************************/
    #ifndef CXX_FILEOPTION_H
    #define CXX_FILEOPTION_H
    #include <ntifs.h>
    #include <devioctl.h>
    NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString);
    VOID DriverUnload(IN PDRIVER_OBJECT pDriverObj);
    HANDLE OpenFile(WCHAR* wzFilePath);
    NTSTATUS    ReadFile(HANDLE hFile,CHAR* szBuffer,PULONG ulLength,PLARGE_INTEGER Offset);
    NTSTATUS    WriteFile(HANDLE hFile,CHAR* szBuffer,PULONG ulLength,PLARGE_INTEGER Offset);
    NTSTATUS FileCopy(WCHAR* wzDest,WCHAR* wzSour);
    #endif
    #ifndef CXX_FILEOPTION_H
    #    include "FileOption.h"
    #endif
    NTSTATUS
    DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING pRegisterPath)
    {
        NTSTATUS        status = STATUS_SUCCESS;
    // #if DBG
    //     _asm int 3
    // 
    // #endif
        DriverObject->DriverUnload = DriverUnload;
        FileCopy(L"\??\D:\Dest.txt",L"\??\D:\Sour.txt");
        
        DbgPrint("[FileOption] DriverEntry Success
    ");
        return STATUS_SUCCESS;
    }
    NTSTATUS FileCopy(WCHAR* wzDest,WCHAR* wzSour)
    {
        HANDLE hSourFile    =    OpenFile(wzSour);
        HANDLE hDestFile    =    OpenFile(wzDest);
        ULONG     ulLength    =    0;
        CHAR*     szBuffer    =    NULL;
        NTSTATUS Status        =    STATUS_UNSUCCESSFUL;
        LARGE_INTEGER Offset    =    {0};
        if (hSourFile==NULL||hDestFile==NULL)
        {
            return STATUS_UNSUCCESSFUL;
        }
        szBuffer    =    (char*)ExAllocatePool(NonPagedPool,4*1024+1);
        while(TRUE)
        {
            RtlZeroMemory(szBuffer,4*1024+1);
            ulLength    =    4*1024;
            //
            Status        =    ReadFile(hSourFile,
                                     szBuffer,
                                     &ulLength,
                                     &Offset);
            if (!NT_SUCCESS(Status))
            {
                    break;
            }
            //
            Status        =    WriteFile(hDestFile,
                                      szBuffer,
                                      &ulLength,
                                      &Offset);
            if (!NT_SUCCESS(Status))
            {
                break;
            }
        }
        DbgPrint("Copy Success!");
        ZwClose(hSourFile);
        ZwClose(hDestFile);
        return STATUS_SUCCESS;
    }
    HANDLE OpenFile(WCHAR* wzFilePath)
    {
        UNICODE_STRING    uniName;
        OBJECT_ATTRIBUTES    Ob;
        HANDLE hFile    =    NULL;
        NTSTATUS Status    =    STATUS_UNSUCCESSFUL;
        IO_STATUS_BLOCK ioStatus    =    {0};
        
        RtlInitUnicodeString(&uniName,wzFilePath);
        InitializeObjectAttributes(&Ob,
            &uniName,
            OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
            NULL,
            NULL);
        Status    =    ZwCreateFile(&hFile,
                                 GENERIC_ALL|SYNCHRONIZE,
                                 &Ob,
                                 &ioStatus,
                                 NULL,
                                 FILE_ATTRIBUTE_NORMAL,
                                 FILE_SHARE_READ,
                                 FILE_OPEN_IF,
                                 FILE_NON_DIRECTORY_FILE|
                                 FILE_RANDOM_ACCESS|
                                 FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);
        if (!NT_SUCCESS(Status))
        {
            return NULL;
        }
        return hFile;
    }
    //读文件 ulLength 为读取实际长度
    NTSTATUS    ReadFile(HANDLE hFile,CHAR* szBuffer,PULONG ulLength,PLARGE_INTEGER Offset)
    {
        //这里用    
        NTSTATUS    Status            =    STATUS_UNSUCCESSFUL;
        IO_STATUS_BLOCK    ioStatus    =    {0};
            
        
        Status    =    ZwReadFile(hFile,
                                NULL,
                                NULL,
                                NULL,
                                &ioStatus,
                                szBuffer,
                                *ulLength,            
                                Offset,
                                NULL);
        if (!NT_SUCCESS(Status))
        {
            //Status==STATUS_END_OF_FILE)
            
            return STATUS_UNSUCCESSFUL;  
            
        }
        *ulLength    =    ioStatus.Information;
        return Status;;
    }
    //写文件
    NTSTATUS    WriteFile(HANDLE hFile,CHAR* szBuffer,PULONG ulLength,PLARGE_INTEGER Offset)
    {
        NTSTATUS    Status            =    STATUS_UNSUCCESSFUL;
        IO_STATUS_BLOCK    ioStatus    =    {0};
        
        Status    =    ZwWriteFile(hFile,
                                NULL,
                                NULL,
                                NULL,
                                &ioStatus,
                                szBuffer,
                                *ulLength,
                                Offset,
                                NULL);
        if (!NT_SUCCESS(Status))
        {
            return STATUS_UNSUCCESSFUL;  //!!!!
        }
        (*Offset).QuadPart    +=    *ulLength;            //Offset移动
        return Status;;
    }
    VOID
    DriverUnload(IN PDRIVER_OBJECT pDriverObj)
    {
        DbgPrint("[FileOption] Unloaded Success
    ");
        return;
    }
  • 相关阅读:
    青云黄允松:2016年是云计算市场最关键的一年
    知道创宇CTO杨冀龙:网络安全人才决定行业格局
    su 与 su
    如何进入单用户模式(CentOS6.9)
    在虚拟机中还原GHO镜像系统
    安装CentOS 7 文字版
    把typora改为微软雅黑+Consolas
    使用python操作文件实现购物车程序
    使用python操作json文本文件
    资源下载网址集合
  • 原文地址:https://www.cnblogs.com/icqw/p/4691818.html
Copyright © 2011-2022 走看看