SECTION_ALL_ACCESS
};
-static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
-{
- ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
- ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */
-};
/* FUNCTIONS *****************************************************************/
if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
+ /* NT HEADER */
+ nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
/* not a Windows executable */
if(pidhDosHeader->e_lfanew <= 0)
DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
- /* NT HEADER */
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
-
if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
NTSTATUS ReturnedStatus = nStatus;
/* If it attempted to read past the end of the file, it means e_lfanew is invalid */
- if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+ if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_INVALID_IMAGE_PROTECT;
DIE(("ReadFile failed, status %08X\n", ReturnedStatus));
}
if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
-
if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
switch(piohOptHeader->Magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+#ifdef _WIN64
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+#endif // _WIN64
break;
default:
SectionSize.QuadPart = 0xFFFFFFFF;
InitializeObjectAttributes(&Obj,
&Name,
- OBJ_PERMANENT,
+ OBJ_PERMANENT | OBJ_KERNEL_EXCLUSIVE,
NULL,
NULL);
Status = MmCreateSection((PVOID)&PhysSection,
BufferSize = Length + OffsetAdjustment;
BufferSize = PAGE_ROUND_UP(BufferSize);
+ /* Flush data since we're about to perform a non-cached read */
+ CcFlushCache(FileObject->SectionObjectPointer,
+ &FileOffset,
+ BufferSize,
+ &Iosb);
+
/*
* It's ok to use paged pool, because this is a temporary buffer only used in
* the loading of executables. The assumption is that MmCreateSection is
'rXmM');
if (!Buffer)
{
- KeBugCheck(MEMORY_MANAGEMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
UsedSize = 0;
}
NTSTATUS
-ExeFmtpCreateImageSection(HANDLE FileHandle,
+ExeFmtpCreateImageSection(PFILE_OBJECT FileObject,
PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
{
LARGE_INTEGER Offset;
*/
Offset.QuadPart = 0;
- /* FIXME: use FileObject instead of FileHandle */
- Status = ExeFmtpReadFile (FileHandle,
+ Status = ExeFmtpReadFile (FileObject,
&Offset,
PAGE_SIZE * 2,
&FileHeader,
RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
Flags = 0;
- /* FIXME: use FileObject instead of FileHandle */
Status = ExeFmtpLoaders[i](FileHeader,
FileHeaderSize,
- FileHandle,
+ FileObject,
ImageSectionObject,
&Flags,
ExeFmtpReadFile,
if (FileObject == NULL)
return STATUS_INVALID_FILE_FOR_SECTION;
+#ifndef NEWCC
+ if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
+ {
+ DPRINT1("Denying section creation due to missing cache initialization\n");
+ return STATUS_INVALID_FILE_FOR_SECTION;
+ }
+#endif
+
/*
* Create the section
*/
(MemoryArea->Type != MEMORY_AREA_CACHE)) ||
MemoryArea->DeleteInProgress)
{
- if (MemoryArea) NT_ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
+ if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_MAPPED_VIEW;
}
* and calculate the image base address */
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+ if (Segment == &SectionSegments[i])
{
- if (Segment == &SectionSegments[i])
- {
- ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
- break;
- }
+ ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
+ break;
}
}
if (i >= NrSegments)
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
- {
- PVOID SBaseAddress = (PVOID)
- ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
+ PVOID SBaseAddress = (PVOID)
+ ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
- Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
- NT_ASSERT(NT_SUCCESS(Status));
+ Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+ SBaseAddress, Process, Status);
+ ASSERT(NT_SUCCESS(Status));
}
}
}
else
{
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
- NT_ASSERT(NT_SUCCESS(Status));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+ BaseAddress, Process, Status);
+ ASSERT(NT_SUCCESS(Status));
+ }
}
MmUnlockAddressSpace(AddressSpace);
*
* @implemented
*/
-NTSTATUS NTAPI
-NtQuerySection(IN HANDLE SectionHandle,
- IN SECTION_INFORMATION_CLASS SectionInformationClass,
- OUT PVOID SectionInformation,
- IN SIZE_T SectionInformationLength,
- OUT PSIZE_T ResultLength OPTIONAL)
+NTSTATUS
+NTAPI
+NtQuerySection(
+ _In_ HANDLE SectionHandle,
+ _In_ SECTION_INFORMATION_CLASS SectionInformationClass,
+ _Out_ PVOID SectionInformation,
+ _In_ SIZE_T SectionInformationLength,
+ _Out_opt_ PSIZE_T ResultLength)
{
PROS_SECTION_OBJECT Section;
KPROCESSOR_MODE PreviousMode;
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(SectionInformation,
+ SectionInformationLength,
+ __alignof(ULONG));
+ if (ResultLength != NULL)
+ {
+ ProbeForWrite(ResultLength,
+ sizeof(*ResultLength),
+ __alignof(SIZE_T));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ return _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
- Status = DefaultQueryInfoBufferCheck(SectionInformationClass,
- ExSectionInfoClass,
- sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
- SectionInformation,
- (ULONG)SectionInformationLength,
- NULL,
- ResultLength,
- PreviousMode);
-
- if(!NT_SUCCESS(Status))
+ if (SectionInformationClass == SectionBasicInformation)
{
- DPRINT1("NtQuerySection() failed, Status: 0x%x\n", Status);
- return Status;
+ if (SectionInformationLength < sizeof(SECTION_BASIC_INFORMATION))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+ else if (SectionInformationClass == SectionImageInformation)
+ {
+ if (SectionInformationLength < sizeof(SECTION_IMAGE_INFORMATION))
+ {
+ return STATUS_INFO_LENGTH_MISMATCH;
+ }
+ }
+ else
+ {
+ return STATUS_INVALID_INFO_CLASS;
}
Status = ObReferenceObjectByHandle(SectionHandle,
PreviousMode,
(PVOID*)(PVOID)&Section,
NULL);
- if (NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference section: 0x%lx\n", Status);
+ return Status;
+ }
+
+ switch (SectionInformationClass)
{
- switch (SectionInformationClass)
- {
case SectionBasicInformation:
{
PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation;
break;
}
- }
-
- ObDereferenceObject(Section);
}
+ ObDereferenceObject(Section);
+
return(Status);
}
return STATUS_INVALID_PAGE_PROTECTION;
}
+ /* FIXME: We should keep this, but it would break code checking equality */
+ Protect &= ~PAGE_NOCACHE;
Section = (PROS_SECTION_OBJECT)SectionObject;
AddressSpace = &Process->Vm;
ImageSize = 0;
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
- {
- ULONG_PTR MaxExtent;
- MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
- SectionSegments[i].Length.QuadPart);
- ImageSize = max(ImageSize, MaxExtent);
- }
+ ULONG_PTR MaxExtent;
+ MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
+ SectionSegments[i].Length.QuadPart);
+ ImageSize = max(ImageSize, MaxExtent);
}
ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) ||
((ImageBase + ImageSize) < ImageSize))
{
- NT_ASSERT(*BaseAddress == NULL);
+ ASSERT(*BaseAddress == NULL);
ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize,
MM_VIRTMEM_GRANULARITY);
NotAtBase = TRUE;
}
else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY))
{
- NT_ASSERT(*BaseAddress == NULL);
+ ASSERT(*BaseAddress == NULL);
ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY);
NotAtBase = TRUE;
}
for (i = 0; i < NrSegments; i++)
{
- if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+ PVOID SBaseAddress = (PVOID)
+ ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
+ MmLockSectionSegment(&SectionSegments[i]);
+ Status = MmMapViewOfSegment(AddressSpace,
+ Section,
+ &SectionSegments[i],
+ &SBaseAddress,
+ SectionSegments[i].Length.LowPart,
+ SectionSegments[i].Protection,
+ 0,
+ 0);
+ MmUnlockSectionSegment(&SectionSegments[i]);
+ if (!NT_SUCCESS(Status))
{
- PVOID SBaseAddress = (PVOID)
- ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
- MmLockSectionSegment(&SectionSegments[i]);
- Status = MmMapViewOfSegment(AddressSpace,
- Section,
- &SectionSegments[i],
- &SBaseAddress,
- SectionSegments[i].Length.LowPart,
- SectionSegments[i].Protection,
- 0,
- 0);
- MmUnlockSectionSegment(&SectionSegments[i]);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(AddressSpace);
- return(Status);
- }
+ MmUnlockAddressSpace(AddressSpace);
+ return(Status);
}
}
return STATUS_SECTION_PROTECTION;
}
- if (ViewSize == NULL)
- {
- /* Following this pointer would lead to us to the dark side */
- /* What to do? Bugcheck? Return status? Do the mambo? */
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
if (SectionOffset == NULL)
{
ViewOffset = 0;
}
MmUnlockAddressSpace(AddressSpace);
- NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
+ ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
if (NotAtBase)
Status = STATUS_IMAGE_NOT_AT_BASE;