windows内核安全(四)

文件操作

Posted by volcanohatred on May 20, 2018

文件操作

文件的表示:

R3:”c:\\doc\\hi.txt”
R0:L”\\??\\hi.txt“->\\device\\harddiskvolume3\\hi.txt

设备名的表示方法:

R3:L”\\\\.\\XXX”
R0:”\\device\\XXX”

常用API

读文件:ZwReadFile
写文件:ZwWriteFile
读文件属性:ZwQueryInformationFile  
写文件属性:ZwSetInformationFile
遍历文件夹:ZwQueryDirectoryFile

ZwQueryInformationFile 里面的FileInformationClass很关键!!!

NTSTATUS  ZwQueryInformationFile( 
    IN HANDLE   FileHandle , 
    OUT PIO_STATUS_BLOCK   IoStatusBlock , 
    OUT PVOID   FileInformation , 
    IN ULONG   Length , 
    IN FILE_INFORMATION_CLASS   FileInformationClass 
    );

(1)当 FileInformationClass 是 FileStandardInformation 时,输入和输出数据是 FILE_STANDARD_INFORMATION 结构体,描述文件的标准信息。

typedef struct FILE_STANDARD_INFORMATION {
  LARGE_INTEGER  AllocationSize ; // 为文件非配的大小
  LARGE_INTEGER  EndOfFile ; // 距离文件结尾还有多少字节
  ULONG  NumberOfLinks ; // 有多少要个链接文件
  BOOLEAN  DeletePending ; // 是否准备删除
  BOOLEAN  Directory ; // 是否为目录
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;

(2)当 FileInformationClass 是 FileBasicInformation 时,输入和输出数据是 FILE_BASIC_INFORMATION 结构体,描述文件的基本信息。

typedef struct FILE_BASIC_INFORMATION {
  LARGE_INTEGER  CreationTime ;
  LARGE_INTEGER  LastAccessTime ;
  LARGE_INTEGER  LastWriteTime ;
  LARGE_INTEGER  ChangeTime ;
  ULONG  FileAttributes ; // 文件属性
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

(3)当FileInformationClass 是 FileNameInformation 时,输入和输出数据是 FILE_NAME_INFORMATION 结构体,描述文件名信息。

typedef struct _FILE_NAME_INFORMATION {
  ULONG  FileNameLength ; // 文件名长度
  WCHAR  FileName [1]; // 文件名
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

(4)当FileInformationClass 是 FilePositionInformation 时,输入和输出数据是 FILE_POSITION_INFORMATION 结构体,描述文件指针位置信息。

typedef struct FILE_POSITION_INFORMATION {
  LARGE_INTEGER  CurrentByteOffset ; // 代表当期文件指针为止
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;

文件操作C代码:

#include <ntifs.h>
#include <ntddk.h>

NTSTATUS ntCreateFile(WCHAR *szFileName);
NTSTATUS ntCreateDirectory(WCHAR *szDirName);

NTSTATUS ntWriteFile(WCHAR *szFileName);
NTSTATUS ntReadFile(WCHAR *szFile);
NTSTATUS ntCopyFile(const WCHAR * src, const WCHAR * dst);
NTSTATUS ntMoveFile(const WCHAR * src, const WCHAR * dst);
NTSTATUS ntDeleteFile1(const WCHAR * filename);
NTSTATUS ntDeleteFile2(const WCHAR *fileName);

ULONG ntGetFileAttributes(const WCHAR * filename);
NTSTATUS ntSetFileAttribute(WCHAR *szFileName);



VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
   NTSTATUS ntStatus = 0;

   WCHAR        *szFileName1 = L"\\??\\d:\\1.txt";
   WCHAR        *szFileName2 = L"\\??\\d:\\2.txt";

   ntStatus = ntDeleteFile2(szFileName1);
   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntDeleteFile2() failed%d\n", ntStatus);
      //return;
   }

   ntStatus = ntDeleteFile2(szFileName2);
   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntDeleteFile2() failed%ws,%x\n", szFileName2, ntStatus);
      return;
   }
   DbgPrint("Driver Unloaded\n");
}

NTSTATUS FileOper(VOID);

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
   DbgPrint("Driver begin\n");
   pDriverObject->DriverUnload = DriverUnload;

   FileOper();

   return STATUS_SUCCESS;
}

NTSTATUS FileOper(VOID)
{
   NTSTATUS      ntStatus = STATUS_SUCCESS;
   ULONG        ulAttributes = 0;
   WCHAR        *szDirName = L"\\??\\D:\\Mallocfree\\";
   WCHAR        *szFileName1 = L"\\??\\d:\\1.txt";
   WCHAR        *szFileName2 = L"\\??\\d:\\2.txt";
   WCHAR        *szFileName3 = L"\\??\\D:\\Mallocfree\\3.txt";
   WCHAR        *szFileName4 = L"\\??\\D:\\Mallocfree\\4.txt";


   ntStatus = ntCreateFile(szFileName1);
   if (!NT_SUCCESS(ntStatus))
   {

      DbgPrint("ntCreateFile() failed:%x\n", ntStatus);
      return ntStatus;
   }

   ntStatus = ntCreateDirectory(szDirName);
   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntCreateDirectory() failed:%x\n", ntStatus);
      return ntStatus;
   }


   ntStatus = ntWriteFile(szFileName1);
   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntWriteFile() failed:%x\n", ntStatus);
      return ntStatus;
   }

   ntStatus = ntReadFile(szFileName1);
   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntReadFile() failed:%x\n", ntStatus);
      return ntStatus;
   }

   ntStatus = ntCopyFile(szFileName1, szFileName2);

   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntCopyFile() failed:%x\n", ntStatus);
      return ntStatus;
   }

   ntStatus = ntCopyFile(szFileName1, szFileName3);

   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntCopyFile() failed:%x\n", ntStatus);
      return ntStatus;
   }


   ntStatus = ntMoveFile(szFileName1, szFileName4);

   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint("ntMoveFile() failed:%x\n", ntStatus);
      return ntStatus;
   }


   ulAttributes = ntGetFileAttributes(szFileName1);
   if (ulAttributes & FILE_ATTRIBUTE_DIRECTORY)
   {
      DbgPrint("%S is a directory\n", szFileName1);
   }
   else
   {
      DbgPrint("%S is not a directory\n", szFileName1);

   }

   ulAttributes = ntGetFileAttributes(szDirName);
   if (ulAttributes & FILE_ATTRIBUTE_DIRECTORY)
   {
      DbgPrint("%S is a directory\n", szDirName);
   }
   else
   {
      DbgPrint("%S is not a directory\n", szDirName);

   }

   //     ntStatus = ntDeleteFile2(szFileName1);
   //     if (!NT_SUCCESS(ntStatus))
   //     {
   //        DbgPrint("ntDeleteFile2() failed\n", ntStatus);
   //        return ntStatus;
   //     }
   // 
   //     ntStatus = ntDeleteFile2(szFileName2);
   //     if (!NT_SUCCESS(ntStatus))
   //     {
   //        DbgPrint("ntDeleteFile2() failed\n", ntStatus);
   //        return ntStatus;
   //     }

   return ntStatus;
}

//创建文件
NTSTATUS ntCreateFile(WCHAR *szFileName)//L"\\??\\c:\\doc\\1.txt"
{
   OBJECT_ATTRIBUTES     objAttrib = { 0 };
   UNICODE_STRING       uFileName = { 0 };
   IO_STATUS_BLOCK           io_status = { 0 };
   HANDLE                     hFile = NULL;
   NTSTATUS                    status = 0;

   RtlInitUnicodeString(&uFileName, szFileName);   
   InitializeObjectAttributes(
      &objAttrib,                    
      &uFileName,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL
   );


   status = ZwCreateFile(
      &hFile,
      GENERIC_WRITE,
      &objAttrib,
      &io_status,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //共享读,写,删除,改为0则独占
      FILE_OPEN_IF,  //重要参数,存在打开,不存在创建再打开,还有很多选项可查看MSDN
      FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,   //同步操作|普通文件或者文件夹
      NULL,
      0);

   if (NT_SUCCESS(status))
   {
      ZwClose(hFile);
   }

   return status;
}

//创建文件夹
NTSTATUS ntCreateDirectory(WCHAR *szDirName)//L"\\??\\c:\\doc\\"
{
   OBJECT_ATTRIBUTES     objAttrib = { 0 };
   UNICODE_STRING       uDirName = { 0 };
   IO_STATUS_BLOCK           io_status = { 0 };
   HANDLE                     hFile = NULL;
   NTSTATUS                    status = 0;

   RtlInitUnicodeString(&uDirName, szDirName);
   InitializeObjectAttributes(&objAttrib,
      &uDirName,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL);

   status = ZwCreateFile(&hFile,
      GENERIC_READ | GENERIC_WRITE,
      &objAttrib,
      &io_status,
      NULL,
      FILE_ATTRIBUTE_DIRECTORY,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      FILE_OPEN_IF,
      FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
      NULL,
      0);
   if (NT_SUCCESS(status))
   {
      ZwClose(hFile);
   }

   return status;

}

//获取文件属性
ULONG ntGetFileAttributes(const WCHAR * filename)
{
   ULONG                    dwRtn = 0;
   NTSTATUS                  ntStatus = STATUS_UNSUCCESSFUL;
   OBJECT_ATTRIBUTES           objAttr = { 0 };
   UNICODE_STRING             uName = { 0 };
   FILE_NETWORK_OPEN_INFORMATION  info = { 0 };


   if (filename == NULL)
   {
      return ntStatus;
   }
   RtlInitUnicodeString(&uName, filename);
   RtlZeroMemory(&info, sizeof(FILE_NETWORK_OPEN_INFORMATION));

   InitializeObjectAttributes(
      &objAttr,
      &uName,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL
   );
   ntStatus = ZwQueryFullAttributesFile(
      &objAttr,
      &info);
   if (NT_SUCCESS(ntStatus))
   {
      dwRtn = info.FileAttributes;
   }
   if (dwRtn & FILE_ATTRIBUTE_DIRECTORY)
   {
      DbgPrint("%S is a directory\n", filename);
   }
   return dwRtn;
}

//设置文件属性
NTSTATUS ntSetFileAttribute(WCHAR *szFileName)
{
   OBJECT_ATTRIBUTES        objectAttributes = { 0 };
   IO_STATUS_BLOCK          iostatus = { 0 };
   HANDLE                    hfile = NULL;
   UNICODE_STRING              uFile = { 0 };
   FILE_STANDARD_INFORMATION  fsi = { 0 };
   FILE_POSITION_INFORMATION  fpi = { 0 };
   NTSTATUS               ntStatus = 0;


   RtlInitUnicodeString(&uFile, szFileName);
   InitializeObjectAttributes(&objectAttributes,
      &uFile,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL);

   ntStatus = ZwCreateFile(&hfile,
      GENERIC_READ,
      &objectAttributes,
      &iostatus,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      0,
      FILE_OPEN,
      FILE_SYNCHRONOUS_IO_NONALERT,
      NULL,
      0);
   if (!NT_SUCCESS(ntStatus))
   {
      return ntStatus;
   }

   ntStatus = ZwQueryInformationFile(hfile,
      &iostatus,
      &fsi,
      sizeof(FILE_STANDARD_INFORMATION),
      FileStandardInformation);
   if (!NT_SUCCESS(ntStatus))
   {
      ZwClose(hfile);
      return ntStatus;
   }

   fpi.CurrentByteOffset.QuadPart = 100i64;


   ntStatus = ZwSetInformationFile(hfile,
      &iostatus,
      &fpi,
      sizeof(FILE_POSITION_INFORMATION),
      FilePositionInformation);

   ZwClose(hfile);
   return ntStatus;
}

//写文件
NTSTATUS ntWriteFile(WCHAR *szFileName)
{
   OBJECT_ATTRIBUTES  objectAttributes = { 0 };
   IO_STATUS_BLOCK        iostatus = { 0 };
   HANDLE                      hfile = NULL;
   UNICODE_STRING        uFile = { 0 };
   LARGE_INTEGER         number = { 0 };
   PUCHAR                  pBuffer = NULL;
   NTSTATUS                 ntStatus = STATUS_SUCCESS;


   RtlInitUnicodeString(&uFile, szFileName);

   InitializeObjectAttributes(&objectAttributes,
      &uFile,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL);

   //创建文件
   ntStatus = ZwCreateFile(&hfile,
      GENERIC_WRITE,
      &objectAttributes,
      &iostatus,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      FILE_SHARE_WRITE,
      FILE_OPEN_IF,
      FILE_SYNCHRONOUS_IO_NONALERT,
      NULL,
      0);
   if (!NT_SUCCESS(ntStatus))
   {
      return ntStatus;
   }

   pBuffer = (PUCHAR)ExAllocatePoolWithTag(PagedPool, 1024, 'ELIF');   //分配内存
   if (pBuffer == NULL)
   {
      ZwClose(hfile);
      return STATUS_INSUFFICIENT_RESOURCES;
   }

   RtlZeroMemory(pBuffer, 1024);

   RtlCopyMemory(pBuffer, L"Hello, world", wcslen(L"Hello, world") * sizeof(WCHAR));
   //写文件
   ntStatus = ZwWriteFile(hfile, NULL, NULL, NULL, &iostatus, pBuffer, 1024, NULL, NULL);


   ZwClose(hfile);

   ExFreePool(pBuffer);
   return ntStatus;
}

//读文件
NTSTATUS ntReadFile(WCHAR *szFile)
{
   OBJECT_ATTRIBUTES        objectAttributes = { 0 };
   IO_STATUS_BLOCK          iostatus = { 0 };
   HANDLE                    hfile = NULL;
   UNICODE_STRING              uFile = { 0 };
   FILE_STANDARD_INFORMATION  fsi = { 0 };
   PUCHAR                pBuffer = NULL;
   NTSTATUS               ntStatus = 0;

   RtlInitUnicodeString(&uFile, szFile);
   InitializeObjectAttributes(&objectAttributes,
      &uFile,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL);

   ntStatus = ZwCreateFile(&hfile,
      GENERIC_READ,
      &objectAttributes,
      &iostatus,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      FILE_OPEN,
      FILE_SYNCHRONOUS_IO_NONALERT,
      NULL,
      0);

   if (!NT_SUCCESS(ntStatus))
   {
      return ntStatus;
   }

   ntStatus = ZwQueryInformationFile(hfile,    //获取文件大小
      &iostatus,
      &fsi,          //要返回的结构体       
      sizeof(FILE_STANDARD_INFORMATION),
      FileStandardInformation);           

   if (!NT_SUCCESS(ntStatus))
   {
      ZwClose(hfile);
      return ntStatus;
   }

   pBuffer = (PUCHAR)ExAllocatePoolWithTag(PagedPool,   //大文件不适合
      (LONG)fsi.EndOfFile.QuadPart, 'ELIF');
   if (pBuffer == NULL)
   {
      ZwClose(hfile);
      return STATUS_INSUFFICIENT_RESOURCES;
   }

   ntStatus = ZwReadFile(
      hfile,
      NULL,
      NULL,
      NULL,
      &iostatus,
      pBuffer,
      (LONG)fsi.EndOfFile.QuadPart,
      NULL, NULL);

   ZwClose(hfile);
   ExFreePool(pBuffer);

   return ntStatus;
}

//文件拷贝
NTSTATUS ntCopyFile(const WCHAR * src, const WCHAR * dst)
{


   HANDLE             hSrcFile = NULL;
   HANDLE             hDstFile = NULL;
   UNICODE_STRING       uSrc = { 0 };
   UNICODE_STRING       uDst = { 0 };
   OBJECT_ATTRIBUTES     objSrcAttrib = { 0 };
   OBJECT_ATTRIBUTES     objDstAttrib = { 0 };
   NTSTATUS            status = 0;
   ULONG              uReadSize = 0;
   ULONG              uWriteSize = 0;
   ULONG              length = 0;
   PVOID              buffer = NULL;
   LARGE_INTEGER        offset = { 0 };
   IO_STATUS_BLOCK       io_status = { 0 };

   RtlInitUnicodeString(&uSrc, src);
   RtlInitUnicodeString(&uDst, dst);

   InitializeObjectAttributes(&objSrcAttrib,
      &uSrc,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL);
   InitializeObjectAttributes(&objDstAttrib,
      &uDst,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL);

   status = ZwCreateFile(
      &hSrcFile,
      FILE_READ_DATA | FILE_READ_ATTRIBUTES,
      &objSrcAttrib,
      &io_status,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      FILE_OPEN,
      FILE_SYNCHRONOUS_IO_NONALERT,
      NULL,
      0);
   if (!NT_SUCCESS(status))
   {
      return status;
   }

   status = ZwCreateFile(
      &hDstFile,
      GENERIC_WRITE,
      &objDstAttrib,
      &io_status,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      FILE_OPEN_IF,
      FILE_SYNCHRONOUS_IO_NONALERT,
      NULL,
      0);
   if (!NT_SUCCESS(status))
   {
      ZwClose(hSrcFile);
      return status;
   }

   buffer = ExAllocatePoolWithTag(PagedPool, 1024, 'ELIF');
   if (buffer == NULL)
   {
      ZwClose(hSrcFile);
      ZwClose(hDstFile);
      return STATUS_INSUFFICIENT_RESOURCES;
   }

   while (1)
   {
      status = ZwReadFile(
         hSrcFile, NULL, NULL, NULL,
         &io_status, buffer, PAGE_SIZE, &offset,
         NULL);
      if (!NT_SUCCESS(status))
      {
         if (status == STATUS_END_OF_FILE)
         {
            status = STATUS_SUCCESS;
         }
         break;
      }

      length = (ULONG)io_status.Information;

      status = ZwWriteFile(
         hDstFile, NULL, NULL, NULL,
         &io_status,
         buffer, length, &offset,
         NULL);
      if (!NT_SUCCESS(status))
         break;

      offset.QuadPart += length;

   }

   ExFreePool(buffer);

   ZwClose(hSrcFile);
   ZwClose(hDstFile);

   return status;
}

//文件移动
NTSTATUS ntMoveFile(const WCHAR * src, const WCHAR * dst)
{
   NTSTATUS      status = 0;

   status = ntCopyFile(src, dst);

   if (NT_SUCCESS(status))
   {
      status = ntDeleteFile2(src);
   }

   return status;
}

//文件删除
NTSTATUS ntDeleteFile1(const WCHAR * filename)    //xp及以上系统
{
   NTSTATUS            ntStatus = 0;
   OBJECT_ATTRIBUTES     objAttr = { 0 };
   UNICODE_STRING       uName = { 0 };

   RtlInitUnicodeString(&uName, filename);
   InitializeObjectAttributes(
      &objAttr,
      &uName,
      OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
      NULL,
      NULL
   );
   ntStatus = ZwDeleteFile(&objAttr);

   return ntStatus;

}    

NTSTATUS ntDeleteFile2(const WCHAR *fileName)    //所有版本
{
   OBJECT_ATTRIBUTES                  objAttributes = { 0 };
   IO_STATUS_BLOCK                        iosb = { 0 };
   HANDLE                             handle = NULL;
   FILE_DISPOSITION_INFORMATION       disInfo = { 0 };
   UNICODE_STRING                uFileName = { 0 };
   NTSTATUS                           status = 0;

   RtlInitUnicodeString(&uFileName, fileName);

   InitializeObjectAttributes(&objAttributes,
      &uFileName,
      OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
      NULL,
      NULL);

   status = ZwCreateFile(
      &handle,
      SYNCHRONIZE | FILE_WRITE_DATA | DELETE,
      &objAttributes,
      &iosb,
      NULL,
      FILE_ATTRIBUTE_NORMAL,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
      FILE_OPEN,
      FILE_SYNCHRONOUS_IO_NONALERT | FILE_DELETE_ON_CLOSE,
      NULL,
      0);
   if (!NT_SUCCESS(status))
   {
      if (status == STATUS_ACCESS_DENIED)      //权限不够
      {
         status = ZwCreateFile(
            &handle,
            SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,     //以低权限打开
            &objAttributes,
            &iosb,
            NULL,
            FILE_ATTRIBUTE_NORMAL,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_SYNCHRONOUS_IO_NONALERT,
            NULL,
            0);
         if (NT_SUCCESS(status))
         {
            FILE_BASIC_INFORMATION        basicInfo = { 0 };

            status = ZwQueryInformationFile(handle, &iosb,      //获取文件基本属性
               &basicInfo, sizeof(basicInfo), FileBasicInformation);
            if (!NT_SUCCESS(status))
            {
               DbgPrint("ZwQueryInformationFile(%wZ) failed(%x)\n", &uFileName, status);
            }

            basicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;  //改为低权限
            status = ZwSetInformationFile(handle, &iosb,        //设置权限
               &basicInfo, sizeof(basicInfo), FileBasicInformation);
            if (!NT_SUCCESS(status))
            {
               DbgPrint("ZwSetInformationFile(%wZ) failed(%x)\n", &uFileName, status);
            }

            ZwClose(handle);
            status = ZwCreateFile(
               &handle,
               SYNCHRONIZE | FILE_WRITE_DATA | DELETE,
               &objAttributes,
               &iosb,
               NULL,
               FILE_ATTRIBUTE_NORMAL,
               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
               FILE_OPEN,
               FILE_SYNCHRONOUS_IO_NONALERT | FILE_DELETE_ON_CLOSE,
               NULL,
               0);
         }
      }

      if (!NT_SUCCESS(status))
      {
         DbgPrint("ZwCreateFile(%wZ) failed(%x)\n", &uFileName, status);
         return status;
      }
   }

   disInfo.DeleteFile = TRUE;
   status = ZwSetInformationFile(handle, &iosb,               
      &disInfo, sizeof(disInfo), FileDispositionInformation); //删除文件
   if (!NT_SUCCESS(status))
   {
      DbgPrint("ZwSetInformationFile(%wZ) failed(%x)\n", &uFileName, status);
   }

   ZwClose(handle);
   return status;
}

注意:非空文件夹不能直接删除!!所以删除文件夹需要先用ZwQueryDirectoryFile遍历。


>