• 梦织未来Windows驱动编程 第06课 驱动对磁盘文件的操作


    代码部分:

    实现一个文件C:\text.txt,并读取写入内容到文件,然后将文件设置为只读,并隐藏文件。代码如下:

      1 //MyCreateFile.c
      2 //2016.07.22
      3 #include <ntddk.h>
      4 
      5 NTSTATUS MyCreateFile()
      6 {
      7     HANDLE hFile;
      8 
      9     NTSTATUS Status = STATUS_SUCCESS;
     10 
     11     UNICODE_STRING usFileName;
     12     OBJECT_ATTRIBUTES FileObjAttr;
     13     IO_STATUS_BLOCK IoStatusBlock;
     14 
     15 
     16     memset (&FileObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));
     17 
     18     RtlInitUnicodeString (&usFileName, L"\??\c:\test.txt");
     19     InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);    //OBJ_CASE_INSENSITIVE 大小写不敏感
     20 
     21     Status = ZwCreateFile (&hFile,
     22         GENERIC_ALL,
     23         &FileObjAttr,
     24         &IoStatusBlock,
     25         NULL,
     26         FILE_ATTRIBUTE_NORMAL,
     27         FILE_SHARE_READ,            
     28         FILE_OPEN_IF,                //如果没有文件,创建文件。如果有文件,直接打开
     29         FILE_NON_DIRECTORY_FILE,    //不是目录
     30         NULL,
     31         0);
     32     if (!NT_SUCCESS(Status))
     33     {
     34         return Status;
     35     }
     36 
     37     KdPrint(("Create File Success!"));
     38 
     39     ZwClose (hFile);
     40 
     41     return Status;
     42 }
     43 
     44 NTSTATUS MyOpenFile()
     45 {
     46     HANDLE hFile;
     47 
     48     UNICODE_STRING usFileName;
     49     NTSTATUS Status = STATUS_SUCCESS;
     50     OBJECT_ATTRIBUTES FileObjAttr;
     51     IO_STATUS_BLOCK IoStatusBlock;
     52 
     53     RtlInitUnicodeString (&usFileName, L"\??\c:\test.txt");
     54     memset (&FileObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));
     55 
     56     InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
     57 
     58     Status = ZwOpenFile(&hFile, 
     59         GENERIC_ALL,
     60         &FileObjAttr,
     61         &IoStatusBlock,
     62         FILE_SHARE_READ,
     63         FILE_NON_DIRECTORY_FILE);
     64     if (!NT_SUCCESS(Status))
     65     {
     66         KdPrint(("Open File Failed:0x%X", Status));
     67         return Status;
     68     }
     69 
     70     KdPrint(("Open File Success!"));
     71 
     72     ZwClose(hFile);
     73 
     74     return Status;
     75 }
     76 
     77 NTSTATUS MyZwSetInfomationFile()
     78 {
     79     HANDLE hFile;
     80 
     81     UNICODE_STRING usFileName;
     82     NTSTATUS Status = STATUS_SUCCESS;
     83     OBJECT_ATTRIBUTES FileObjAttr;
     84     IO_STATUS_BLOCK IoStatusBlock;
     85     FILE_BASIC_INFORMATION fbi;
     86 
     87 
     88     RtlInitUnicodeString (&usFileName, L"\??\c:\test.txt");
     89     memset (&FileObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));
     90 
     91     InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
     92 
     93     Status = ZwOpenFile(&hFile, 
     94         GENERIC_ALL,
     95         &FileObjAttr,
     96         &IoStatusBlock,
     97         FILE_SHARE_READ,
     98         FILE_NON_DIRECTORY_FILE);
     99     if (!NT_SUCCESS(Status))
    100     {
    101         KdPrint(("Open File Failed:0x%X", Status));
    102         return Status;
    103     }
    104 
    105     KdPrint(("Open File Success!"));
    106 
    107     Status = ZwQueryInformationFile (hFile, &IoStatusBlock, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation);    //查看FileBasicInformation
    108     if (!NT_SUCCESS(Status))
    109     {
    110         KdPrint(("Query Information Error code: %X", Status));
    111         ZwClose (hFile);
    112         return Status;
    113     }
    114 
    115     KdPrint(("CreationTime:0x%X    Attributes:0x%X", fbi.CreationTime, fbi.FileAttributes));
    116     fbi.FileAttributes |= FILE_ATTRIBUTE_HIDDEN;    //隐藏文件
    117     fbi.FileAttributes |= FILE_ATTRIBUTE_READONLY;    //只读属性
    118 
    119 
    120     Status = ZwSetInformationFile (hFile, &IoStatusBlock, &fbi, sizeof(FILE_BASIC_INFORMATION),    FileBasicInformation);
    121     if (!NT_SUCCESS(Status))
    122     {
    123         KdPrint(("Set Information Error:0x%X", Status));
    124         ZwClose(hFile);
    125         return Status;
    126     }
    127 
    128     ZwClose(hFile);
    129 
    130     return Status;
    131 }
    132 
    133 NTSTATUS MyReadFile()
    134 {
    135     HANDLE hFile;
    136 
    137     UNICODE_STRING usFileName;
    138     NTSTATUS Status = STATUS_SUCCESS;
    139     OBJECT_ATTRIBUTES FileObjAttr;
    140     IO_STATUS_BLOCK IoStatusBlock;
    141     LARGE_INTEGER ReadBuffer;
    142 
    143     char strBuffer[100] = {0};
    144 
    145     RtlInitUnicodeString (&usFileName, L"\??\c:\test.txt");
    146     memset (&FileObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));
    147 
    148     InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
    149 
    150     Status = ZwOpenFile(&hFile, 
    151         GENERIC_ALL,
    152         &FileObjAttr,
    153         &IoStatusBlock,
    154         FILE_SHARE_READ,
    155         FILE_NON_DIRECTORY_FILE);
    156     if (!NT_SUCCESS(Status))
    157     {
    158         KdPrint(("Open File Failed:0x%X", Status));
    159         return Status;
    160     }
    161 
    162     KdPrint(("Open File Success!"));
    163     ReadBuffer.QuadPart = 0;
    164 
    165     Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)strBuffer, 16, &ReadBuffer, NULL);    //从文件的0位置读取16个字节到strBuffer
    166     if (!NT_SUCCESS(Status))
    167     {
    168         KdPrint(("ReadFile Failed, Error Code:0x%X", Status));
    169         ZwClose(hFile);
    170         return Status;
    171     }
    172     
    173     KdPrint(("strBuffer:<%s>", strBuffer));
    174 
    175     
    176     ZwClose(hFile);
    177     return Status;
    178 }
    179 
    180 NTSTATUS MyWriteFile()
    181 {
    182     HANDLE hFile;
    183 
    184     UNICODE_STRING usFileName;
    185     NTSTATUS Status = STATUS_SUCCESS;
    186     OBJECT_ATTRIBUTES FileObjAttr;
    187     IO_STATUS_BLOCK IoStatusBlock;
    188     LARGE_INTEGER WriteBuffer;
    189 
    190      char strBuffer[100] = "ahuakndkaj.;'?";
    191 
    192     RtlInitUnicodeString (&usFileName, L"\??\c:\test.txt");
    193     memset (&FileObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));
    194 
    195     InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
    196 
    197     Status = ZwOpenFile(&hFile, 
    198         GENERIC_ALL,
    199         &FileObjAttr,
    200         &IoStatusBlock,
    201         FILE_SHARE_READ,
    202         FILE_NON_DIRECTORY_FILE);
    203     if (!NT_SUCCESS(Status))
    204     {
    205         KdPrint(("Open File Failed:0x%X", Status));
    206         return Status;
    207     }
    208 
    209     KdPrint(("Open File Success!"));
    210     
    211     WriteBuffer.QuadPart = 0;
    212 
    213     Status = ZwWriteFile(hFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)strBuffer, 16, &WriteBuffer, NULL);    //将strBuffer中的前16个字节写入文件,从文件的0位置开始写
    214     if (!NT_SUCCESS(Status))
    215     {
    216         KdPrint(("WriteFile Failed, Error Code:0x%X", Status));
    217         ZwClose(hFile);
    218         return Status;
    219     }
    220     
    221     ZwClose(hFile);
    222     return Status;
    223 }
    224 
    225 VOID MyUnload(PDRIVER_OBJECT pDriverObject)
    226 {
    227     KdPrint(("Unload MyCreateFile.sys Success"));
    228 }
    229 
    230 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
    231 {
    232     pDriverObject->DriverUnload = MyUnload;
    233 
    234     MyOpenFile();
    235     MyCreateFile();
    236     MyOpenFile();
    237 
    238      MyReadFile();
    239     MyWriteFile();
    240      MyReadFile();
    241     
    242     MyZwSetInfomationFile();
    243 
    244     return STATUS_SUCCESS;
    245 }
    MyCreateFile.c

    文件的操作函数有:

    ZwCreateFile            //创建文件或者打开文件
    ZwOpenFile             //打开文件
    ZwQueryInformationFile    //查看文件信息
    ZwSetInformationFile      //设置文件信息
    ZwReadFile           //读取文件
    ZwWriteFile          //写入文件

    创建或打开文件ZwCreateFile

     1 NTSTATUS ZwCreateFile(
     2   _Out_    PHANDLE            FileHandle,              //文件句柄
     3   _In_     ACCESS_MASK        DesiredAccess,           //访问权限,一般为GENERIC_ALL,即所有权限
     4   _In_     POBJECT_ATTRIBUTES ObjectAttributes,          //文件对象的属性,需要用InitializeObjectAttributes来初始化
     5   _Out_    PIO_STATUS_BLOCK   IoStatusBlock,           //用于接收返回信息
     6   _In_opt_ PLARGE_INTEGER     AllocationSize,         
    7
    _In_ ULONG FileAttributes,   //FILE_ATTRIBUTE_NORMAL 8 _In_ ULONG ShareAccess,   //FILE_SHARE_READ 9 _In_ ULONG CreateDisposition,    //FILE_OPEN_IF 如果没有文件,创建文件。如果有文件,直接打开 10 _In_ ULONG CreateOptions,    //FILE_NON_DIRECTORY_FILE 不是目录 11 _In_opt_ PVOID EaBuffer, //NULL 12 _In_ ULONG EaLength   //0 13 );

    其中的第三个参数ObjectAttributes需要使用函数InitializeObjectAttributes来初始化,函数参数:

    1 VOID InitializeObjectAttributes(
    2   [out]          POBJECT_ATTRIBUTES   InitializedAttributes,      //文件对象指针
    3   [in]           PUNICODE_STRING      ObjectName,                  //文件路径及名称
    4   [in]           ULONG                Attributes,                  //flag,一般是OBJ_CASE_INSENSITIVE(大小写不敏感)
    5   [in]           HANDLE               RootDirectory,              //根目录,如果ObjectName是绝对路径的话,那么根目录就是NULL
    6   [in, optional] PSECURITY_DESCRIPTOR SecurityDescriptor          //默认为NULL
    7 );

    打开文件函数ZwOpenFile:

    1 NTSTATUS ZwOpenFile(
    2   _Out_ PHANDLE            FileHandle,
    3   _In_  ACCESS_MASK        DesiredAccess,
    4   _In_  POBJECT_ATTRIBUTES ObjectAttributes,
    5   _Out_ PIO_STATUS_BLOCK   IoStatusBlock,
    6   _In_  ULONG              ShareAccess,
    7   _In_  ULONG              OpenOptions        //和ZwCreateFile的CreateOptions参数相同. FILE_NON_DIRECTORY_FILE 不是目录
    8 );

    获取文件属性函数ZwQueryInformationFile:

    1 NTSTATUS ZwQueryInformationFile(
    2   _In_  HANDLE                 FileHandle,
    3   _Out_ PIO_STATUS_BLOCK       IoStatusBlock,
    4   _Out_ PVOID                  FileInformation,            //接收文件相应FileInformationClass信息的结构
    5   _In_  ULONG                  Length,                     //FileInformation的大小
    6   _In_  FILE_INFORMATION_CLASS FileInformationClass        //指定获取文件什么信息(FileInformation)的枚举值
    7 );

    设置文件属性函数ZwSetInformationFile

    1 NTSTATUS ZwSetInformationFile(
    2   _In_  HANDLE                 FileHandle,
    3   _Out_ PIO_STATUS_BLOCK       IoStatusBlock,
    4   _In_  PVOID                  FileInformation,
    5   _In_  ULONG                  Length,
    6   _In_  FILE_INFORMATION_CLASS FileInformationClass
    7 );

    读取文件函数ZwReadFile:

     1 NTSTATUS ZwReadFile(
     2   _In_     HANDLE           FileHandle,
     3   _In_opt_ HANDLE           Event,                
     4   _In_opt_ PIO_APC_ROUTINE  ApcRoutine,            
     5   _In_opt_ PVOID            ApcContext,            
     6   _Out_    PIO_STATUS_BLOCK IoStatusBlock,
     7   _Out_    PVOID            Buffer,                //保存读取到的
     8   _In_     ULONG            Length,                //从文件读取多少个字节
     9   _In_opt_ PLARGE_INTEGER   ByteOffset,            //从文件的哪个位置开始读取,传入一个LARGE_INTEGER的指针
    10   _In_opt_ PULONG           Key                    //NULL
    11 );

    写入文件函数ZwWriteFile

     1 NTSTATUS ZwWriteFile(
     2   _In_     HANDLE           FileHandle,
     3   _In_opt_ HANDLE           Event,
     4   _In_opt_ PIO_APC_ROUTINE  ApcRoutine,
     5   _In_opt_ PVOID            ApcContext,
     6   _Out_    PIO_STATUS_BLOCK IoStatusBlock,
     7   _In_     PVOID            Buffer,
     8   _In_     ULONG            Length,
     9   _In_opt_ PLARGE_INTEGER   ByteOffset,
    10   _In_opt_ PULONG           Key
    11 );

    有些地方可能现在还不太清楚,以后再回来补吧。

    操作部分:

    启动并按章MyCreateFile.sys驱动后,C盘生成了test.txt的文件

    这个文件是只读的,并且是隐藏的:

    test.txt文件中写着“ahuakndkaj.;'?  "

    DbgView输出:

    0. 没有相应文件时,MyOpenFile里 ZwOpenFile打开文件失败

    1. MyCreateFile里 ZwCreateFile创建文件成功

    2. MyOpenFile里 ZwOpenFile打开文件成功

    3. MyReadFile里 ZwOpenFile打开文件成功

    4. MyReadFile里 ZwReadFile读取文件失败 这时文件中还没有数据

    5. MyWriteFile里 ZwOpenFile打开文件成功 没输出错误 说明ZwWriteFile也成功了

    6. MyReadFile里 ZwReadFile读取文件成功

    7. MyReadFile里 读取到了数据

    8. MyZwQueryInfomationFile里 打开文件成功

    9. 获取文件属性成功 没输出错误 说明MyZwSetInfomationFile也成功了

    10. 驱动卸载成功

  • 相关阅读:
    OpenLDAP备份和恢复
    OpenLDAP搭建部署
    Python正则表达式
    ansible学习
    Jenkins学习
    docker学习2
    让阿里告诉你, iOS开发者为什么要学 Flutter !
    用UIKit和UIView在视图上执行iOS动画
    iOS开发如何面对疫情过后的面试高峰期 !
    如何写好一个UITableView
  • 原文地址:https://www.cnblogs.com/linuxxiaoyu/p/5683026.html
Copyright © 2020-2023  润新知