前言:本文基于ReactOS 0.4.15源码。
在创建进程时会载入exe文件,分两步进行,首先是将可执行映像映射到用户空间,这一步可以理解为对虚拟内存地址的规划。在实际执行exe文件时会触发缺页中断,此时才会读取exe文件的内容,本文介绍的就是缺页中断的处理。
缺页中断的处理函数是MmNotPresentFaultSectionView,来看看这个函数。 Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
if (Entry == 0)
* If the entry is zero, then we need to load the page.
if ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart)) && (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
/* We are beyond the data which is on file. Just get a new page. */
MI_SET_USAGE(MI_USAGE_SECTION);
if (Process) MI_SET_PROCESS2(Process->ImageFileName);
if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
if (!NT_SUCCESS(Status))
MmUnlockSectionSegment(Segment);
return STATUS_NO_MEMORY;
MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SSE(Page << PAGE_SHIFT, 1));
MmUnlockSectionSegment(Segment);
Status = MmCreateVirtualMapping(Process, PAddress, Attributes, Page);
if (!NT_SUCCESS(Status))
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
ASSERT(MmIsPagePresent(Process, PAddress));
if (Process)
MmInsertRmap(Page, Process, Address);
DPRINT("Address 0x%p\n", Address);
return STATUS_SUCCESS;
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
/* The data must be paged in. Lock the file, so that the VDL doesn't get updated behind us. */
FsRtlAcquireFileExclusive(Segment->FileObject);
PFSRTL_COMMON_FCB_HEADER FcbHeader = Segment->FileObject->FsContext;
Status = MmMakeSegmentResident(Segment, Offset.QuadPart, PAGE_SIZE, &FcbHeader->ValidDataLength, FALSE);
FsRtlReleaseFile(Segment->FileObject);
/* Lock address space again */
MmLockAddressSpace(AddressSpace);
if (!NT_SUCCESS(Status))
if (Status == STATUS_NO_MEMORY)
return Status;
/* Damn */
DPRINT1("Failed to page data in!\n");
return STATUS_IN_PAGE_ERROR;
/* Everything went fine. Restart the operation */
return STATUS_MM_RESTART_OPERATION;
}首先调用MmGetPageEntrySectionSegment,此时返回的Entry为空,所以会进入if语句,此时会执行Mm函数MakeSegmentResident,这个函数内会读取exe文件的内容。之后返回STATUS_MM_RESTART_OPERATION,这会导致MmNotPresentFaultSectionView被再次调用,不过此时执行的路径就和第一次不同了。/* We already have a page on this section offset. Map it into the process address space. */
Page = PFN_FROM_SSE(Entry);
Status = MmCreateVirtualMapping(Process,
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290864.htm
[原创]Windows内核之载入exe文件
459 浏览
0 回复
暂无回复,快来抢沙发吧!