登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 9|回复: 0

驱动开发与系统原理-文件操作-写入文件

[复制链接]
回帖奖励 20 断点币 回复本帖可获得 1 断点币奖励! 每人限 1 次

56

主题

-7

回帖

66

积分

网站编辑

积分
66
发表于 昨天 20:50 | 显示全部楼层 |阅读模式

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)
          #define CTL_WRITE_FILE IRP_IOCTRL_CODE(1)
          #define CTL_WRITE_DATA IRP_IOCTRL_CODE(2)
          #define CTL_READ_PATH IRP_IOCTRL_CODE(3)

          //全局变量
          char g_FilePath[0x256] = { 0 };//文件路径
          //缓冲区
          char g_Buffer[0x1024] = { 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;
            //结束IRP处理流程
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);
            return STATUS_SUCCESS;
          }

          //文件操作-写入文件
          NTSTATUS  WriteFileIoCall(char* szData) {
              //状态码
              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 };
              WCHAR  wcBuffer[256];
              ULONG wcbufferLen = 256 * sizeof(WCHAR);
              RtlInitEmptyUnicodeString(&usDrvPath, &wcBuffer, wcbufferLen);
              RtlInitUnicodeString(&usDriverFilePath, L"\\??\\");
              RtlInitAnsiString(&asFilePath, g_FilePath);
              RtlAnsiStringToUnicodeString(&usFilePath, &asFilePath, TRUE);
              RtlAppendUnicodeStringToString(&usDrvPath, &usDriverFilePath);
              RtlAppendUnicodeStringToString(&usDrvPath, &usFilePath);
              RtlFreeUnicodeString(&usFilePath);
              InitializeObjectAttributes(&ObjectAtt, &usDrvPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
              ntSTATUS = ZwCreateFile(&hFile,GENERIC_WRITE, &ObjectAtt, &Iostatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
              if (!NT_SUCCESS(ntSTATUS)) {
                  return ntSTATUS;
              }
              ULONG uDataLength = strlen(szData) * sizeof(char);
              ntSTATUS = ZwWriteFile(hFile, NULL, NULL, NULL, &Iostatus, szData, uDataLength, NULL, NULL);
              ZwClose(hFile);
              return ntSTATUS;

          }

          //文件操作-创建文件
          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 };
              WCHAR  wcBuffer[256];
              ULONG wcbufferLen = 256 * sizeof(WCHAR);
              RtlInitEmptyUnicodeString(&usDrvPath, &wcBuffer, wcbufferLen); 
              RtlInitUnicodeString(&usDriverFilePath, L"\\??\\");
              RtlInitAnsiString(&asFilePath, szFilePath);
              RtlAnsiStringToUnicodeString(&usFilePath, &asFilePath, TRUE);
              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) {
            //状态码
              NTSTATUS  ntStatus = 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;
            }

            case CTL_WRITE_FILE: {
                RtlZeroMemory(g_FilePath, 0x256);
                RtlCopyMemory(g_FilePath, pInputBuffer, uInputLength);
                RtlZeroMemory(pOutputBuffer,  1024);
                ULONG uRetlength = strlen("Success!");
                RtlCopyMemory(pOutputBuffer, "Success!", uRetlength);
                pIrp->IoStatus.Status = STATUS_SUCCESS;
                pIrp->IoStatus.Information = uRetlength;
                IoCompleteRequest(pIrp, IO_NO_INCREMENT);
                return STATUS_SUCCESS;
            }

            case CTL_WRITE_DATA: {
                ntStatus = WriteFileIoCall(pInputBuffer);
                if (NT_SUCCESS(ntStatus)) {
                    RtlZeroMemory(pOutputBuffer,1024);
                    ULONG uRetlength = strlen("Write Success!");
                    RtlCopyMemory(pOutputBuffer, "Write Success!", uRetlength);
                    pIrp->IoStatus.Status = STATUS_SUCCESS;
                    pIrp->IoStatus.Information = uRetlength;
                    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

                }
                else {
                    RtlZeroMemory(pOutputBuffer,1024);
                    ULONG uRetlength = strlen("Write Failed!");
                    RtlCopyMemory(pOutputBuffer, "Write Failed!", 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;
            }
            pDeviceObject->Flags |= DO_BUFFERED_IO;

            //创建符号链接
            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[i] = DispatchCommon;
            }
            pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoCtrl;
            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)
      #define CTL_WRITE_FILE IRP_IOCTRL_CODE(1)
      #define CTL_WRITE_DATA IRP_IOCTRL_CODE(2)
      #define CTL_READ_PATH IRP_IOCTRL_CODE(3)
      int main() {

        CHAR InputBuffer[1024] = { 0 };
        CHAR OutputBuffer[1024] = { 0 };
        DWORD RetNumber = 0;
        CHAR Data[1024] = { 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':
          {
            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;
          }
          case '2':
          {
            memset(InputBuffer, 0, sizeof(InputBuffer));
            memset(OutputBuffer, 0, sizeof(OutputBuffer));
            memset(Data, 0, sizeof(InputBuffer));
            printf("请输入要写入数据的文件的路径:\n");
            scanf("%s", InputBuffer);
            printf("\n请输入要写入的数据:\n");
            scanf("%s", Data);
            DeviceIoControl(hDriver, CTL_WRITE_FILE, InputBuffer, sizeof(InputBuffer), OutputBuffer, sizeof(OutputBuffer), &RetNumber, NULL);//先确定写哪个文件
            if (!strcmp(OutputBuffer,"Success!"))
            {
              memset(OutputBuffer, 0, sizeof(OutputBuffer));
              DeviceIoControl(hDriver, CTL_WRITE_DATA, Data, sizeof(Data), OutputBuffer, sizeof(OutputBuffer), &RetNumber, NULL);//写入什么数据,数据通过inputbuffer传入
              printf("%s\n", OutputBuffer);
              system("pause");
            }

            break;
          }


          case'3':
          {
            RetNumber = 0;
            memset(InputBuffer, 0, sizeof(InputBuffer));
            memset(OutputBuffer, 0, sizeof(OutputBuffer));
            printf("请输入需要读取数据的文件路径:\n");
            scanf("%s", InputBuffer); 
            DeviceIoControl(hDriver, CTL_READ_PATH, InputBuffer, sizeof(InputBuffer), OutputBuffer, sizeof(OutputBuffer), &RetNumber, NULL);
            printf("读取数据:%s\n", OutputBuffer);
            system("pause");
            break;
          }
          default:
            break;
          }
        }
        return 0;
      }

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-1-24 19:35 , Processed in 0.053425 second(s), 28 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表