强制删除文件(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 ;}
原创粉丝点击