大理寺少卿 发表于 2025-1-23 20:49:24

驱动开发与系统原理-文件操作-创建文件

0环代码

```
      #include<ntifs.h>
      //设备对象名称
      #define DEVICE_NAME L"\\device\\FileDrv"
      //符号链接名称
      #define LINK_NAME L"\\dosdevices\\whitebird"
      //控制码起始地址
      #define IRP_IOCTRLL_BASE 0x8000
      //控制码的宏定义
      #define IRP_IOCTRL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN,IRP_IOCTRLL_BASE+i,METHOD_BUFFERED,FILE_ANY_ACCESS)
      //控制码定义
      #define CTL_CREATE_FILE IRP_IOCTRL_CODE(0)


      VOID DriverUnload(PDRIVER_OBJECT pDriver) {   
          UNICODE_STRING uLinkName = { 0 };               //符号链接名称   
          RtlInitUnicodeString(&uLinkName, LINK_NAME);    //初始化符号链接名称      
          IoDeleteSymbolicLink(&uLinkName);               //删除符号链接      
          IoDeleteDevice(pDriver->DeviceObject);          //删除设备对象
          DbgPrint("Unload success!\n");

      }

      //IRP派遣函数-默认处理
      NTSTATUS DispatchCommon (PDEVICE_OBJECT pDeviceObject,PIRP pIrp){
          DbgPrint("Patched Success");                  //设置IRP处理成功,告诉3环
          pIrp->IoStatus.Status = STATUS_SUCCESS;      
          pIrp->IoStatus.Information = 0;               //设置返回的字节数
          IoCompleteRequest(pIrp, IO_NO_INCREMENT);   //结束IRP处理流程
          return STATUS_SUCCESS;
      }

      //文件操作-创建文件
      NTSTATUS CreateFileIoCall(char *szFilePath) {
            //状态码
            NTSTATUS ntSTATUS = STATUS_SUCCESS;
            //文件句柄
            HANDLE hFile = NULL;
            //完成状态
            IO_STATUS_BLOCK Iostatus = { 0 };
            //对象属性
            OBJECT_ATTRIBUTES ObjectAtt = { 0 };
            //三环c:\a.txt
            //0环:\\??\\c:\a.txt
            //将三环路径转换成驱动使用的路径
            ANSI_STRING asFilePath = { 0 };
            UNICODE_STRING usFilePath = { 0 };
            UNICODE_STRING usDriverFilePath = { 0 };
            UNICODE_STRING usDrvPath = { 0 };
            WCHARwcBuffer;
            ULONG wcbufferLen = 256 * sizeof(WCHAR);
            RtlInitEmptyUnicodeString(&usDrvPath, &wcBuffer, wcbufferLen);
            RtlInitUnicodeString(&usDriverFilePath, L"\\??\\");
            RtlInitAnsiString(&asFilePath, szFilePath);
            RtlAnsiStringToUnicodeString(&usFilePath, &asFilePath, TRUE);         //把ANSI转换成UNICODE
            RtlAppendUnicodeStringToString(&usDrvPath, &usDriverFilePath);      //把\\??\\与用户输入路径进行拼接
            RtlAppendUnicodeStringToString(&usDrvPath, &usFilePath);
            RtlFreeUnicodeString(&usFilePath);
            //初始化对象属性
            InitializeObjectAttributes(&ObjectAtt, &usDrvPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
            //创建文件
            ntSTATUS = ZwCreateFile(&hFile, GENERIC_ALL, &ObjectAtt, &Iostatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
            //判断是否创建成功
            if (NT_SUCCESS(ntSTATUS))
            {
                ZwClose(hFile);       //关闭文件句柄
                return STATUS_SUCCESS;
            }
            else
            {
                return ntSTATUS;
            }


      }
      //IRP派遣函数-控制派遣
      NTSTATUS DispatchIoCtrl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) {
          //状态码
            NTSTATUSntStatus = STATUS_SUCCESS;
          //控制码
          ULONG uIoCode = 0;
          //输入缓冲区
          PVOID pInputBuffer = NULL;
          //输出缓冲区
          PVOID pOutputBuffer = NULL;
          //输入缓冲区的长度
          ULONG uInputLength = 0;
          //栈结构指针
          PIO_STACK_LOCATION pStack = NULL;
          //获取缓冲区
          pInputBuffer = pOutputBuffer = pIrp->AssociatedIrp.SystemBuffer;
          //获取IRP栈
          pStack = IoGetCurrentIrpStackLocation(pIrp);
          uInputLength = pStack->Parameters.DeviceIoControl.InputBufferLength;
          //获取控制码
          uIoCode = pStack->Parameters.DeviceIoControl.IoControlCode;
          switch (uIoCode)
          {
          case CTL_CREATE_FILE:
          {
            ntStatus=CreateFileIoCall(pInputBuffer);      //调用我们自己实现的打开文件的函数
            if ( !NT_SUCCESS(ntStatus))
            {
                  RtlZeroMemory(pOutputBuffer, 1024);
                  ULONG uRetlength = strlen("CreatFile Failed!");
                  RtlCopyMemory(pOutputBuffer, "CreatFile Failed!", uRetlength);
                  pIrp->IoStatus.Status = STATUS_SUCCESS;
                  pIrp->IoStatus.Information = uRetlength;
                  IoCompleteRequest(pIrp, IO_NO_INCREMENT);
            }else{
                  RtlZeroMemory(pOutputBuffer, 1024);
                  ULONG uRetlength = strlen("CreatFile Success!");
                  RtlCopyMemory(pOutputBuffer, "CreatFile Success!", uRetlength);
                  pIrp->IoStatus.Status = STATUS_SUCCESS;
                  pIrp->IoStatus.Information = uRetlength;
                  IoCompleteRequest(pIrp, IO_NO_INCREMENT);
            }

            return STATUS_SUCCESS;
          }
          default:
            break;
          }
          //设置IRP处理成功,告诉3环
          pIrp->IoStatus.Status = STATUS_SUCCESS;
          //设置返回的字节数
          pIrp->IoStatus.Information = 0;
          //结束IRP处理流程
          IoCompleteRequest(pIrp, IO_NO_INCREMENT);
          return STATUS_SUCCESS;
          }



      NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) {//驱动对象指针,注册表路径 DriverEntry不能改

          //注册卸载函数,作用是指定用哪个函数来完成卸载
          pDriverObject->DriverUnload = DriverUnload;
          //返回状态
          NTSTATUS ntStatus = 0;
          //设备对象
          UNICODE_STRING uDevicename = { 0 };
          //符号链接名称
          UNICODE_STRING uLinkName = { 0 };
          //初始化设备对象
          RtlInitUnicodeString(&uDevicename, DEVICE_NAME);
          //初始化符号链接名称
          RtlInitUnicodeString(&uLinkName, LINK_NAME);
          //设备对象
          PDEVICE_OBJECT pDeviceObject = NULL;
          //创建设备对象
          ntStatus=IoCreateDevice(pDriverObject, 0, &uDevicename, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDeviceObject);
          //判断设备对象是否创建成功
          if (!NT_SUCCESS(ntStatus))
          {
            DbgPrint("IoCreateDevice failed:%x", ntStatus);
            return ntStatus;
          }
      
          //创建符号链接
          ntStatus = IoCreateSymbolicLink(&uLinkName, &uDevicename);
          //判断符号链接是否创建成功
          if (!NT_SUCCESS(ntStatus))
          {        //删除设备对象
            IoDeleteDevice(&pDeviceObject);
            DbgPrint("IoCreateSymbolicLink failed:%x", ntStatus);
            return ntStatus;
          }

          //将所有IRP派遣处理函数,设置为默认处理函数
          for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
          {
            pDriverObject->MajorFunction = DispatchCommon;
          }
          pDriverObject->MajorFunction = DispatchIoCtrl;   //IO_CONTROL的回调函数
          DbgPrint("Driver Load Success!");
          return STATUS_SUCCESS;//状态成功0,一定要有返回值
      }

```

3环代码

```
      #define _CRT_SECURE_NO_WARNINGS
      #include<stdio.h>
      #include<Windows.h>
      #define DEVICE_LINK_NAME L"\\\\.\\whitebird"
      //控制码起始地址
      #define IRP_IOCTRLL_BASE 0x8000
      //控制码的宏定义
      #define IRP_IOCTRL_CODE(i) CTL_CODE(FILE_DEVICE_UNKNOWN,IRP_IOCTRLL_BASE+i,METHOD_BUFFERED,FILE_ANY_ACCESS)
      //控制码定义
      #define CTL_CREATE_FILE IRP_IOCTRL_CODE(0)

      int main() {
          CHAR InputBuffer = { 0 };
          CHAR OutputBuffer = { 0 };
          DWORD RetNumber = 0;
          //创建文件、读取文件、写出文件、拷贝文件、删除文件、移动文件、获取文件属性、设置文件属性、保护文件、接触保护、强行删除
          HANDLE hDriver = CreateFile(DEVICE_LINK_NAME, GENERIC_ALL,0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
          if (hDriver==INVALID_HANDLE_VALUE)
          {
            printf("file error code : %d", GetLastError());
            system("pause");
            return 1;
          }
          while (TRUE)
          {
            system("cls");
            printf("请输入您需要的选项:\n");
            printf("1.创建文件(ZwCreateFile)\n");
            printf("2.写入文件(ZwWriteFile)\n");
            printf("3.读取文件(ZwReadFile)\n");
            printf("4.拷贝文件(ZwWriteFile&ZwReadFile)\n");
            printf("5.删除文件(ZwDeleteFile)\n");
            printf("6.删除文件(ZwSetInformationFile)\n");
            printf("7.移动文件(ZwWriteFile&ZwReadFile&ZwDeleteFile)\n");
            printf("8.获取属性(ZwQueryFullAttributesFile)\n");
            printf("9.设置属性(ZwSetInformationFile)\n");
            char flag = getchar();
            switch (flag)
            {
            case '1':
            {
            system("cls");
            memset(InputBuffer, 0, sizeof(InputBuffer));
            memset(OutputBuffer, 0, sizeof(OutputBuffer));
            printf("请输入文件创建路径:\n");
            scanf("%s", InputBuffer);
            DeviceIoControl(hDriver, CTL_CREATE_FILE, InputBuffer, sizeof(InputBuffer), OutputBuffer, sizeof(OutputBuffer), &RetNumber, NULL);
            printf("%s\n", OutputBuffer);
            system("pause");
            break;
            }
            default:
            break;
            }
          }
          return 0;
      }
```

我们这里先实现文件创建,后面陆续实现其他功能

![](https://raw.githubusercontent.com/Whitebird0/tuchuang/main/QQ%E6%88%AA%E5%9B%BE20211204163434.png)
页: [1]
查看完整版本: 驱动开发与系统原理-文件操作-创建文件