强制删除文件(1)——直接发IRP到文件系统
来源:互联网 发布:网络口碑营销失败案例 编辑:程序博客网 时间:2024/06/06 03:59
学习资料:http://www.antiprotect.com/forum_posts.asp?TID=95
上面这个连接中的DEMO是比较完整软件,这里我把其中发IRP强制删除文件的部分抽出来了,
学习了下,顺便加点注释。这个程序比较简单,主要练习了两个点:
(1)模拟发送IRP
(2)使用内核事件对象同步IRP的执行
强制删除文件的思路很简单,把SECTION_OBJECT_POINTERS结构的DataSectionObject和ImageSectionObject两个域清空即可删除正在运行的文件。如果不清空就不能删除运行中的文件。正在运行的文件的这两个域值不为0而文件系统正在根据这两个域决定该文件是否可以删除。如果文件系统检测这两个值为0,就理解为文件没有被使用,可以删除。接下去,就是直接发IRP。
测试时,在C盘目录下放一个test.exe并执行,然后加载驱动即可。
强制删除文件功能在ForceDeleteFile中实现,DriverEntry中只需要简单调用即可。具体实现如下
NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){// 其他初始化代码// ……DbgPrint ( "Delete File %s", ForceDeleteFile(L"//DosDevices//C://test.exe") ? "Success!" : "Failed!" ) ;return STATUS_SUCCESS;}NTSTATUS FD_SetFileCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ){Irp->UserIosb->Status= Irp->IoStatus.Status;Irp->UserIosb->Information= Irp->IoStatus.Information;KeSetEvent ( Irp->UserEvent, IO_NO_INCREMENT, FALSE ) ;IoFreeIrp(Irp);return STATUS_MORE_PROCESSING_REQUIRED;}HANDLEFD_OpenFile ( WCHAR szFileName[] ){NTSTATUSntStatus ;UNICODE_STRINGFileName ;OBJECT_ATTRIBUTESobjectAttributes;HANDLEhFile ;IO_STATUS_BLOCKioStatus ;// 确保IRQL在PASSIVE_LEVEL上if (KeGetCurrentIrql() > PASSIVE_LEVEL)return NULL;// 初始化文件名RtlInitUnicodeString ( &FileName, szFileName ) ;DbgPrint ( "%ws", FileName.Buffer ) ;//初始化对象属性InitializeObjectAttributes ( &objectAttributes, &FileName,OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE, NULL, NULL ) ;// 打开文件ntStatus = IoCreateFile ( &hFile, FILE_READ_ATTRIBUTES, &objectAttributes, &ioStatus, /0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_DELETE,FILE_OPEN,0,NULL,0,CreateFileTypeNone,NULL,IO_NO_PARAMETER_CHECKING);if ( !NT_SUCCESS(ntStatus) )return NULL ;return hFile ;}BOOLEANFD_StripFileAttributes ( HANDLE FileHandle ){NTSTATUSntStatus = STATUS_SUCCESS;PFILE_OBJECTfileObject;PDEVICE_OBJECTDeviceObject;PIRPIrp;KEVENTSycEvent;FILE_BASIC_INFORMATIONFileInformation;IO_STATUS_BLOCKioStatus;PIO_STACK_LOCATIONirpSp;// 获取文件对象ntStatus = ObReferenceObjectByHandle ( FileHandle, DELETE,*IoFileObjectType, KernelMode, (PVOID*)&fileObject, NULL) ;if ( !NT_SUCCESS(ntStatus) ){DbgPrint ( "ObReferenceObjectByHandle error!" ) ;return FALSE;}// 获取与指定文件对象相关联的设备对象DeviceObject = IoGetRelatedDeviceObject ( fileObject ) ;// 创建IRPIrp = IoAllocateIrp ( DeviceObject->StackSize, TRUE ) ;if ( Irp == NULL ) {ObDereferenceObject(fileObject);DbgPrint ( "FD_StripFileAttributes IoAllocateIrp error" ) ;return FALSE;}// 初始化同步事件对象KeInitializeEvent ( &SycEvent, SynchronizationEvent, FALSE ) ;memset ( &FileInformation, 0, 0x28 ) ;FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;// 初始化IRPIrp->AssociatedIrp.SystemBuffer= &FileInformation;Irp->UserEvent= &SycEvent;Irp->UserIosb= &ioStatus;Irp->Tail.Overlay.OriginalFileObject= fileObject;Irp->Tail.Overlay.Thread= (PETHREAD)KeGetCurrentThread();Irp->RequestorMode = KernelMode;// 设置IRP堆栈信息irpSp = IoGetNextIrpStackLocation(Irp);irpSp->MajorFunction= IRP_MJ_SET_INFORMATION;irpSp->DeviceObject= DeviceObject;irpSp->FileObject= fileObject;irpSp->Parameters.SetFile.Length= sizeof(FILE_BASIC_INFORMATION) ;irpSp->Parameters.SetFile.FileInformationClass= FileBasicInformation;irpSp->Parameters.SetFile.FileObject= fileObject ;// 设置完成例程IoSetCompletionRoutine ( Irp, FD_SetFileCompletion ,NULL, TRUE, TRUE, TRUE ) ;// 派发IRPIoCallDriver(DeviceObject, Irp);// 等待IRP的完成KeWaitForSingleObject ( &SycEvent, Executive, KernelMode, TRUE, NULL ) ;// 递减引用计数ObDereferenceObject(fileObject);return TRUE ;}BOOLEAN FD_DeleteFile ( HANDLE FileHandle ){NTSTATUS ntStatus = STATUS_SUCCESS;PFILE_OBJECT fileObject;PDEVICE_OBJECT DeviceObject;PIRP Irp;KEVENT SycEvent ;FILE_DISPOSITION_INFORMATION FileInformation;IO_STATUS_BLOCKioStatus;PIO_STACK_LOCATIONirpSp;PSECTION_OBJECT_POINTERSpSectionObjectPointer; // 获取文件对象ntStatus = ObReferenceObjectByHandle ( FileHandle, DELETE,*IoFileObjectType, KernelMode, (PVOID*)&fileObject, NULL) ;if ( !NT_SUCCESS(ntStatus) ){DbgPrint ( "ObReferenceObjectByHandle error!" ) ;return FALSE;}// 获取与指定文件对象相关联的设备对象DeviceObject = IoGetRelatedDeviceObject ( fileObject ) ;// 创建IRPIrp = IoAllocateIrp ( DeviceObject->StackSize, TRUE ) ;if (Irp == NULL){ObDereferenceObject ( fileObject ) ;DbgPrint ( "FD_DeleteFile IoAllocateIrp error" ) ;return FALSE;}// 初始化同步事件对象KeInitializeEvent ( &SycEvent, SynchronizationEvent, FALSE ) ;FileInformation.DeleteFile = TRUE;// 初始化IRPIrp->AssociatedIrp.SystemBuffer= &FileInformation;Irp->UserEvent= &SycEvent;Irp->UserIosb= &ioStatus;Irp->Tail.Overlay.OriginalFileObject= fileObject;Irp->Tail.Overlay.Thread= (PETHREAD)KeGetCurrentThread();Irp->RequestorMode= KernelMode;// 设置IRP堆栈irpSp = IoGetNextIrpStackLocation(Irp);irpSp->MajorFunction= IRP_MJ_SET_INFORMATION;irpSp->DeviceObject= DeviceObject;irpSp->FileObject= fileObject;irpSp->Parameters.SetFile.Length= sizeof(FILE_DISPOSITION_INFORMATION);irpSp->Parameters.SetFile.FileInformationClass= FileDispositionInformation;irpSp->Parameters.SetFile.FileObject= fileObject;// 设置完成例程IoSetCompletionRoutine ( Irp, FD_SetFileCompletion, NULL, TRUE, TRUE, TRUE ) ;// 如果没有这3行,就无法删除正在运行的文件pSectionObjectPointer = fileObject->SectionObjectPointer;pSectionObjectPointer->ImageSectionObject = 0;pSectionObjectPointer->DataSectionObject = 0;// 派发IRPIoCallDriver ( DeviceObject, Irp ) ;// 等待IRP完成KeWaitForSingleObject ( &SycEvent, Executive, KernelMode, TRUE, NULL);// 递减引用计数ObDereferenceObject ( fileObject ) ;return TRUE ;}BOOLEANForceDeleteFile ( WCHAR szFileName[] ){HANDLEhFile = NULL ;BOOLEANstatus = FALSE ;__try {// 打开文件if ( ( hFile = FD_OpenFile( szFileName ) ) == NULL ){DbgPrint ( "FD_OpenFile error!" ) ;return FALSE ;}// //去掉只读属性,才能删除只读文件if ( FD_StripFileAttributes(hFile) == FALSE ){ZwClose ( hFile ) ;DbgPrint ( "FD_StripFileAttributes error!" ) ;return FALSE ;}// 删除文件status = FD_DeleteFile(hFile) ;ZwClose ( hFile ) ;return status ;} __except ( 1 ) {DbgPrint ( "execption!" ) ;}return FALSE ;}
- 强制删除文件——直接发IRP到文件系统
- 强制删除文件(1)——直接发IRP到文件系统
- 强制删除文件(1)——直接发IRP到文件系统
- 强制删除文件(1)——直接发IRP到文件系统
- 把文件直接删除到回收站
- 强制删除文件 强制删除文件夹
- 强制删除文件
- 强制删除文件
- inf强制删除文件
- 【半原创】Irp占坑保护文件不被删除
- QT cmd强制删除文件
- 如何直接强制客户端刷新.js文件
- git 强制放弃本地修改(新增、删除文件)
- 无发删除的文件
- windows驱动编程学习笔记——(三)IRP
- IRP操作文件
- IRP操作文件
- 如何强制删除正在使用的文件
- 深入浅出之正则表达式(一)
- 深入浅出之正则表达式(二)
- ABAP 數據筆記 6-11-08
- 一个批量下载图片的c#类(downmoon)
- 有关SQL 截取和替换字符串
- 强制删除文件(1)——直接发IRP到文件系统
- 无法解决 equal to 操作的排序规则冲突
- 等待
- 常用正则表达式
- 深入分析MFC文档视图结构(项目实践)
- 无组件图片与文本同步存入数据库的最简单的办法
- 世界上最好的中文名字是什么
- 试用IE 8.0的感受
- 揭开正则表达式的神秘面纱