zoukankan      html  css  js  c++  java
  • section map1

    typedef struct _SEGMENT {

        struct _CONTROL_AREA *ControlArea;

        ULONG TotalNumberOfPtes;

        ULONG NonExtendedPtes;

        ULONG Spare0;

        UINT64 SizeOfSegment;

        MMPTE SegmentPteTemplate;

        SIZE_T NumberOfCommittedPages;

        PMMEXTEND_INFO ExtendInfo;

        SEGMENT_FLAGS SegmentFlags;

        PVOID BasedAddress;//映象基地址

        //

        // The fields below are for image & pagefile-backed sections only.

        // Common fields are above and new common entries must be added to

        // both the SEGMENT and MAPPED_FILE_SEGMENT declarations.

        //

        union {

            SIZE_T ImageCommitment;     // for image-backed sections only

            PEPROCESS CreatingProcess;  // for pagefile-backed sections only

        } u1;

        union {

            PSECTION_IMAGE_INFORMATION ImageInformation;    // for images only

            PVOID FirstMappedVa;        // for pagefile-backed sections only

        } u2;

        PMMPTE PrototypePte;

        MMPTE ThePtes[MM_PROTO_PTE_ALIGNMENT / PAGE_SIZE];

    } SEGMENT, *PSEGMENT;

    NTSTATUS MiCreateImageFileMap ( IN PFILE_OBJECT File, OUT PSEGMENT *Segment ) 

    {

        PageFrameNumber = MiGetPageForHeader (TRUE);

        Base = MiCopyHeaderIfResident (File, PageFrameNumber);

    if(base==NULL)

    {

     IoPageRead()

    }

    在这判断File是不是image文件

    接着

    FileHeader = &NtHeader->FileHeader;

        FileHeaderNumberOfSections = FileHeader->NumberOfSections;

    NumberOfSubsections = FileHeader->NumberOfSections;

            //

            // The image alignment is less than the page size,

            // map the image with a single subsection.

            //

            ControlArea = ExAllocatePoolWithTag (NonPagedPool,

                          sizeof(CONTROL_AREA) + sizeof(SUBSECTION),

                          MMCONTROL);

            SubsectionsAllocated = 1;

            SingleSubsection = TRUE;

       Subsection = (PSUBSECTION)(ControlArea + 1);

        SizeOfSegment = sizeof(SEGMENT) + (sizeof(MMPTE) * ((ULONG)NumberOfPtes - 1)) +

                        sizeof(SECTION_IMAGE_INFORMATION);

        NewSegment = ExAllocatePoolWithTag (PagedPool | POOL_MM_ALLOCATION,

                                            SizeOfSegment,

                                            MMSECT);

        *Segment = NewSegment;

        RtlZeroMemory (NewSegment, sizeof(SEGMENT));

        NewSegment->PrototypePte = &NewSegment->ThePtes[0];

        PointerPte = &NewSegment->ThePtes[0];

           ImageAlignment = NtHeader32->OptionalHeader.SectionAlignment;

            FileAlignment = NtHeader32->OptionalHeader.FileAlignment - 1;

            SizeOfImage = NtHeader32->OptionalHeader.SizeOfImage;

            LoaderFlags = NtHeader32->OptionalHeader.LoaderFlags;

            ImageBase = NtHeader32->OptionalHeader.ImageBase;

            SizeOfHeaders = NtHeader32->OptionalHeader.SizeOfHeaders;

    NumberOfPtes = BYTES_TO_PAGES (SizeOfImage);//算出映像大小

       Pfn1->u2.Blink = (PFN_NUMBER) PointerPte; //pfn1是MiCopyHeaderIfResident函数的ImagePageFrameNumber参数对应的PFN结构

        NewSegment->ControlArea = ControlArea;

        NewSegment->u2.ImageInformation =

            (PSECTION_IMAGE_INFORMATION)((PCHAR)NewSegment + sizeof(SEGMENT) +

                                           (sizeof(MMPTE) * (NumberOfPtes - 1)));

        NewSegment->TotalNumberOfPtes = (ULONG) NumberOfPtes;

        NewSegment->NonExtendedPtes = (ULONG) NumberOfPtes;

        NewSegment->SizeOfSegment = NumberOfPtes * PAGE_SIZE;

       PointerPte = NewSegment->PrototypePte;

        Subsection->SubsectionBase = PointerPte;  //Subsection是ControlArea结构后面的那个,

    ControlArea->Segment = NewSegment;

    //在这里就会判断下文件是不是在U盘,网络文件,或者floppy等介质上面

    if ((ActiveDataReferences == TRUE) ||

    (IoIsDeviceEjectable(File->DeviceObject)) ||

    ((FileHeader->Characteristics &

    IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) &&

    (FILE_REMOVABLE_MEDIA & File->DeviceObject->Characteristics)) ||

    ((FileHeader->Characteristics &

    IMAGE_FILE_NET_RUN_FROM_SWAP) &&

    (FILE_REMOTE_DEVICE & File->DeviceObject->Characteristics))) {

    //

    // This file resides on a floppy disk or a removable media or

    // network with flags set indicating it should be copied

    // to the paging file.

    //

    ControlArea->u.Flags.FloppyMedia = 1;

    }

    if (FILE_REMOTE_DEVICE & File->DeviceObject->Characteristics) {

    //

    // This file resides on a redirected drive.

    //

    ControlArea->u.Flags.Networked = 1;

    }

    }

    PVOID MiCopyHeaderIfResident ( IN PFILE_OBJECT File, IN PFN_NUMBER ImagePageFrameNumber ) 

    {

    //MiCopyHeaderIfResident函数作用就是把对应文件的一个头先copy出来,作法是这样的:

    //ImagePageFrameNumber 是事先调用者调用MiGetPageForHeader函数找到一个空闲物理页

    //第一步,找一个buffer来返回要copy的数据,这个buffer就是返回值ImagePage了

    //先用MiReserveSystemPtes函数获取一个PTE,再把里面的PFN改成ImagePageFrameNumber

    //接着使用MiGetVirtualAddressMappedByPte就可以获取对应的虚拟地址ImagePage了。这个有点手工打造物理映射的味道

    //第二步,查找目标数据,但目标现在只有fileobject参数。作法如下

    //ControlArea = (PCONTROL_AREA) fileobject->SectionObjectPointer->DataSectionObject;

    /*

        if (ControlArea->u.Flags.Rom == 0) {

            Subsection = (PSUBSECTION) (ControlArea + 1);

        }

        else {

            Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1);

        }

    PointerPte = Subsection->SubsectionBase;

    DataPage = MiMapPageInHyperSpaceAtDpc (Process, PageFrameIndex);//PageFrameIndex是从PointerPte中获取的

           

    */

    //最后RtlCopyMemory (ImagePage, DataPage, PAGE_SIZE);就完成了

    ControlArea = (PCONTROL_AREA) SectionObjectPointer->DataSectionObject;

        ImagePte = MiReserveSystemPtes (1, SystemPteSpace);

        if (ImagePte == NULL) {

            return NULL;

        }

        ImagePage = MiGetVirtualAddressMappedByPte (ImagePte);

        ASSERT (ImagePte->u.Hard.Valid == 0);

        PteContents = ValidKernelPte;

        PteContents.u.Hard.PageFrameNumber = ImagePageFrameNumber;

        MI_WRITE_VALID_PTE (ImagePte, PteContents);

        if (ControlArea->u.Flags.Rom == 0) {

            Subsection = (PSUBSECTION) (ControlArea + 1);

        }

        else {

            Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1);

        }

    PointerPte = Subsection->SubsectionBase;

    DataPage = MiMapPageInHyperSpaceAtDpc (Process, PageFrameIndex);//PageFrameIndex是从PointerPte中获取的

           RtlCopyMemory (ImagePage, DataPage, PAGE_SIZE);

      

    }

  • 相关阅读:
    2019课设---基于微信小程序的食堂订餐送餐系统设计 【构思】(12)
    宝塔安装
    win10添加新建文本文档的快捷方式
    Vue底部菜单模块
    CSS渐变
    记录页面位置及进入页面时跳转位置
    PHP获取微信JS-SDK接口设置(access_token、jsapi_ticket、signature)
    添加Notepad++至右键菜单
    win10卸载XShell6报错1603
    win10我的电脑左侧快捷方式的控制
  • 原文地址:https://www.cnblogs.com/kkindof/p/2542341.html
Copyright © 2011-2022 走看看