Question

FLASHCODER on Fri, 08 Jun 2018 12:08:42


In this question was suggested send a IRP directly to ntfs.sys driver to have success to delete a file protected by filters/minifilters or any hook on file system.

Then today tested this following code but i'm able to delete only injected dll files, this was the maximum where i had sucess.

My doubt is how make a "reference" to ntfs.sys before send this IRP? until now not was possible delete the file that i wish.

NTSTATUS
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;
}

StripFileAttributes(HANDLE FileHandle) 
{

    NTSTATUS          ntStatus = STATUS_SUCCESS;
    PFILE_OBJECT      fileObject;
    PDEVICE_OBJECT    DeviceObject;
    PIRP              Irp;
    KEVENT            event1;
    FILE_BASIC_INFORMATION    FileInformation;
    IO_STATUS_BLOCK ioStatus;
    PIO_STACK_LOCATION irpSp;

    ntStatus = ObReferenceObjectByHandle(FileHandle,
        DELETE,
        *IoFileObjectType,
        KernelMode,
        (PVOID*)&fileObject,
        NULL);

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

    DeviceObject = IoGetRelatedDeviceObject(fileObject);
    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);

    if (Irp == NULL)
    {
        ObDereferenceObject(fileObject);
        return FALSE;
    }

    KeInitializeEvent(&event1, SynchronizationEvent, FALSE);

    memset(&FileInformation,0,0x28);

    FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
    Irp->AssociatedIrp.SystemBuffer = &FileInformation;
    Irp->UserEvent = &event1;
    Irp->UserIosb = &ioStatus;
    Irp->Tail.Overlay.OriginalFileObject = fileObject;
    Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
    Irp->RequestorMode = KernelMode;

    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,
        SetFileCompletion,
        &event1,
        TRUE,
        TRUE,
        TRUE);

    IoCallDriver(DeviceObject,Irp);
        KeWaitForSingleObject(&event1,Executive,KernelMode,TRUE,NULL);

    ObDereferenceObject(fileObject);

      return ntStatus;
}

NTSTATUS IrpDeleteFile(HANDLE FileHandle)
{
    NTSTATUS status;    
    PFILE_OBJECT      fileObject;
    PDEVICE_OBJECT DeviceObject;
    KEVENT            event1;
    PIRP Irp;
    IO_STATUS_BLOCK ioStatus;
    FILE_DISPOSITION_INFORMATION    FileInformation;
    PIO_STACK_LOCATION irpSp;
    PSECTION_OBJECT_POINTERS pSectionObjectPointer;
    DbgPrint(("start to IrpDeleteFile\n"));

    StripFileAttributes( FileHandle);

    status=ObReferenceObjectByHandle(FileHandle,DELETE,*IoFileObjectType,KernelMode,(PVOID*)&fileObject,NULL);

    if (!NT_SUCCESS(status))
    {
        return STATUS_UNSUCCESSFUL;
     }

    DeviceObject=IoGetRelatedDeviceObject(fileObject);

    Irp=IoAllocateIrp(DeviceObject->StackSize,TRUE);
    if (Irp==NULL)
    {
        ObDereferenceObject(fileObject);
        return STATUS_UNSUCCESSFUL;
    }
    KeInitializeEvent(&event1,SynchronizationEvent,FALSE);

    FileInformation.DeleteFile=TRUE;
    Irp->AssociatedIrp.SystemBuffer=&FileInformation;
    Irp->UserEvent=&event1;
    Irp->UserIosb=&ioStatus;
    Irp->Tail.Overlay.OriginalFileObject=fileObject;
    Irp->Tail.Overlay.Thread=(PETHREAD)KeGetCurrentThread();
    Irp->RequestorMode=KernelMode;

    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,SetFileCompletion,&event1,TRUE,TRUE,TRUE);

    pSectionObjectPointer = fileObject->SectionObjectPointer;
    pSectionObjectPointer->ImageSectionObject = 0;
    pSectionObjectPointer->DataSectionObject = 0;

    IoCallDriver(DeviceObject,Irp);

    KeWaitForSingleObject(&event1,Executive,KernelMode,TRUE,NULL);
    ObDereferenceObject(fileObject);

    return STATUS_SUCCESS;

}
HANDLE IoOpenFile(OBJECT_ATTRIBUTES objattributes)
{   
    NTSTATUS status;
    HANDLE FileHandle;
    IO_STATUS_BLOCK       ioStatus;

    if (KeGetCurrentIrql() > PASSIVE_LEVEL)
    {
        DbgPrint(("it is not the PASSIVE_LEVEL \n"));
        return 0;
    }

    status=IoCreateFile(&FileHandle,FILE_READ_ATTRIBUTES,&objattributes,&ioStatus,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_DELETE,FILE_OPEN,0,NULL,0,CreateFileTypeNone,NULL,IO_NO_PARAMETER_CHECKING);
    if (!NT_SUCCESS(status))
    {
        status=ZwCreateFile(&FileHandle,FILE_READ_ATTRIBUTES,&objattributes,&ioStatus,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_DELETE,FILE_OPEN,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
        if (!NT_SUCCESS(status))

        {

            return 0;
        }

    }
    return FileHandle;

}

NTSTATUS BuildIrpToDelete(OBJECT_ATTRIBUTES  objattributes)
{
    NTSTATUS status;
    HANDLE FileHandle;

    FileHandle=IoOpenFile(objattributes);
    if (FileHandle!=NULL)
    {
        status=IrpDeleteFile(FileHandle);
        ZwClose(FileHandle);

    }
    else
    {
        DbgPrint(("IoOpenFile failed\n"));
    }
    return status;
}

// DriverEntry



    OBJECT_ATTRIBUTES objattributes;
    UNICODE_STRING UniFileName,UniString,fullUniName;

    RtlInitUnicodeString(&UniFileName,L"C:\\MyDll.dll");

    RtlInitUnicodeString(&UniString,L"\\??\\");
    fullUniName.Buffer=(PWCHAR)ExAllocatePool(PagedPool,1024);  
    fullUniName.MaximumLength=1024;   

    RtlCopyUnicodeString(&fullUniName,&UniString);
    status=RtlAppendUnicodeStringToString(&fullUniName,&UniFileName);

    if (status==STATUS_SUCCESS)
    {

        InitializeObjectAttributes(&objattributes,&fullUniName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE ,NULL,NULL);
        status=BuildIrpToDelete(objattributes);
        if (!NT_SUCCESS(status))
        {
            status=STATUS_UNSUCCESSFUL;

        }
        else
        {

        }
    }
    else
    {
        DbgPrint(("failed\n"));
    }
    if (fullUniName.Buffer)
    {
        ExFreePool(fullUniName.Buffer);
    }

All examples avaiable on web (eg: see here) points pratically to same code design, but none works to my goal.



Sponsored