zoukankan      html  css  js  c++  java
  • x64内核强删文件.

    x64内核中强删文件的实现

    一丶简介

    说道删除文件.有各种各样的方法. 有ring3 也有ring0. 而且也有许多对抗的方法. 如ring3想删除一个文件.被占用你就无法删除.此时可以通过解除句柄进行删除 ring0中想删除一个文件.有常规方法也有非常规方法.常规方法就是 设置文件属性为删除.然后进行设置. 还有就是直接调用ZwDeleteFile 进行删除. 暴力删除就是这里所讲的 IRP删除.给底层发送IRP即可进行删除文件.

    1.步骤

    步骤很简单.基本上说完就可以自己写代码做出

    • 1.打开文件.获取文件句柄 (IoCreateFile)
    • 2.根据文件句柄,获取文件对象.(有了句柄都应该第一时间想到获取它的对象) (ObReferenceObjectByHandle)
    • 3.获取文件对象的设备对象指针.这个发送IRP的时候需要使用(IoGetRelatedDeviceObject)
    • 4.申请IRP(IoAllocateIrp)
    • 5.初始化你申请的IRP
    • 6.获取IRP的下层堆栈,并且初始化信息.(IoGetNextIrpStackLocation)
    • 7.设置回调.系统完成IRP之后会调用你这个回调.所以你需要设置事件同步跟你自己同步,才知道IRP已经发送完了.(IoSetCompletionRoutine)
    • 8.获取文件对象的域指针.并且设置域指针的两个成员为0.系统以他来判断这个程序是否可以删除.如果不为0.那么则无法删除运行中的文件.
    pSectionObjectPointer->ImageSectionObject = 0;
    pSectionObjectPointer->DataSectionObject = 0;
    
    • 9.发送IRP(IoCallDriver)
    • 10.根据 事件 来等待是否IRP完成(KeWaitForSingleObject)
    • 11.做完收工.(ZwClose)

    2.Nt驱动代码

    
    #include "Driver.h"
    
    
    //删除文件函数的入口
    NTSTATUS RetOpenFileHandle(UNICODE_STRING uDelFileName, PHANDLE pFileHandle)
    {
        
        NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
        IO_STATUS_BLOCK iostu;
        HANDLE hFileHandle = 0;
        if (pFileHandle == NULL)
            return STATUS_UNSUCCESSFUL;
        if (KeGetCurrentIrql() > PASSIVE_LEVEL)
            return 0;
    
        if (uDelFileName.Length < 0 || uDelFileName.MaximumLength < 0)
        {
            return 0;
        }
    
    
        OBJECT_ATTRIBUTES ObjAttribute;
        ObjAttribute.ObjectName = &uDelFileName;
        ObjAttribute.SecurityDescriptor = NULL;
        ObjAttribute.SecurityQualityOfService = NULL;
        ObjAttribute.Attributes = OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE;
        ObjAttribute.Length = sizeof(OBJECT_ATTRIBUTES);
    
      /*  InitializeObjectAttributes(
            &ObjAttribute,
            &uDelFileName, 
            OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, 
            NULL, NULL);*/
    
        ntStatus = IoCreateFile(&hFileHandle,
            FILE_READ_ATTRIBUTES,
            &ObjAttribute, 
            &iostu,
            0, 
            FILE_ATTRIBUTE_NORMAL,
            FILE_SHARE_DELETE, 
            FILE_OPEN,
            0, 
            NULL, 
            0, 
            CreateFileTypeNone,
            NULL,
            IO_NO_PARAMETER_CHECKING);
    
        *pFileHandle = hFileHandle;
        return ntStatus;
    }
    
    //去掉文件属性
    
    
    //CallBack回调
    NTSTATUS
    CallBackIrpCompleteionProc(
        PDEVICE_OBJECT DeviceObject,
        PIRP Irp,
         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;
    }
    NTSTATUS PassFileattribute(PFILE_OBJECT pFileObj)
    {
        /*
        1.申请IRP,初始化IRP
        2.初始化同步事件,以及设置回调.
        3.设置文件属性为默认
        4.发送IRP
        */
        PDEVICE_OBJECT pNextDeviceObj = NULL;
        PIRP pAllocIrp = NULL;
        KEVENT IrpSynEvent = {0}; //Irp同步需要的事件同步
        FILE_BASIC_INFORMATION fileBasciInfo = { 0 };
        IO_STATUS_BLOCK iostu;
        PIO_STACK_LOCATION IrpStack;
        //通过文件对象.获取其设备对象指针
        pNextDeviceObj = IoGetRelatedDeviceObject(pFileObj);  
        if (pNextDeviceObj == NULL)
            return STATUS_UNSUCCESSFUL;
    
        //通过设备对象指针.确定申请的IRP的大小,注意在完成设置里面进行释放.
        pAllocIrp = IoAllocateIrp(pNextDeviceObj->StackSize,TRUE);
        if (pAllocIrp == NULL)
            return STATUS_UNSUCCESSFUL;
    
        //初始化Irp
    
        //设置为自动,设置为无信号.
        KeInitializeEvent(&IrpSynEvent, SynchronizationEvent, FALSE); 
    
        fileBasciInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
        pAllocIrp->AssociatedIrp.SystemBuffer = &fileBasciInfo;
        pAllocIrp->UserIosb = &iostu;
        pAllocIrp->UserEvent = &IrpSynEvent;
        pAllocIrp->Tail.Overlay.OriginalFileObject = pFileObj;
        pAllocIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
    
        //获取下层堆栈.进行设置.
    
        //IrpStack  = 
        IrpStack = IoGetNextIrpStackLocation(pAllocIrp);
        IrpStack->MajorFunction = IRP_MJ_SET_INFORMATION; 
        IrpStack->DeviceObject = pNextDeviceObj;
        IrpStack->FileObject = pFileObj;
        IrpStack->Parameters.SetFile.Length = sizeof(FILE_BASIC_INFORMATION);
        IrpStack->Parameters.SetFile.FileObject = pFileObj;
        IrpStack->Parameters.SetFile.FileInformationClass = FileBasicInformation;
    
        //设置完成例程
        IoSetCompletionRoutine(pAllocIrp, CallBackIrpCompleteionProc, &IrpSynEvent, TRUE, TRUE, TRUE);
     
    
        //发送IRP
        IoCallDriver(pNextDeviceObj, pAllocIrp);
        //等待完成.
    
        KeWaitForSingleObject(&IrpSynEvent, Executive, KernelMode, TRUE, NULL);
    
        return STATUS_SUCCESS;
    }
    
    NTSTATUS FsDeleteFile(PFILE_OBJECT pFileObj)
    {
        /*
      1.申请IRP,初始化IRP
      2.初始化同步事件,以及设置回调.
      3.设置文件属性为默认
      4.发送IRP
    
      核心:
        核心是设置 FileObject中的域.进而删除正在运行中的文件
    
      */
        PDEVICE_OBJECT pNextDeviceObj = NULL;
        PIRP pAllocIrp = NULL;
        KEVENT IrpSynEvent = { 0 }; //Irp同步需要的事件同步
        FILE_DISPOSITION_INFORMATION     fileBasciInfo = { 0 };  //注意此位置.已经变化为 FILE_DISPOSITION_INFORMATION
        IO_STATUS_BLOCK iostu;
        PIO_STACK_LOCATION IrpStack;
    
        PSECTION_OBJECT_POINTERS pFileExe;  //注意此属性要设置为0.欺骗系统进行删除
        //通过文件对象.获取其设备对象指针
        pNextDeviceObj = IoGetRelatedDeviceObject(pFileObj);
        if (pNextDeviceObj == NULL)
            return STATUS_UNSUCCESSFUL;
    
        //通过设备对象指针.确定申请的IRP的大小,注意在完成设置里面进行释放.
        pAllocIrp = IoAllocateIrp(pNextDeviceObj->StackSize, TRUE);
        if (pAllocIrp == NULL)
            return STATUS_UNSUCCESSFUL;
    
        //初始化Irp
    
        //设置为自动,设置为无信号.
        KeInitializeEvent(&IrpSynEvent, SynchronizationEvent, FALSE);
    
        fileBasciInfo.DeleteFile = TRUE;        //设置标记为删除
        pAllocIrp->AssociatedIrp.SystemBuffer = &fileBasciInfo;
        pAllocIrp->UserIosb = &iostu;
        pAllocIrp->UserEvent = &IrpSynEvent;
        pAllocIrp->Tail.Overlay.OriginalFileObject = pFileObj;
        pAllocIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
    
        //获取下层堆栈.进行设置.
    
        //IrpStack  = 
        IrpStack = IoGetNextIrpStackLocation(pAllocIrp);
        IrpStack->MajorFunction = IRP_MJ_SET_INFORMATION;
        IrpStack->DeviceObject = pNextDeviceObj;
        IrpStack->FileObject = pFileObj;
        IrpStack->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
        IrpStack->Parameters.SetFile.FileObject = pFileObj;
        IrpStack->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
    
        //设置完成例程
        IoSetCompletionRoutine(pAllocIrp, CallBackIrpCompleteionProc, &IrpSynEvent, TRUE, TRUE, TRUE);
    
        //删除正在运行中的文件.
        
        pFileExe = pFileObj->SectionObjectPointer;
        pFileExe->DataSectionObject = 0;
        pFileExe->ImageSectionObject = 0;
        //发送IRP
        IoCallDriver(pNextDeviceObj, pAllocIrp);
        //等待完成.
    
        KeWaitForSingleObject(&IrpSynEvent, Executive, KernelMode, TRUE, NULL);
    
        return STATUS_SUCCESS;
    }
    NTSTATUS IrpDeleteFileRun(UNICODE_STRING uDelFileName)
    {
        KdBreakPoint();
        NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
        /*
        1.首先通过发送IRP去掉文件的属性
        2.设置文件属性为删除.进行发送IRP强删文件.
        */
        HANDLE hFileHandle = { 0 };
        PFILE_OBJECT  pFileObject = NULL;
        //sep1 : OpenFile Get File Handle
        ntStatus = RetOpenFileHandle(uDelFileName,&hFileHandle);
    
        if (!NT_SUCCESS(ntStatus))
        {
            goto ExitAnRelease;
        }
        //sep2:  Chang File Handle to FileObject
    
        ntStatus = ObReferenceObjectByHandle(
            hFileHandle,
            GENERIC_ALL,
            *IoFileObjectType,
            KernelMode,
            &pFileObject,
            NULL);
        if (!NT_SUCCESS(ntStatus))
        {
           
            goto ExitAnRelease;
        }
    
        //setp 3:  Pass File Atribute
        KdBreakPoint();
       ntStatus =  PassFileattribute(pFileObject);
       if (!NT_SUCCESS(ntStatus))
       {
           goto ExitAnRelease;
       }
    
       //setp 4: Send Irp DeleteFile
       KdBreakPoint();
       ntStatus = FsDeleteFile(pFileObject);
       if (!NT_SUCCESS(ntStatus))
       {
           goto ExitAnRelease;
       }
    ExitAnRelease:
    
        if (pFileObject != NULL)
            ObDereferenceObject(pFileObject);
        if (hFileHandle != NULL)
            ZwClose(hFileHandle);
      
        return ntStatus;
    }
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
    {
    	ULONG iCount = 0;
    	NTSTATUS ntStatus;
        UNICODE_STRING uDelFileName = { 0 };
    	pDriverObj->DriverUnload = DriverUnLoad;
    	/*ntStatus = InitDeviceAnSybolicLinkName(pDriverObj);
    	if (!NT_SUCCESS(ntStatus))
    	{
    		return ntStatus;
    	}
    
    	ntStatus = InitDisPatchFunction(pDriverObj);
    	if (!NT_SUCCESS(ntStatus))
    	{
    		return ntStatus;
    	}*/
    
        //也可写成: \??\c:\xxx.txt
    
        RtlInitUnicodeString(&uDelFileName, L"//DosDevices//C://123.txt");
        IrpDeleteFileRun(uDelFileName);
    	return STATUS_SUCCESS;
    }
    
    

    代码测试可以进行强删.

  • 相关阅读:
    深拷贝和浅拷贝
    【.NET MVC分页】.NET MVC 使用pagelist 分页
    Win10开启IIS
    Win10开启IIS
    目前问题:plupload上传带参数到后台
    目前问题:plupload上传带参数到后台
    jquery怎样获取html页面中的data-xxx
    .Net MVC删除图片
    .Net MVC删除图片
    AlloyClip的简单使用
  • 原文地址:https://www.cnblogs.com/iBinary/p/11596466.html
Copyright © 2011-2022 走看看