博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
section map1
阅读量:5010 次
发布时间:2019-06-12

本文共 5292 字,大约阅读时间需要 17 分钟。

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

  

}

转载于:https://www.cnblogs.com/kkindof/archive/2012/06/08/2542341.html

你可能感兴趣的文章
Java读取并下载网络文件
查看>>
github上构建自己的个人网站
查看>>
在word中粘贴的图片为什么显示不完整
查看>>
SQL Server 数据库的鼠标操作
查看>>
net软件工程师求职简历
查看>>
总线置顶[置顶] Linux bus总线
查看>>
nullnullHandling the Results 处理结果
查看>>
SQL SERVER BOOK
查看>>
JS基础回顾,小练习(判断数组,以及函数)
查看>>
多任务——进程
查看>>
WCF:如何将net.tcp协议寄宿到IIS
查看>>
WebAPI HelpPage支持area
查看>>
Path元素
查看>>
php_soap扩展应用
查看>>
第二百三十一节,Bootstrap 介绍
查看>>
vi/vim 三种模式的操作
查看>>
JAVA面向对象三大特性总结
查看>>
guid
查看>>
Python中出现“TabError: inconsistent use of tabs and spaces in indentation”问题的解决
查看>>
ajax请求
查看>>