[NTOSKRNL]

Implement MiGetFileObjectForSectionAddress and use it in MmGetFileNameForAddress and NtAreMappedFilesTheSame. Don't call MmLocateMemoryAreaByAddress from these functions anymore.

svn path=/trunk/; revision=67810
This commit is contained in:
Timo Kreuzer 2015-05-17 13:46:12 +00:00
parent 18861e4fde
commit 635d9ca5a2

View file

@ -1603,6 +1603,69 @@ MiCreatePagingFileMap(OUT PSEGMENT *Segment,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS
NTAPI
MiGetFileObjectForSectionAddress(
IN PVOID Address,
OUT PFILE_OBJECT *FileObject)
{
PMMVAD Vad;
PCONTROL_AREA ControlArea;
/* Get the VAD */
Vad = MiLocateAddress(Address);
if (Vad == NULL)
{
/* Fail, the address does not exist */
DPRINT1("Invalid address\n");
return STATUS_INVALID_ADDRESS;
}
/* Check if this is a RosMm memory area */
if (Vad->u.VadFlags.Spare != 0)
{
PMEMORY_AREA MemoryArea = (PMEMORY_AREA)Vad;
PROS_SECTION_OBJECT Section;
/* Check if it's a section view (RosMm section) */
if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
{
/* Get the section pointer to the SECTION_OBJECT */
Section = MemoryArea->Data.SectionData.Section;
*FileObject = Section->FileObject;
}
else
{
ASSERT(MemoryArea->Type == MEMORY_AREA_CACHE);
DPRINT1("Address is a cache section!\n");
return STATUS_SECTION_NOT_IMAGE;
}
}
else
{
/* Make sure it's not a VM VAD */
if (Vad->u.VadFlags.PrivateMemory == 1)
{
DPRINT1("Address is not a section\n");
return STATUS_SECTION_NOT_IMAGE;
}
/* Get the control area */
ControlArea = Vad->ControlArea;
if (!(ControlArea) || !(ControlArea->u.Flags.Image))
{
DPRINT1("Address is not a section\n");
return STATUS_SECTION_NOT_IMAGE;
}
/* Get the file object */
*FileObject = ControlArea->FilePointer;
}
/* Return success */
return STATUS_SUCCESS;
}
PFILE_OBJECT PFILE_OBJECT
NTAPI NTAPI
MmGetFileObjectForSection(IN PVOID SectionObject) MmGetFileObjectForSection(IN PVOID SectionObject)
@ -1705,92 +1768,46 @@ NTAPI
MmGetFileNameForAddress(IN PVOID Address, MmGetFileNameForAddress(IN PVOID Address,
OUT PUNICODE_STRING ModuleName) OUT PUNICODE_STRING ModuleName)
{ {
PVOID Section; POBJECT_NAME_INFORMATION ModuleNameInformation;
PMEMORY_AREA MemoryArea; PVOID AddressSpace;
POBJECT_NAME_INFORMATION ModuleNameInformation; NTSTATUS Status;
PVOID AddressSpace; PFILE_OBJECT FileObject = NULL;
NTSTATUS Status;
PFILE_OBJECT FileObject = NULL;
PMMVAD Vad;
PCONTROL_AREA ControlArea;
/* Lock address space */ /* Lock address space */
AddressSpace = MmGetCurrentAddressSpace(); AddressSpace = MmGetCurrentAddressSpace();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
/* Locate the memory area for the process by address */ /* Get the file object pointer for the address */
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); Status = MiGetFileObjectForSectionAddress(Address, &FileObject);
if (!MemoryArea) if (!NT_SUCCESS(Status))
{ {
/* Fail, the address does not exist */ DPRINT1("Failed to get file object for Address %p\n", Address);
InvalidAddress: MmUnlockAddressSpace(AddressSpace);
DPRINT1("Invalid address\n"); return Status;
MmUnlockAddressSpace(AddressSpace); }
return STATUS_INVALID_ADDRESS;
}
/* Check if it's a section view (RosMm section) or ARM3 section */ /* Reference the file object */
if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) ObReferenceObject(FileObject);
{
/* Get the section pointer to the SECTION_OBJECT */
Section = MemoryArea->Data.SectionData.Section;
/* Unlock address space */ /* Unlock address space */
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
/* Get the filename of the section */ /* Get the filename of the file object */
Status = MmGetFileNameForSection(Section, &ModuleNameInformation); Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
}
else if (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)
{
/* Get the VAD */
Vad = MiLocateAddress(Address);
if (!Vad) goto InvalidAddress;
/* Make sure it's not a VM VAD */ /* Dereference the file object */
if (Vad->u.VadFlags.PrivateMemory == 1) ObDereferenceObject(FileObject);
{
NotSection:
DPRINT1("Address is not a section\n");
MmUnlockAddressSpace(AddressSpace);
return STATUS_SECTION_NOT_IMAGE;
}
/* Get the control area */ /* Check if we were able to get the file object name */
ControlArea = Vad->ControlArea; if (NT_SUCCESS(Status))
if (!(ControlArea) || !(ControlArea->u.Flags.Image)) goto NotSection; {
/* Get the file object */
FileObject = ControlArea->FilePointer;
ASSERT(FileObject != NULL);
ObReferenceObject(FileObject);
/* Unlock address space */
MmUnlockAddressSpace(AddressSpace);
/* Get the filename of the file object */
Status = MmGetFileNameForFileObject(FileObject, &ModuleNameInformation);
/* Dereference it */
ObDereferenceObject(FileObject);
}
else
{
/* Trying to access virtual memory or something */
goto InvalidAddress;
}
/* Check if we were able to get the file object name */
if (NT_SUCCESS(Status))
{
/* Init modulename */ /* Init modulename */
RtlCreateUnicodeString(ModuleName, RtlCreateUnicodeString(ModuleName, ModuleNameInformation->Name.Buffer);
ModuleNameInformation->Name.Buffer);
/* Free temp taged buffer from MmGetFileNameForFileObject() */ /* Free temp taged buffer from MmGetFileNameForFileObject() */
ExFreePoolWithTag(ModuleNameInformation, TAG_MM); ExFreePoolWithTag(ModuleNameInformation, TAG_MM);
DPRINT("Found ModuleName %S by address %p\n", ModuleName->Buffer, Address); DPRINT("Found ModuleName %S by address %p\n", ModuleName->Buffer, Address);
} }
/* Return status */ /* Return status */
return Status; return Status;
@ -3082,74 +3099,41 @@ NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,
IN PVOID File2MappedAsFile) IN PVOID File2MappedAsFile)
{ {
PVOID AddressSpace; PVOID AddressSpace;
PMEMORY_AREA MemoryArea1, MemoryArea2; PFILE_OBJECT FileObject1, FileObject2;
PROS_SECTION_OBJECT Section1, Section2; NTSTATUS Status;
/* Lock address space */ /* Lock address space */
AddressSpace = MmGetCurrentAddressSpace(); AddressSpace = MmGetCurrentAddressSpace();
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
/* Locate the memory area for the process by address */ /* Get the file object pointer for address 1 */
MemoryArea1 = MmLocateMemoryAreaByAddress(AddressSpace, File1MappedAsAnImage); Status = MiGetFileObjectForSectionAddress(File1MappedAsAnImage, &FileObject1);
if (!MemoryArea1) if (!NT_SUCCESS(Status))
{ {
/* Fail, the address does not exist */ DPRINT1("Failed to get file object for Address %p\n", File1MappedAsAnImage);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_INVALID_ADDRESS; return Status;
} }
/* Check if it's a section view (RosMm section) or ARM3 section */ /* Get the file object pointer for address 2 */
if (MemoryArea1->Type != MEMORY_AREA_SECTION_VIEW) Status = MiGetFileObjectForSectionAddress(File2MappedAsFile, &FileObject2);
if (!NT_SUCCESS(Status))
{ {
/* Fail, the address is not a section */ DPRINT1("Failed to get file object for Address %p\n", File1MappedAsAnImage);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_CONFLICTING_ADDRESSES; return Status;
} }
/* Get the section pointer to the SECTION_OBJECT */ /* SectionObjectPointer is equal if the files are equal */
Section1 = MemoryArea1->Data.SectionData.Section; if (FileObject1->SectionObjectPointer != FileObject2->SectionObjectPointer)
if (Section1->FileObject == NULL)
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_CONFLICTING_ADDRESSES; return STATUS_NOT_SAME_DEVICE;
}
/* Locate the memory area for the process by address */
MemoryArea2 = MmLocateMemoryAreaByAddress(AddressSpace, File2MappedAsFile);
if (!MemoryArea2)
{
/* Fail, the address does not exist */
MmUnlockAddressSpace(AddressSpace);
return STATUS_INVALID_ADDRESS;
}
/* Check if it's a section view (RosMm section) or ARM3 section */
if (MemoryArea2->Type != MEMORY_AREA_SECTION_VIEW)
{
/* Fail, the address is not a section */
MmUnlockAddressSpace(AddressSpace);
return STATUS_CONFLICTING_ADDRESSES;
}
/* Get the section pointer to the SECTION_OBJECT */
Section2 = MemoryArea2->Data.SectionData.Section;
if (Section2->FileObject == NULL)
{
MmUnlockAddressSpace(AddressSpace);
return STATUS_CONFLICTING_ADDRESSES;
}
/* The shared cache map seems to be the same if both of these are equal */
if (Section1->FileObject->SectionObjectPointer->SharedCacheMap ==
Section2->FileObject->SectionObjectPointer->SharedCacheMap)
{
MmUnlockAddressSpace(AddressSpace);
return STATUS_SUCCESS;
} }
/* Unlock address space */ /* Unlock address space */
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_SAME_DEVICE; return STATUS_SUCCESS;
} }
/* /*