56 #undef MmSetPageEntrySectionSegment 57 #define MmSetPageEntrySectionSegment(S,O,E) do { \ 58 DPRINT("SetPageEntrySectionSegment(old,%p,%x,%x)\n",(S),(O)->LowPart,E); \ 59 _MmSetPageEntrySectionSegment((S),(O),(E),__FILE__,__LINE__); \ 296 ULONG cbFileHeaderOffsetSize = 0;
297 ULONG cbSectionHeadersOffset = 0;
298 ULONG cbSectionHeadersSize;
299 ULONG cbSectionHeadersOffsetSize = 0;
300 ULONG cbOptHeaderSize;
301 ULONG cbHeadersSize = 0;
302 ULONG nSectionAlignment;
303 ULONG nFileAlignment;
312 SIZE_T nPrevVirtualEndOfSegment = 0;
313 ULONG nFileSizeOfHeaders = 0;
318 ASSERT(FileHeaderSize > 0);
320 ASSERT(ImageSectionObject);
322 ASSERT(AllocateSegmentsCb);
328 #define DIE(ARGS_) { DPRINT ARGS_; goto l_Return; } 331 pidhDosHeader = FileHeader;
338 DIE((
"Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
342 DIE((
"No MZ signature found, e_magic is %hX\n", pidhDosHeader->
e_magic));
349 DIE((
"Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->
e_lfanew));
352 DIE((
"The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->
e_lfanew));
354 if(FileHeaderSize < cbFileHeaderOffsetSize)
370 if(FileHeaderSize < cbFileHeaderOffsetSize ||
373 ULONG cbNtHeaderSize;
377 l_ReadHeaderFromFile:
391 DIE((
"ReadFile failed, status %08X\n", ReturnedStatus));
402 DIE((
"The file doesn't contain the PE file header\n"));
404 pinhNtHeader =
pData;
418 DIE((
"The file isn't a PE executable, Signature is %X\n", pinhNtHeader->
Signature));
423 DIE((
"The full NT header is too large\n"));
426 if(cbReadSize < cbNtHeaderSize)
427 DIE((
"The file doesn't contain the full NT header\n"));
431 ULONG cbOptHeaderOffsetSize = 0;
437 DIE((
"The file isn't a PE executable, Signature is %X\n", pinhNtHeader->
Signature));
440 DIE((
"The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->
e_lfanew));
448 if(cbOptHeaderOffsetSize > FileHeaderSize)
449 goto l_ReadHeaderFromFile;
459 DIE((
"The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
463 switch(piohOptHeader->
Magic)
468 DIE((
"Win64 optional header, unsupported\n"));
475 DIE((
"Unrecognized optional header, Magic is %X\n", piohOptHeader->
Magic));
485 DIE((
"Sections aren't page-aligned and the file alignment isn't the same\n"));
488 DIE((
"The section alignment is smaller than the file alignment\n"));
494 DIE((
"The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
505 switch(piohOptHeader->
Magic)
514 ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->
SizeOfImage;
517 ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->
SizeOfStackReserve;
520 ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->
SizeOfStackCommit;
524 ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->
Subsystem;
536 ImageSectionObject->ImageInformation.TransferAddress = (
PVOID) (ImageBase +
541 ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->
SizeOfCode != 0;
543 ImageSectionObject->ImageInformation.ImageContainsCode =
TRUE;
549 ImageSectionObject->ImageInformation.ImageContainsCode =
FALSE;
554 ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->
LoaderFlags;
558 ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->
DllCharacteristics;
588 DIE((
"ImageBase exceeds the address space\n"));
594 DIE((
"SizeOfImage exceeds the address space\n"));
596 ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->
SizeOfImage;
602 DIE((
"SizeOfStackReserve exceeds the address space\n"));
610 DIE((
"SizeOfStackCommit exceeds the address space\n"));
617 ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->
Subsystem;
629 ImageSectionObject->ImageInformation.TransferAddress = (
PVOID) (ImageBase +
634 ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->
SizeOfCode != 0;
636 ImageSectionObject->ImageInformation.ImageContainsCode =
TRUE;
642 ImageSectionObject->ImageInformation.ImageContainsCode =
FALSE;
647 ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->
LoaderFlags;
650 ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->
DllCharacteristics;
659 DIE((
"ImageBase is not aligned on a 64KB boundary"));
663 ImageSectionObject->ImageInformation.GpValue = 0;
664 ImageSectionObject->ImageInformation.ZeroBits = 0;
665 ImageSectionObject->BasedAddress = (
PVOID)ImageBase;
683 DIE((
"Offset overflow\n"));
686 DIE((
"Offset overflow\n"));
692 if(!
Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
693 DIE((
"Section headers too large\n"));
702 DIE((
"The section headers overflow SizeOfHeaders\n"));
706 else if(!
AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
707 DIE((
"Overflow aligning the size of headers\n"));
718 if(FileHeaderSize < cbSectionHeadersOffsetSize)
719 pishSectionHeaders =
NULL;
727 pishSectionHeaders = (
PVOID)((
UINT_PTR)FileHeader + cbSectionHeadersOffset);
734 if(FileHeaderSize < cbSectionHeadersOffsetSize ||
740 lnOffset.
QuadPart = cbSectionHeadersOffset;
743 nStatus = ReadFileCb(
File, &lnOffset, cbSectionHeadersSize, &
pData, &
pBuffer, &cbReadSize);
746 DIE((
"ReadFile failed with status %08X\n", nStatus));
755 if(cbReadSize < cbSectionHeadersSize)
756 DIE((
"The file doesn't contain all of the section headers\n"));
758 pishSectionHeaders =
pData;
772 ImageSectionObject->Segments = AllocateSegmentsCb(ImageSectionObject->NrSegments);
774 if(ImageSectionObject->Segments ==
NULL)
775 DIE((
"AllocateSegments failed\n"));
778 pssSegments = ImageSectionObject->Segments;
782 if(!
AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment))
783 DIE((
"Cannot align the size of the section headers\n"));
785 nPrevVirtualEndOfSegment =
ALIGN_UP_BY(cbHeadersSize, nSectionAlignment);
786 if (nPrevVirtualEndOfSegment < cbHeadersSize)
787 DIE((
"Cannot align the size of the section headers\n"));
789 pssSegments[0].
Image.FileOffset = 0;
793 pssSegments[0].
Image.VirtualAddress = 0;
794 pssSegments[0].
Image.Characteristics = 0;
802 ASSERT(ImageSectionObject->RefCount > 0);
805 for(
i = 0;
i < ImageSectionObject->NrSegments - 1; ++
i)
807 ULONG nCharacteristics;
811 DIE((
"Image.VirtualAddress[%u] is not aligned\n",
i));
815 DIE((
"Memory gap between section %u and the previous\n",
i));
818 if(pishSectionHeaders[
i].SizeOfRawData != 0)
825 if(!
IsAligned(pishSectionHeaders[
i].SizeOfRawData, nFileAlignment))
826 DIE((
"SizeOfRawData[%u] is not aligned\n",
i));
833 DIE((
"SizeOfRawData[%u] too large\n",
i));
843 ASSERT(pssSegments[
i].RawLength.QuadPart == 0);
873 if(AlignedLength < pssSegments[
i].
Length.LowPart)
874 DIE((
"Cannot align the virtual size of section %u\n",
i));
878 if(pssSegments[
i].
Length.QuadPart == 0)
879 DIE((
"Virtual size of section %u is null\n",
i));
886 if (nPrevVirtualEndOfSegment < pssSegments[
i].
Image.VirtualAddress)
887 DIE((
"The image is too large\n"));
946 if (SavedSwapEntry != 0)
997 MmDereferenceSegmentWithLock(
1026 Segment->FileObject->SectionObjectPointer->DataSectionObject =
NULL;
1041 ASSERT(ImageSectionObject->
FileObject->SectionObjectPointer->ImageSectionObject == ImageSectionObject);
1042 ImageSectionObject->
FileObject->SectionObjectPointer->ImageSectionObject =
NULL;
1048 SectionSegments = ImageSectionObject->
Segments;
1049 for (
i = 0;
i < NrSegments;
i++)
1074 DPRINT1(
"Entry == 0 for MmSharePageEntrySectionSegment\n");
1079 DPRINT1(
"Maximum share count reached\n");
1105 DPRINT1(
"Entry == 0 for MmUnsharePageEntrySectionSegment\n");
1180 if (DestAddress ==
NULL)
1218 if (RangeEnd %
_64K)
1219 RangeEnd +=
_64K - (RangeEnd %
_64K);
1231 if (RangeEnd >
Segment->RawLength.QuadPart)
1232 RangeEnd =
Segment->RawLength.QuadPart;
1236 for ( ; RangeStart < RangeEnd; RangeStart +=
_64K)
1239 ULONG ToReadPageBits = 0;
1242 if (ChunkEnd > RangeEnd)
1243 ChunkEnd = RangeEnd;
1246 for (
LONGLONG ChunkOffset = RangeStart; ChunkOffset < ChunkEnd; ChunkOffset +=
PAGE_SIZE)
1250 CurrentOffset.
QuadPart = ChunkOffset;
1272 ToReadPageBits |= 1
UL << ((ChunkOffset - RangeStart) >>
PAGE_SHIFT);
1279 if (ToReadPageBits == 0)
1287 while (ChunkOffset < ChunkEnd)
1296 ToReadPageBits >>= BitSet;
1298 ASSERT(ChunkOffset < ChunkEnd);
1318 while (ChunkOffset < ChunkEnd)
1320 if (ToReadPageBits & 1)
1323 CurrentOffset.
QuadPart = ChunkOffset;
1327 ToReadPageBits >>= 1;
1350 if (
FileOffset.QuadPart > ValidDataLength->QuadPart)
1353 goto AssignPagesToSegment;
1394 while (ChunkOffset < ChunkEnd)
1396 if (ToReadPageBits & 1)
1399 CurrentOffset.
QuadPart = ChunkOffset;
1403 ToReadPageBits >>= 1;
1411 AssignPagesToSegment:
1431 ToReadPageBits >>= BitSet;
1477 if (SwapEntry != MM_WAIT_ENTRY)
1595 DPRINT1(
"Removing PAGE_GUARD protection failed : 0x%08x.\n",
Status);
1609 if (SwapEntry == MM_WAIT_ENTRY)
1625 ASSERT(DummyEntry == SwapEntry);
1643 DPRINT1(
"MmReadFromSwapPage failed, status = %x\n",
Status);
1649 ASSERT(DummyEntry == MM_WAIT_ENTRY);
1657 DPRINT(
"MmCreateVirtualMapping failed, not out of memory\n");
1699 DPRINT(
"MmCreateVirtualMappingUnsafe failed, not out of memory\n");
1747 DPRINT1(
"Unable to create virtual mapping\n");
1775 DPRINT1(
"Failed to page data in!\n");
1789 if (SwapEntry == MM_WAIT_ENTRY)
1830 DPRINT1(
"Someone changed ppte entry while we slept (%x vs %x)\n",
Entry, Entry1);
1846 DPRINT1(
"Unable to create virtual mapping\n");
1874 DPRINT1(
"Unable to create virtual mapping\n");
2005 DPRINT(
"Swapping page (Old %x New %x)\n", OldPage, NewPage);
2017 DPRINT1(
"MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
2056 *OldProtect =
Region->Protect;
2072 PVOID RegionBaseAddress;
2094 Info->BaseAddress = RegionBaseAddress;
2116 DPRINT(
"MmpDeleteSection(ObjectBody %p)\n", ObjectBody);
2197 sizeof(*PhysSection),
2200 (
PVOID*)&PhysSection);
2203 DPRINT1(
"MmCreatePhysicalMemorySection: failed to create object (0x%lx)\n",
Status);
2213 PhysSection->u.Flags.filler = 1;
2215 PhysSection->u.Flags.PhysicalMemory = 1;
2216 PhysSection->SizeOfSection = SectionSize;
2232 Segment->Image.FileOffset = 0;
2234 Segment->RawLength = SectionSize;
2235 Segment->Length = SectionSize;
2238 Segment->Image.VirtualAddress = 0;
2239 Segment->Image.Characteristics = 0;
2266 DPRINT(
"Creating Section Object Type\n");
2273 RtlZeroMemory(&ObjectTypeInitializer,
sizeof(ObjectTypeInitializer));
2275 ObjectTypeInitializer.
Length =
sizeof(ObjectTypeInitializer);
2334 Section->u.Flags.filler = 1;
2336 Section->u.Flags.File = 1;
2339 Section->u.Flags.NoChange = 1;
2341 Section->u.Flags.Reserve = 1;
2363 if ((UMaximumSize !=
NULL) && (UMaximumSize->
QuadPart != 0))
2472 Segment->Image.FileOffset = 0;
2475 Segment->Image.Characteristics = 0;
2486 Segment->Image.VirtualAddress = 0;
2587 ULONG OffsetAdjustment;
2610 OffsetAdjustment =
FileOffset.u.LowPart - AdjustOffset;
2642 *ReadSize = UsedSize - OffsetAdjustment;
2653 # define MmspAssertSegmentsSorted(OBJ_) ((void)0) 2654 # define MmspAssertSegmentsNoOverlap(OBJ_) ((void)0) 2655 # define MmspAssertSegmentsPageAligned(OBJ_) ((void)0) 2664 for(
i = 1;
i < ImageSectionObject->NrSegments; ++
i )
2666 ASSERT(ImageSectionObject->Segments[
i].Image.VirtualAddress >=
2667 ImageSectionObject->Segments[
i - 1].Image.VirtualAddress);
2680 for(
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2682 ASSERT(ImageSectionObject->Segments[
i].Length.QuadPart > 0);
2686 ASSERT(ImageSectionObject->Segments[
i].Image.VirtualAddress >=
2687 (ImageSectionObject->Segments[
i - 1].Image.VirtualAddress +
2688 ImageSectionObject->Segments[
i - 1].Length.QuadPart));
2700 for(
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2702 ASSERT((ImageSectionObject->Segments[
i].Image.VirtualAddress %
PAGE_SIZE) == 0);
2703 ASSERT((ImageSectionObject->Segments[
i].Length.QuadPart %
PAGE_SIZE) == 0);
2717 if (Segment1->
Image.VirtualAddress > Segment2->
Image.VirtualAddress)
2719 else if (Segment1->
Image.VirtualAddress < Segment2->
Image.VirtualAddress)
2740 qsort(ImageSectionObject->Segments,
2741 ImageSectionObject->NrSegments,
2742 sizeof(ImageSectionObject->Segments[0]),
2770 ASSERT(ImageSectionObject->NrSegments >= 1);
2772 for (
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2774 if(ImageSectionObject->Segments[
i].Length.QuadPart == 0)
2788 if ((ImageSectionObject->Segments[
i - 1].Image.VirtualAddress +
2789 ImageSectionObject->Segments[
i - 1].Length.QuadPart) !=
2790 ImageSectionObject->Segments[
i].Image.VirtualAddress)
2824 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2826 for (
i = 0;
i < ImageSectionObject->NrSegments; ++
i )
2843 EffectiveSegment->
Image.VirtualAddress;
2848 if (EffectiveSegment->
Image.FileOffset < VirtualOffset)
2858 EffectiveSegment->
Image.FileOffset -= VirtualOffset;
2873 if (EndOfEffectiveSegment ==
Segment->Image.VirtualAddress)
2877 ASSERT(LastSegment < ImageSectionObject->NrSegments);
2879 EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
2881 if (LastSegment !=
i)
2901 else if (EndOfEffectiveSegment >
Segment->Image.VirtualAddress)
2903 static const ULONG FlagsToProtection[16] =
2923 unsigned ProtectionFlags;
2930 if (
Segment->Image.FileOffset != (EffectiveSegment->
Image.FileOffset +
2944 EffectiveSegment->
Image.VirtualAddress;
2952 ProtectionFlags = 0;
2955 ProtectionFlags |= 1 << 0;
2958 ProtectionFlags |= 1 << 1;
2961 ProtectionFlags |= 1 << 2;
2964 ProtectionFlags |= 1 << 3;
2966 ASSERT(ProtectionFlags < 16);
2967 EffectiveSegment->
Protection = FlagsToProtection[ProtectionFlags];
2985 ImageSectionObject->NrSegments = LastSegment + 1;
2996 PVOID FileHeaderBuffer;
2997 ULONG FileHeaderSize;
2999 ULONG OldNrSegments;
3019 if (FileHeaderSize == 0)
3042 if (ImageSectionObject->Segments)
3045 ImageSectionObject->Segments =
NULL;
3100 OldNrSegments = ImageSectionObject->
NrSegments;
3106 if (ImageSectionObject->
NrSegments < OldNrSegments)
3117 if (Segments ==
NULL)
3122 ImageSectionObject->
Segments = Segments;
3163 DPRINT1(
"Denying section creation due to missing cache initialization\n");
3190 Section->u.Flags.filler = 1;
3193 Section->u.Flags.File = 1;
3194 Section->u.Flags.Image = 1;
3196 Section->u.Flags.NoChange = 1;
3198 grab_image_section_object:
3202 ImageSectionObject =
FileObject->SectionObjectPointer->ImageSectionObject;
3210 ImageSectionObject =
FileObject->SectionObjectPointer->ImageSectionObject;
3213 if (ImageSectionObject ==
NULL)
3221 if (ImageSectionObject ==
NULL)
3232 if (
FileObject->SectionObjectPointer->ImageSectionObject !=
NULL)
3237 goto grab_image_section_object;
3240 FileObject->SectionObjectPointer->ImageSectionObject = ImageSectionObject;
3273 Section->Segment = (
PSEGMENT)ImageSectionObject;
3315 Section->Segment = (
PSEGMENT)ImageSectionObject;
3386 DPRINT1(
"Mapping between 0x%p and 0x%p failed (%X).\n",
3470 if (SavedSwapEntry != 0)
3549 MmDereferenceSegment(
Segment);
3563 PVOID ImageBaseAddress = 0;
3565 DPRINT(
"Opening memory area Process %p BaseAddress %p\n",
3599 SectionSegments = ImageSectionObject->
Segments;
3606 for (
i = 0;
i < NrSegments;
i++)
3608 if (
Segment == &SectionSegments[
i])
3614 if (
i >= NrSegments)
3619 for (
i = 0;
i < NrSegments;
i++)
3622 ((
char*)ImageBaseAddress + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
3627 DPRINT1(
"MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3632 DPRINT(
"One mapping less for %p\n", ImageSectionObject->
FileObject->SectionObjectPointer);
3640 DPRINT1(
"MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
3697 SectionInformationLength,
3744 switch(SectionInformationClass)
3750 Sbi.
Size = Section->SizeOfSection;
3754 if (Section->u.Flags.File)
3756 if (Section->u.Flags.Image)
3766 if (Section->u.Flags.Image)
3787 DPRINT1(
"Unimplemented code path!");
3807 if (!Section->u.Flags.Image)
3835 *Sii = *Section->Segment->u2.ImageInformation;
3848 DPRINT1(
"Unknown SectionInformationClass: %d\n", SectionInformationClass);
3925 DPRINT(
"Mapping ARM3 section into %s\n",
Process->ImageFileName);
3966 SectionSegments = ImageSectionObject->
Segments;
3978 for (
i = 0;
i < NrSegments;
i++)
3983 ImageSize =
max(ImageSize, MaxExtent);
3990 ((ImageBase + ImageSize) < ImageSize))
4025 for (
i = 0;
i < NrSegments;
i++)
4028 ((
char*)ImageBase + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
4032 &SectionSegments[
i],
4034 SectionSegments[
i].
Length.QuadPart,
4044 SBaseAddress = ((
char*)ImageBase + (
ULONG_PTR)SectionSegments[
i].
Image.VirtualAddress);
4058 DPRINT(
"Mapped %p for section pointer %p\n", ImageSectionObject, ImageSectionObject->
FileObject->SectionObjectPointer);
4161 DPRINT1(
"ERROR: File can't be truncated because it has an image section\n");
4173 if ((
Segment->SectionCount == 0) ||
4191 MmDereferenceSegment(
Segment);
4193 DPRINT(
"FIXME: didn't check for outstanding write probes\n");
4251 case MmFlushForDelete:
4259 case MmFlushForWrite:
4276 if (!ImageSectionObject)
4278 DPRINT(
"No image section object. Accepting\n");
4289 DPRINT(
"Denying. There are mappings open\n");
4316 MmDereferenceSegmentWithLock(&ImageSectionObject->
Segments[0],
OldIrql);
4325 MmDereferenceSegmentWithLock(&ImageSectionObject->
Segments[0],
OldIrql);
4376 DPRINT(
"MmMapViewInSystemSpaceEx() called\n");
4449 DPRINT(
"MmUnmapViewInSystemSpace() called\n");
4547 DPRINT1(
"Page protection is invalid\n");
4557 DPRINT1(
"Large pages cannot be used with an image mapping\n");
4599 DPRINT1(
"Cannot create image maps with writers open on the file!\n");
4605 DPRINT1(
"Creating image map with writers open on the file!\n");
4751 MmDereferenceSegment(
Segment);