首页
社区
课程
招聘
[求助]R0强删文件问题(网络代码经个人修改无问题!求原因)
发表于: 2011-11-27 23:46 8585

[求助]R0强删文件问题(网络代码经个人修改无问题!求原因)

2011-11-27 23:46
8585
【求助】R0强删文件问题(网络代码经个人修改无问题!求原因)
       

BOOLEAN
SKillDeleteFile(IN HANDLE    FileHandle)
{
        NTSTATUS          ntStatus = STATUS_SUCCESS;
        PFILE_OBJECT      fileObject;
        PDEVICE_OBJECT    DeviceObject;
        PIRP              Irp;
        KEVENT            event;
        FILE_DISPOSITION_INFORMATION    FileInformation;
        IO_STATUS_BLOCK ioStatus;
        PIO_STACK_LOCATION irpSp;
        PSECTION_OBJECT_POINTERS pSectionObjectPointer;
        PVOID ceshi1=NULL;
        PVOID ceshi2=NULL;
        SKillStripFileAttributes( FileHandle);          //去掉只读属性,才能删除只读文件
        ntStatus = ObReferenceObjectByHandle(FileHandle,
                DELETE,
                *IoFileObjectType,
                KernelMode,
                &fileObject,
                NULL);                               //取对象指针
        if (!NT_SUCCESS(ntStatus))
        {
                return FALSE;
        }
        DeviceObject = MyIoGetRelatedDeviceObject(fileObject);//获取最高设备对象
        Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);//指定设备栈中申请irp
        if (Irp == NULL)
        {
                ObDereferenceObject(fileObject);
                return FALSE;
        }
        KeInitializeEvent(&event, SynchronizationEvent, FALSE);
        FileInformation.DeleteFile = TRUE;
        Irp->AssociatedIrp.SystemBuffer = &FileInformation;
        Irp->UserEvent = &event;
        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,
                SkillSetFileCompletion,
                &event,
                TRUE,
                TRUE,
                TRUE);
        pSectionObjectPointer = fileObject->SectionObjectPointer;
        pSectionObjectPointer->ImageSectionObject = 0;
        pSectionObjectPointer->DataSectionObject = 0;
        IoCallDriver(DeviceObject, Irp);
        KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
        ObDereferenceObject(fileObject);
        return TRUE;
}

[ATTACH] OK.jpg[/ATTACH]

-----------------------------------------------------------以下个人分析  虽然问题解决不蓝屏但确实不知具体细节原因所以来此一问-------------------------------------------
蓝屏代码

*** Fatal System Error: 0x0000000a
                       (0x00000023,0x00000002,0x00000000,0x8050D623)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y <symbol_path> argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck A, {23, 2, 0, 8050d623}

***** Kernel symbols are WRONG. Please fix symbols to do analysis.

Probably caused by : memory_corruption ( nt!MmCommitSessionMappedView+4cf )

Followup: MachineOwner
---------

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

//此处疑问  看代码意思是将镜像对象 设置为0  我尝试将此处代码注销,
删除失效 不知道是不是 进行删除时 系统会对该对象进行检查此值如果不为0 不能删除  
但是源代码如此  却会造成后期蓝屏 (复制大量文件的时候会蓝屏)  Irql级别问题  
解决此问题时我个人 看来是因为访问的内存出现了问题 后 windbg 查看 以上蓝屏信息

我查看了一下0x8050D623 位置为一个函数头部

1: kd> u 0x8050D623   nt!MiRemoveImageSectionObject 这个函数里面

1: kd> u MiRemoveImageSectionObject
nt!MiRemoveImageSectionObject:
8050d614 8bff            mov     edi,edi
8050d616 55              push    ebp
8050d617 8bec            mov     ebp,esp
8050d619 56              push    esi
8050d61a 8b7508          mov     esi,dword ptr [ebp+8]
8050d61d 8b4e14          mov     ecx,dword ptr [esi+14h]
8050d620 8b4108          mov     eax,dword ptr [ecx+8]
8050d623 f6402310        test    byte ptr [eax+23h],10h//此处造成?

看代码是操作了第一个参数的一些成员然后成员内存出现问题?

wrk MiRemoveImageSectionObject 代码如下:

VOID
MiRemoveImageSectionObject(
    IN PFILE_OBJECT File,
    IN PCONTROL_AREA InputControlArea
    )

/*++

Routine Description:

    This function searches the control area chains (if any) for an existing
    cache of the specified image file.  For non-global control areas, there is
    no chain and the control area is shared for all callers and sessions.
    Likewise for systemwide global control areas.

    However, for global PER-SESSION control areas, we must do the walk.

    Upon finding the specified control area, we unlink it.

Arguments:

    File - Supplies the file object for the image file.

    InputControlArea - Supplies the control area to remove.

Return Value:

    None.

Environment:

    Must be holding the PFN lock.

--*/

{
#if DBG
    PLIST_ENTRY Head;
#endif
    PLIST_ENTRY Next;
    PLARGE_CONTROL_AREA ControlArea;
    PLARGE_CONTROL_AREA FirstControlArea;
    PLARGE_CONTROL_AREA NextControlArea;

    MM_PFN_LOCK_ASSERT();

    ControlArea = (PLARGE_CONTROL_AREA) InputControlArea;

    FirstControlArea = (PLARGE_CONTROL_AREA)(File->SectionObjectPointer->ImageSectionObject);

    //
    // Get a pointer to the first control area.  If this is not a
    // global-per-session control area, then there is no list, so we're done.
    //

    if (FirstControlArea->u.Flags.GlobalOnlyPerSession == 0) {//貌似是此处
        ASSERT (ControlArea->u.Flags.GlobalOnlyPerSession == 0);

        File->SectionObjectPointer->ImageSectionObject = NULL;
        return;
    }

    //
    // A list may exist.  Walk it as necessary and delete the requested entry.
    //

所以我认为之前删除的地方         pSectionObjectPointer->ImageSectionObject = 0; 会对后面调用这个函数是访问出现问题故此保留原始数据清空后再恢复原始数据解决方案代码修改如下:
       
        PVOID temp1=null;
        PVOID temp2=null;
        pSectionObjectPointer = fileObject->SectionObjectPointer;
        temp1=pSectionObjectPointer->ImageSectionObject;
        temp2=pSectionObjectPointer->DataSectionObject;
        pSectionObjectPointer->ImageSectionObject = 0;
        pSectionObjectPointer->DataSectionObject = 0;
        IoCallDriver(DeviceObject, Irp);
        KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
        pSectionObjectPointer->ImageSectionObject=temp1;
        pSectionObjectPointer->ImageSectionObject=temp2;
-------------------------------------------------------以上为个人分析和修改信息---------------------------------------------------------------------------------------

个人疑问:

问题1: 主要请隔位大牛解释一下问题所在,为什么会蓝?  

问题2:虽然问题已经解决并且我已发布驱动给客户使用反映良好。但是确实不知自己分析是否正确 如BugCheck 蓝屏代码的信息我是否理解正确并请对各个参数给予解释(多谢)

问题3:此问题实属个人自私问题,如果哪位牛人有时间并且有空闲能帮小弟扫一下盲。请就帮小弟注释一下代码多谢了。。(如果没空也没事我自己继续学习)主要目的想对照看看自己理解是否有问题
以及一些不懂的地方参考一下

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
没人帮一下吗?
2011-11-28 00:04
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
必须自己顶着?
2011-11-28 03:08
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
有客户了 而且还反应良好,别人还能说什么。 只能羡慕有这样的好人。 ^@^
2011-11-28 04:01
0
雪    币: 237
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

围观看有多少人会帮你
2011-11-28 05:19
0
雪    币: 405
活跃值: (2260)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
pSectionObjectPointer = fileObject->SectionObjectPointer;
  pSectionObjectPointer->ImageSectionObject = 0;

FirstControlArea = (PLARGE_CONTROL_AREA)(File->SectionObjectPointer->ImageSectionObject);
if (FirstControlArea->u.Flags.GlobalOnlyPerSession == 0) {//貌似是此处

8050d620 8b4108          mov     eax,dword ptr [ecx+8]
8050d623 f6402310        test    byte ptr [eax+23h],10h//此处造成?

eax =0 导致蓝了。
网上用的方法一般是 HOOK MmFlushImageSection来欺骗FSD。
2011-11-28 09:30
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
Callers of IoAllocateIrp must be running at IRQL <= DISPATCH_LEVEL.

   
我不太确认哦~  在前面加一句
        if (KeGetCurrentIrql() > DISPATCH_LEVEL)
        {
                DbgPrint("SKillDeleteFile KeGetCurrentIrql() > DISPATCH_LEVEL");
                return FALSE;
        }
试试。
2011-11-28 13:14
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我楼主:

7楼代码只调用一次 并且调用时是无问题的 运行级别也没问题

6楼的回答跟我调试的结果和解决的方案相同 但是不知道为什么 难道出这份代码的人不知道这个问题? 还是我个人原因导致的?

ps:现在用的挺好的 我后来修改后基本没问题  主要是想知道一下原因呵呵 多谢楼上几位了 围观也是帮在下顶了一下帖子 多谢
2011-11-28 14:47
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不是啊 就是想知道一下原因嘛!  虽然过程,我是如此分析但不知是否正确啊.

很有可能是误打误撞  

昨天花了几个小时 看了看  ntdeletefile  暂时还没看完 今天继续但愿能找到答案

找到原因就上来发布一下。
2011-11-28 14:50
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
10
不是你个人原因导致的  因为我也蓝了  而且也是6楼说的那个地方蓝的  上传一个Dmp文件大家研究研究吧
上传的附件:
2011-11-28 15:04
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我帖子里面给出了一个 个人分析的蓝屏原因和解决方法  你测试可以不?

我客户反映是没问题的。  就是 eax=0了  
因为 主要是前面删除的时候  imageobject=0

我想是这个原因所以 我才准备 完全跟踪下来  

看看系统究竟是怎么处理 这个irp的
2011-11-28 16:46
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
12
能把蓝屏的具体条件 告诉我吗   我这边偶尔会出现一次  但我也不知道怎样触发的这个条件。
2011-11-28 19:02
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
找个超过1G的文件夹 复制 到另一个地方  比如 system32这个文件夹
2011-11-28 19:19
0
雪    币: 107
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我这里说说我瞎猜的想法
那个ImageSectionObject   和DATASectionObject
涉及到文件的缓存
直接置零造成内存没有正常释放
没测试没弄出蓝屏看DUMP文件
你有DUMP文件看看应该很有帮助的
2011-11-28 22:52
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
15
从我某个RK摘下来的:

pSectionObjectPointer = NULL;
        pSectionObjectPointer = fileObject->SectionObjectPointer;
        if (MmIsAddressValid(pSectionObjectPointer))
        {
                ulImageSectionObject = pSectionObjectPointer->ImageSectionObject; // 备份之~~~
                pSectionObjectPointer->ImageSectionObject = 0; //清零,准备删除

                ulDataSectionObject = pSectionObjectPointer->DataSectionObject;  //备份之
                pSectionObjectPointer->DataSectionObject = 0;       //清零,准备删除
        }

        //发irp删除
        IoCallDriver(DeviceObject, Irp);

        //等待操作完毕
        KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);

        //删除文件之后,从备份那里填充回来
        pSectionObjectPointer = NULL;
        pSectionObjectPointer = fileObject->SectionObjectPointer;
        if (MmIsAddressValid(pSectionObjectPointer))
        {
                if (ulImageSectionObject)
                        pSectionObjectPointer->ImageSectionObject = ulImageSectionObject; //填充回来,不然蓝屏哦

                if (ulDataSectionObject)
                        pSectionObjectPointer->DataSectionObject = ulDataSectionObject;
        }
2011-11-29 02:16
0
游客
登录 | 注册 方可回帖
返回
//