zjjmj2002
驱动小牛
驱动小牛
  • 注册日期2007-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望321点
  • 贡献值0点
  • 好评度224点
  • 原创分1分
  • 专家分0分
阅读:4216回复:9

原来MmFlushImageSection函数居然如此简单!

楼主#
更多 发布于:2007-08-16 15:00
今天看了RootKit上一篇vardyh的文章后,俺好奇地反汇编了一下MmFlushImageSection函数,发现这个函数居然出奇地简单,虽然绕过来绕过去,最终却只是检查了pSectionObjectPointer->ImageSectionObject和pSectionObjectPointer->DataSectionObject两变量值,如为零则返回TRUE,否则返回FALSE。这就意味着MJ的那个粉碎机只需要再多加几行代码,将这两个变量清零,就可以删除正在运行的文件,这可比HOOK这个函数简单方便多了。
(注:vardyt自己构造了一个三个变量值全为0的SectionObjectPointer结构来替换将被删除文件对象,效果一样,但是俺认为没有必要去动的数据就不要去动,这样心理上保险一些)
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;



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

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

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

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

最新喜欢:

linshierlinshi...
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2007-08-16 15:12
其实是没什么区别的
但是HOOK不用管那些内部结构怎么变,但是直接DKOM,万一结构一变,就挂了 :)

而且据说经Flower同学验证,这样的DKOM不一定成功
原因请见MmFlushImageSection的源代码:
BOOLEAN
MmFlushImageSection (
    __in PSECTION_OBJECT_POINTERS SectionPointer,
    __in MMFLUSH_TYPE FlushType
    )

/*++

Routine Description:

    This function determines if any views of the specified image section
    are mapped, and if not, flushes valid pages (even modified ones)
    from the specified section and returns any used pages to the free
    list.  This is accomplished by examining the prototype PTEs
    from the specified offset to the end of the section, and if
    any prototype PTEs are in the transition state, putting the
    prototype PTE back into its original state and putting the
    physical page on the free list.

Arguments:

    SectionPointer - Supplies a pointer to a section object pointers
                     within the FCB.

    FlushType - Supplies the type of flush to check for.  One of
                MmFlushForDelete or MmFlushForWrite.

Return Value:

    Returns TRUE if either no section exists for the file object or
    the section is not mapped and the purge was done, FALSE otherwise.

--*/

{
    PLIST_ENTRY Next;
    PCONTROL_AREA ControlArea;
    PLARGE_CONTROL_AREA LargeControlArea;
    KIRQL OldIrql;
    LOGICAL state;

    if (FlushType == MmFlushForDelete) {

        //
        // Do a quick check to see if there are any mapped views for
        // the data section.  If so, just return FALSE.
        //

        LOCK_PFN (OldIrql);
        ControlArea = (PCONTROL_AREA)(SectionPointer->DataSectionObject);
        if (ControlArea != NULL) {
            if ((ControlArea->NumberOfUserReferences != 0) ||
                (ControlArea->u.Flags.BeingCreated)) {
                UNLOCK_PFN (OldIrql);
                return FALSE;
            }
        }
        UNLOCK_PFN (OldIrql);
    }

    //
    // Check the status of the control area.  If the control area is in use
    // or the control area is being deleted, this operation cannot continue.
    //

    state = MiCheckControlAreaStatus (CheckImageSection,
                                      SectionPointer,
                                      FALSE,
                                      &ControlArea,
                                      &OldIrql);

    if (ControlArea == NULL) {
        return (BOOLEAN) state;
    }

    //
    // PFN LOCK IS NOW HELD!
    //

    //
    // Repeat until there are no more control areas - multiple control areas
    // for the same image section occur to support user global DLLs - these DLLs
    // require data that is shared within a session but not across sessions.
    // Note this can only happen for Hydra.
    //

    do {

        //
        // Set the being deleted flag and up the number of mapped views
        // for the segment.  Upping the number of mapped views prevents
        // the segment from being deleted and passed to the deletion thread
        // while we are forcing a delete.
        //

        ControlArea->u.Flags.BeingDeleted = 1;
        ControlArea->NumberOfMappedViews = 1;
        LargeControlArea = NULL;

        if (ControlArea->u.Flags.GlobalOnlyPerSession == 0) {
            NOTHING;
        }
        else if (IsListEmpty(&((PLARGE_CONTROL_AREA)ControlArea)->UserGlobalList)) {
            ASSERT (ControlArea ==
                    (PCONTROL_AREA)SectionPointer->ImageSectionObject);
        }
        else {

            //
            // Check if there's only one image section in this control area, so
            // we don't reference the section object pointers as the
            // MiCleanSection call may result in its deletion.
            //

            //
            // There are multiple control areas, bump the reference count
            // on one of them (doesn't matter which one) so that it can't
            // go away.  This ensures the section object pointers will stick
            // around even after the calls below so we can safely reloop to
            // flush any other remaining control areas.
            //

            ASSERT (ControlArea->u.Flags.GlobalOnlyPerSession == 1);

            Next = ((PLARGE_CONTROL_AREA)ControlArea)->UserGlobalList.Flink;

            LargeControlArea = CONTAINING_RECORD (Next,
                                                  LARGE_CONTROL_AREA,
                                                  UserGlobalList);
        
            ASSERT (LargeControlArea->u.Flags.GlobalOnlyPerSession == 1);

            LargeControlArea->NumberOfSectionReferences += 1;
        }

        //
        // This is a page file backed or image segment.  The segment is being
        // deleted, remove all references to the paging file and physical
        // memory.
        //

        UNLOCK_PFN (OldIrql);

        MiCleanSection (ControlArea, TRUE);

        //
        // Get the next Hydra control area.
        //

        if (LargeControlArea != NULL) {
            state = MiCheckControlAreaStatus (CheckImageSection,
                                              SectionPointer,
                                              FALSE,
                                              &ControlArea,
                                              &OldIrql);
            if (!ControlArea) {
                LOCK_PFN (OldIrql);
                LargeControlArea->NumberOfSectionReferences -= 1;
                MiCheckControlArea ((PCONTROL_AREA)LargeControlArea,
                                    OldIrql);
            }
            else {
                LargeControlArea->NumberOfSectionReferences -= 1;
                MiCheckControlArea ((PCONTROL_AREA)LargeControlArea,
                                    OldIrql);
                LOCK_PFN (OldIrql);
            }
        }
        else {
            state = TRUE;
            break;
        }

    } while (ControlArea);

    return (BOOLEAN) state;
}
驱动开发者 呵呵
wangjianfeng
驱动小牛
驱动小牛
  • 注册日期2004-05-28
  • 最后登录2013-10-02
  • 粉丝0
  • 关注0
  • 积分1002分
  • 威望263点
  • 贡献值0点
  • 好评度260点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-08-16 18:06
MJ从哪里整的这么多源代码???
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2007-08-16 21:30
路过。。
人不靓仔心灵美,版头不正红花仔!
zjjmj2002
驱动小牛
驱动小牛
  • 注册日期2007-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望321点
  • 贡献值0点
  • 好评度224点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2007-08-17 09:18
明白了,是WRK里的吧?
zjjmj2002
驱动小牛
驱动小牛
  • 注册日期2007-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望321点
  • 贡献值0点
  • 好评度224点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2007-08-17 09:20
呵呵,wowocock和楚狂人夜读天书哇,这下白读了哇。
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2007-08-17 16:23
现在流氓都不怕你删,你还没删完利他又生成了,所以不但要删除它,还得欺骗OS,让他认为自己还活着。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2007-08-17 17:21
block住就可以了 见粉碎机
驱动开发者 呵呵
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2007-08-20 09:04
死锁加占坑的想法不错,不过对于那些重启后能再生成的保护,最好也加入,现在那些该死的病毒保护的地方太多了,手动很难清除。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
9楼#
发布于:2007-08-20 09:55
如果已经把所有的流氓/病毒粉碎+占坑了,它哪还有重启再生成的机会?:P
驱动开发者 呵呵
游客

返回顶部