找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 3147|回复: 9

如何強制刪除像PCHunter這樣的文件夾?

[复制链接]

5

主题

156

回帖

0

精华

铜牌会员

积分
119
发表于 2020-6-26 13:48:56 | 显示全部楼层 |阅读模式
本帖最后由 Krueger 于 2020-6-26 14:25 编辑

好吧,我試圖強制刪除由minifilter鎖定的文件,並且這些文件具有使文件名無效的快捷方式



IoCreateFile這樣的函數將因NTSTATUS代碼0xC000003A(STATUS_OBJECT_PATH_NOT_FOUND)或0xC0000034(STATUS_OBJECT_NAME_INVALID)而失敗。 今天,我在此文件上測試了PCHunter的“強制刪除”功能,但是並未刪除該文件,當在包含該文件的文件夾上使用“強制刪除”功能時,所有內容均被刪除。

有關如何執行此操作的任何想法? 以下是我用來強制刪除minifilter鎖定的普通文件的代碼。

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

  3. HANDLE
  4. SkillIoOpenFile(
  5.         IN PCWSTR FileName,
  6.         IN ACCESS_MASK DesiredAccess,
  7.         IN ULONG ShareAccess)
  8. {
  9.         NTSTATUS ntStatus;
  10.         UNICODE_STRING uniFileName;
  11.         OBJECT_ATTRIBUTES objectAttributes;
  12.         HANDLE ntFileHandle;
  13.         IO_STATUS_BLOCK ioStatus;
  14.         if (KeGetCurrentIrql() > PASSIVE_LEVEL) {
  15.                 DbgPrint("KeGetCurrentIrql() > PASSIVE_LEVEL\n");
  16.                 return 0;
  17.         }

  18.         RtlInitUnicodeString(&uniFileName, FileName);
  19.         InitializeObjectAttributes(&objectAttributes, &uniFileName,
  20.                 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

  21.         ntStatus = IoCreateFile(&ntFileHandle,
  22.                 DesiredAccess,
  23.                 &objectAttributes,
  24.                 &ioStatus,
  25.                 0,
  26.                 FILE_ATTRIBUTE_NORMAL,
  27.                 ShareAccess,
  28.                 FILE_OPEN,
  29.                 0,
  30.                 NULL,
  31.                 0,
  32.                 0,
  33.                 NULL,
  34.                 IO_NO_PARAMETER_CHECKING);

  35.         if (!NT_SUCCESS(ntStatus)) {
  36.                 DbgPrint("IoCreateFile() error - 0x%X \n", ntStatus);
  37.                 return 0;
  38.         }

  39.         return ntFileHandle;
  40. }

  41. NTSTATUS
  42. SkillSetFileCompletion(
  43.         IN PDEVICE_OBJECT DeviceObject,
  44.         IN PIRP Irp,
  45.         IN PVOID Context)
  46. {
  47.         Irp->UserIosb->Status = Irp->IoStatus.Status;
  48.         Irp->UserIosb->Information = Irp->IoStatus.Information;

  49.         KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);

  50.         IoFreeIrp(Irp);

  51.         return STATUS_MORE_PROCESSING_REQUIRED;
  52. }

  53. BOOLEAN
  54. ForceFileAttributes(
  55.         IN HANDLE FileHandle)
  56. {
  57.         NTSTATUS ntStatus = STATUS_SUCCESS;
  58.         PFILE_OBJECT fileObject;
  59.         PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
  60.         PIRP Irp;
  61.         KEVENT event1;
  62.         FILE_BASIC_INFORMATION FileInformation;
  63.         IO_STATUS_BLOCK ioStatus;
  64.         PIO_STACK_LOCATION irpSp;

  65.         ntStatus = ObReferenceObjectByHandle(FileHandle,
  66.                 DELETE,
  67.                 *IoFileObjectType,
  68.                 KernelMode,
  69.                 &fileObject,
  70.                 NULL);

  71.         if (!NT_SUCCESS(ntStatus))
  72.                 return FALSE;

  73.         DeviceObject = IoGetRelatedDeviceObject(fileObject);

  74.         BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);

  75.         Irp = IoAllocateIrp(BaseDeviceObject->StackSize, TRUE);

  76.         if (Irp == NULL) {
  77.                 ObDereferenceObject(fileObject);
  78.                 return FALSE;
  79.         }

  80.         KeInitializeEvent(&event1, SynchronizationEvent, FALSE);

  81.         memset(&FileInformation, 0, 0x28);

  82.         FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
  83.         Irp->AssociatedIrp.SystemBuffer = &FileInformation;
  84.         Irp->UserEvent = &event1;
  85.         Irp->UserIosb = &ioStatus;
  86.         Irp->Tail.Overlay.OriginalFileObject = fileObject;
  87.         Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
  88.         Irp->RequestorMode = KernelMode;

  89.         irpSp = IoGetNextIrpStackLocation(Irp);
  90.         irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
  91.         irpSp->DeviceObject = BaseDeviceObject;
  92.         irpSp->FileObject = fileObject;
  93.         irpSp->Parameters.SetFile.Length = sizeof(FILE_BASIC_INFORMATION);
  94.         irpSp->Parameters.SetFile.FileInformationClass = FileBasicInformation;
  95.         irpSp->Parameters.SetFile.FileObject = fileObject;

  96.         IoSetCompletionRoutine(
  97.                 Irp,
  98.                 SkillSetFileCompletion,
  99.                 &event1,
  100.                 TRUE,
  101.                 TRUE,
  102.                 TRUE);

  103.         IoCallDriver(BaseDeviceObject, Irp);

  104.         KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);

  105.         ObDereferenceObject(fileObject);

  106.         return TRUE;
  107. }

  108. BOOLEAN
  109. ForceDeleteFile(
  110.         IN HANDLE FileHandle,
  111.         IN BOOLEAN IsDirectory)
  112. {
  113.         NTSTATUS ntStatus = STATUS_SUCCESS;
  114.         PFILE_OBJECT fileObject;
  115.         PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
  116.         PIRP Irp;
  117.         KEVENT event1;
  118.         FILE_DISPOSITION_INFORMATION FileInformation;
  119.         IO_STATUS_BLOCK ioStatus;
  120.         PIO_STACK_LOCATION irpSp;
  121.         PSECTION_OBJECT_POINTERS pSectionObjectPointer;

  122.         if (ForceFileAttributes(FileHandle))
  123.                 /*DbgPrint("ForceFileAttributes OK - %08X\n", FileHandle)*/;

  124.         ntStatus = ObReferenceObjectByHandle(FileHandle,
  125.                 DELETE,
  126.                 *IoFileObjectType,
  127.                 KernelMode,
  128.                 &fileObject,
  129.                 NULL);

  130.         if (!NT_SUCCESS(ntStatus))
  131.                 return FALSE;

  132.         DeviceObject = IoGetRelatedDeviceObject(fileObject);

  133.         BaseDeviceObject = IoGetDeviceAttachmentBaseRef(DeviceObject);

  134.         Irp = IoAllocateIrp(BaseDeviceObject->StackSize, TRUE);

  135.         if (Irp == NULL) {
  136.                 ObDereferenceObject(fileObject);
  137.                 return FALSE;
  138.         }

  139.         KeInitializeEvent(&event1, SynchronizationEvent, FALSE);

  140.         FileInformation.DeleteFile = TRUE;

  141.         Irp->AssociatedIrp.SystemBuffer = &FileInformation;
  142.         Irp->UserEvent = &event1;
  143.         Irp->UserIosb = &ioStatus;
  144.         Irp->Tail.Overlay.OriginalFileObject = fileObject;
  145.         Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
  146.         Irp->RequestorMode = KernelMode;

  147.         irpSp = IoGetNextIrpStackLocation(Irp);
  148.         irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
  149.         irpSp->DeviceObject = BaseDeviceObject;
  150.         irpSp->FileObject = fileObject;
  151.         irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
  152.         irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
  153.         irpSp->Parameters.SetFile.FileObject = fileObject;

  154.         IoSetCompletionRoutine(
  155.                 Irp,
  156.                 SkillSetFileCompletion,
  157.                 &event1,
  158.                 TRUE,
  159.                 TRUE,
  160.                 TRUE);

  161.         if (!IsDirectory) {
  162.                 pSectionObjectPointer = fileObject->SectionObjectPointer;
  163.                 pSectionObjectPointer->ImageSectionObject = 0;
  164.                 pSectionObjectPointer->DataSectionObject = 0;

  165.                 CONST BOOLEAN ImageSectionFlushed = MmFlushImageSection(pSectionObjectPointer, MmFlushForDelete);
  166.                 if (ImageSectionFlushed)
  167.                         /*DbgPrint("ImageSectionFlushed() OK")*/;
  168.         }

  169.         IoCallDriver(BaseDeviceObject, Irp);

  170.         KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);

  171.         ObDereferenceObject(fileObject);

  172.         return TRUE;
  173. }

  174. //---------------------------------------------------------------------------------------------------

  175. HANDLE hFileHandle = SkillIoOpenFile(L"\\??\\C:\\Program Files\\Some Software\\Subfolder\\file.dll",
  176.                 FILE_READ_ATTRIBUTES,
  177.                 FILE_SHARE_DELETE);
  178.                
  179. if (hFileHandle != 0) {
  180.        
  181.         DbgPrint("hFileHandle: %08X\n", hFileHandle);
  182.         if (ForceDeleteFile(hFileHandle, FALSE))
  183.                 DbgPrint("<%08X> - DELETE OK\n", hFileHandle);
  184.         ZwClose(hFileHandle);
  185. }
复制代码

856

主题

2630

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36108
发表于 2020-6-26 14:45:16 | 显示全部楼层
如果它真是用MiniFilter来保护文件的话,你试试把BaseDeviceObject设置为fileObject->Vpb->DeviceObject。

5

主题

156

回帖

0

精华

铜牌会员

积分
119
 楼主| 发表于 2020-7-2 08:43:24 | 显示全部楼层
本帖最后由 Krueger 于 2020-7-2 08:47 编辑
Tesla.Angela 发表于 2020-6-26 14:45
如果它真是用MiniFilter来保护文件的话,你试试把BaseDeviceObject设置为fileObject->Vpb->DeviceObject。 ...


fileObject-> Vpb-> DeviceObjectIoGetBaseFileSystemDeviceObject相同(已棄用並由IoGetDeviceAttachmentBaseRef代替)。 但是問題是PCHunter如何才能“查找” IoCreateFile函數無法執行的文件? 有一些秘密嗎? 例如:上面的屏幕截圖是Avast防病毒目錄中的這些“無效”文件,只能通過PcHunter的“強制刪除”功能(在文件夾中,而不在文件中)將其刪除。

謝謝

77

主题

192

回帖

9

精华

贵宾会员

积分
15602
发表于 2020-7-2 11:57:15 | 显示全部楼层
搞到盘符的DeviceObject,可以用ZwOpenFile打开盘符,然后以句柄引用文件对象,进而取到Vpb中的DeviceObject。这个操作可以被MiniFilter拦截,但一般不会被过滤掉。
然后IoCreateFileSpecifyDeviceObjectHint打开文件,最后一个参数填盘符的DeviceObject。因为是操作最底层设备对象,直接绕过了MiniFilter过滤驱动。
至于删文件,可以在打开文件时指定FILE_DELETE_ON_CLOSE然后关闭句柄,也可以ZwSetInformationFile。注意你打开文件时指定了栈底设备对象,使得ZwSetInformationFile函数不会被过滤驱动拦截。
最后别忘了解引用对象,关闭句柄。
这假定了只有MiniFilter作为干扰项。

856

主题

2630

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36108
发表于 2020-7-2 16:21:48 | 显示全部楼层
Krueger 发表于 2020-7-2 08:43
fileObject-> Vpb-> DeviceObject與IoGetBaseFileSystemDeviceObject相同(已棄用並由IoGetDeviceAttachm ...


我不知道Avast是不是只使用了MiniFilter来做文件保护,我也不知道PcHunter是怎么实现文件删除的。
但是我知道,只要你把IRP发送到了NTFS的“真”设备上(不经过附加设备的处理),MiniFilter是肯定拦不住的。

5

主题

156

回帖

0

精华

铜牌会员

积分
119
 楼主| 发表于 2020-7-3 04:02:36 | 显示全部楼层
tangptr@126.com 发表于 2020-7-2 11:57
搞到盘符的DeviceObject,可以用ZwOpenFile打开盘符,然后以句柄引用文件对象,进而取到Vpb中的DeviceObjec ...

"打开盘符"

什麼意思? C:\?

還是C:\ Program Files \ Software Folder \ file文件夾?

77

主题

192

回帖

9

精华

贵宾会员

积分
15602
发表于 2020-7-3 15:34:41 | 显示全部楼层
Krueger 发表于 2020-7-3 04:02
"打开盘符"

什麼意思? C:\?

打开C:\就可以了。你想想有谁会去过滤掉打开盘符根目录的行为呢。

5

主题

156

回帖

0

精华

铜牌会员

积分
119
 楼主| 发表于 2020-7-18 11:38:23 | 显示全部楼层
本帖最后由 Krueger 于 2020-7-18 11:42 编辑

好消息!,我發現這些文件具有.symlink擴展名並指向.dll文件。 現在,我將針對它們測試上面的代碼(使用.symlink而不是.dll擴展名)並在此處報告結果。

以上所有建議均未奏效,但學習愉快,謝謝。

5

主题

156

回帖

0

精华

铜牌会员

积分
119
 楼主| 发表于 2020-7-19 11:25:22 | 显示全部楼层
解決了在IoCreateFile()上添加FILE_OPEN_REPARSE_POINT標誌之後。

856

主题

2630

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36108
发表于 2020-7-31 06:43:54 | 显示全部楼层
Krueger 发表于 2020-7-19 11:25
解決了在IoCreateFile()上添加FILE_OPEN_REPARSE_POINT標誌之後。

原来你说的“快捷方式”是符号链接啊……
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

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