测试环境:win7 32
测试功能:通过构造irp 请求包,直接发给DeviceObject 调用对应DriverObject中的MajorFunction 来删除文件
参考:强制删除文件(1)——直接发IRP到文件系统_zz_strive_2012的专栏-CSDN博客
来源:从文件 MD5:dace344b6a923a756143a76c9cd12ebc 中扣出来的。
NTSTATUS DeleteCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
Irp->UserIosb->Status = Irp->IoStatus.Status;
Irp->UserIosb->Information = Irp->IoStatus.Information;
KeSetEvent(Irp->UserEvent, 0, FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS TryDeleteFile(PFILE_OBJECT FileObject, HANDLE FileHandle)
{
NTSTATUS status = STATUS_SUCCESS;
KEVENT Event = { 0 };
IO_STATUS_BLOCK IoStatusBlock = { 0 };
PDEVICE_OBJECT RelatedDeviceObject = NULL;
PIRP Irp = NULL;
PIO_STACK_LOCATION IoStackLocation = NULL;
CHAR FileDispositionInfo = 1;
PSECTION_OBJECT_POINTERS pSectionObjectPointer;
RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
if (RelatedDeviceObject == NULL)
{
DbgPrint("fails to get related DeviceObject");
return STATUS_UNSUCCESSFUL;
}
Irp = IoAllocateIrp(RelatedDeviceObject->StackSize, FALSE);
if (Irp)
{
KeInitializeEvent(&Event, SynchronizationEvent, 0);
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = &FileDispositionInfo;
Irp->UserEvent = &Event;
Irp->UserIosb = &IoStatusBlock;
Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IoStackLocation = IoGetNextIrpStackLocation(Irp);
if (IoStackLocation)
{
IoStackLocation->MajorFunction = IRP_MJ_SET_INFORMATION;
IoStackLocation->DeviceObject = RelatedDeviceObject;
IoStackLocation->FileObject = FileObject;
IoStackLocation->Parameters.SetFile.Length = 1;
IoStackLocation->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
IoStackLocation->Parameters.SetFile.FileObject = FileObject;
IoStackLocation->Parameters.SetFile.DeleteHandle = Handle;
//IoStackLocation->CompletionRoutine = (PIO_COMPLETION_ROUTINE)DeleteCompletionRoutine;
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)DeleteCompletionRoutine, NULL, TRUE, TRUE, TRUE);
IoStackLocation->Control = 0xe0;
//pSectionObjectPointer = FileObject->SectionObjectPointer;
//pSectionObjectPointer->ImageSectionObject = 0;
//pSectionObjectPointer->DataSectionObject = 0;
status = IoCallDriver(RelatedDeviceObject, Irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,
0,
KernelMode,
TRUE,
0);
}
status = Irp->UserIosb->Status;
}
else
{
DbgPrint("the next irp stack location is null!\n");
}
}
else
{
status = STATUS_NO_MEMORY;
}
return status;
}
NTSTATUS DeleteFileByIrp(WCHAR* FileName)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING DestinationString = { 0 };
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
IO_STATUS_BLOCK IoStatusBlock = { 0 };
HANDLE Handle = NULL;
PFILE_OBJECT FileObject = NULL;
RtlInitUnicodeString(&DestinationString, FileToDelete);
ObjectAttributes.ObjectName = &DestinationString;
ObjectAttributes.Length = 0x18;
ObjectAttributes.Attributes = 0x240;
ObjectAttributes.RootDirectory =
ObjectAttributes.SecurityDescriptor =
ObjectAttributes.SecurityQualityOfService = NULL;
status = ZwCreateFile(&Handle,
FILE_READ_DATA | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(status))
{
status = ObReferenceObjectByHandle(Handle,
DELETE,
*IoFileObjectType,
KernelMode,
&FileObject,
NULL);
if (NT_SUCCESS(status))
{
DbgPrint("<<<DeleteFileByIrp>>>get the file object.");
status = TryDeleteFile(FileObject, Handle);
}
else
{
DbgPrint("fails to reference file ,status:0x%x", status);
}
}
else
{
DbgPrint("open file fails,status:0x%x", status);
}
if (FileObject)
{
ObDereferenceObject(FileObject);
}
if (Handle)
{
ZwClose(Handle);
}
return status;
}