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

  

}

posted @ 2012-06-08 22:18  kkindof  阅读(569)  评论(0编辑  收藏  举报