MmLoadSystemImage——>MiLoadImageSection(MmMapViewOfSection、MiUnmapViewOfSection?)
为什么在要调用者2个函数呢? 不是很明白,请老师指点下迷津
代码如下:
MiLoadImageSection (
IN OUT PSECTION *InputSectionPointer,
OUT PVOID *ImageBaseAddress,
IN PUNICODE_STRING ImageFileName,
IN ULONG LoadInSessionSpace,
IN PKLDR_DATA_TABLE_ENTRY FoundDataTableEntry
)
{
.
.
FirstPte = MiReserveSystemPtes (NumberOfPtes, SystemPteSpace);
if (FirstPte == NULL) {
MI_INCREMENT_RESIDENT_AVAILABLE (PagesRequired,
MM_RESAVAIL_FREE_LOAD_SYSTEM_IMAGE1);
return STATUS_INSUFFICIENT_RESOURCES;
}
PointerPte = FirstPte;
SystemVa = MiGetVirtualAddressMappedByPte (PointerPte);
.
.
.
.
Process = PsGetCurrentProcess ();
KeStackAttachProcess (&PsInitialSystemProcess->Pcb, &ApcState);
.
.
TargetProcess = PsGetCurrentProcess ();
Status =MmMapViewOfSection (SectionPointer,
TargetProcess,
&Base,
0,
0,
&SectionOffset,
&ViewSize,
ViewUnmap,
0,
PAGE_EXECUTE);
.
.
ControlArea = SectionPointer->Segment->ControlArea;
if ((ControlArea->u.Flags.GlobalOnlyPerSession == 0) &&
(ControlArea->u.Flags.Rom == 0)) {
Subsection = (PSUBSECTION)(ControlArea + 1);
}
else {
Subsection = (PSUBSECTION)((PLARGE_CONTROL_AREA)ControlArea + 1);
}
ASSERT (Subsection->SubsectionBase != NULL);
ProtoPte = Subsection->SubsectionBase;
*ImageBaseAddress = SystemVa;
UserVa = Base;
TempPte = ValidKernelPte;
TempPte.u.Long |= MM_PTE_EXECUTE;
LastProto = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
LastPte = PointerPte + NumberOfPtes;
ExceptionStatus = STATUS_SUCCESS;
while (PointerPte < LastPte) {
if (ProtoPte >= LastProto) {
Subsection = Subsection->NextSubsection;
ProtoPte = Subsection->SubsectionBase;
LastProto = &Subsection->SubsectionBase[
Subsection->PtesInSubsection];
}
PteContents = *ProtoPte;
if ((PteContents.u.Hard.Valid == 1) ||
(PteContents.u.Soft.Protection != MM_NOACCESS)) {
ActualPagesUsed += 1;
PageFrameIndex = MiAllocatePfn (PointerPte, MM_EXECUTE);
TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
MI_WRITE_VALID_PTE (PointerPte, TempPte);
ASSERT (MI_PFN_ELEMENT (PageFrameIndex)->u1.WsIndex == 0);
try {
RtlCopyMemory (SystemVa, UserVa, PAGE_SIZE);
} except (MiMapCacheExceptionFilter (&ExceptionStatus,
GetExceptionInformation())) {
.
.
}
else {
MI_WRITE_ZERO_PTE (PointerPte);
}
ProtoPte += 1;
PointerPte += 1;
SystemVa = ((PCHAR)SystemVa + PAGE_SIZE);
UserVa = ((PCHAR)UserVa + PAGE_SIZE);
}
Status =MiUnmapViewOfSection(TargetProcess, Base, 0);
MmPurgeSection (ControlArea->FilePointer->SectionObjectPointer,
NULL,
0,
FALSE);